разрезать текст по пробелу

Автор Сигма, 8 июля 2015, 10:57

0 Пользователи и 1 гость просматривают эту тему.

Сигма

Здравствуйте. Имеется произвольный текст в столбце Calc. Необходимо скопировать из всех ячеек первые 70 символов слева, при этом не разрезая слов. То есть если 71 символ попадается внутри слова, это слово нужно отбросить и взять не 70 символов, а меньше, так что бы не разрезать слова. Не могу ничего придумать на этот счет.

Yakov

например можно сделать так:

=IF(FIND(" " ;D1;60)>70;LEFT(D1;70);LEFT(D1;FIND(" " ;D1;60)))

Эта формула начинает искать пробел с 60 символа
если пробел после 70 символа - выдаёт только 70 символов,
а если в диапазоне от 60 до 70 - выдает строку, не разрезая слов.

Сигма

Большое спасибо, вопрос решен.

celler

#3
А ведь задача не правильно решена. Ведь так могут и слова разрезаться и может оказаться, что последнее слово в диапазоне 70-ти символов будет длиннее 10 символов и тогда результат будет тоже длиннее 70 символов, а может наоборот, между 60-м и 70-м символом будет несколько пробелов и тогда результат будет слишком коротким.
Правильнее было бы что-нибудь наподобие такого:
=IF(OR(ISERROR(SEARCH(" ";LEFT(D1;70);1));LEN(TRIM(D1))<71);LEFT(TRIM(D1);70);MID(SUBSTITUTE(TRIM(D1);" ";"&&&&";70-LEN(SUBSTITUTE(LEFT(TRIM(D1);70);" ";"")));1;SEARCH("&&&&";SUBSTITUTE(TRIM(D1);" ";"&&&&";70-LEN(SUBSTITUTE(LEFT(TRIM(D1);70);" ";"")));1)-1))

Yakov

Предложенный выше вариант может и не лишён недостатков, но точно при его использовании не может быть ситуации, когда результирующая строка получится длиннее 70 символов.

celler

#5
Цитата: Yakov от 17 июля 2015, 22:21Предложенный выше вариант может и не лишён недостатков, но точно при его использовании не может быть ситуации, когда результирующая строка получится длиннее 70 символов.
Непосредственно по формуле да, не может, но такой результат практически запрограммирован самим выбранным алгоритмом решения задачи. Вот смотрите, Ваша формула ищет пробел начиная с шестидесятого символа. Если она его находит ранее 70-го символа, то по нему и обрезает. Но ведь между 60-м и 70-м символом может быть несколько пробелов, а следовательно формула обрежет по первому и сделает неправильно, удалив то, что не должна была. Если она его находит за 70-м символом, то она обрезает вообще точно 70 символов, нарушая условие задачи не разрезать слова. Плюс формула вообще не знает что делать, если строка длиннее 70-ти символов, но после 60-го нет пробелов. Или если строка короче 60 символов. Или она между 60-тью и 70-тью символами, но там нет пробелов. Или если в строке всего одно слово без пробелов. А если это слово длиннее 70-ти символов (а это возможно, например в тексте приведено число пи до сотого знака)? Или например в тексте присутствуют ошибки набора, когда встречаются несколько пробелов подряд. Таких вариантов может быть много и тогда формула либо возвращает ошибочный результат, либо, если формула не знает что с ними делать, возвращает что-нибудь, начинающееся на #. Фактически формула корректно обрабатывает только один вариант, когда между 60-м и 70-м символами встречается ровно один пробел и при этом строка длиннее 70-ти символов.
Теперь представим себе новичка, который получил такую формулу. Он берёт заведомо длинную строку, испытывает и обнаруживает, что формула работает - обрезает. Он рад, берёт все свои тексты и обрезает этой формулой. Может ничего и не заметить, испортив тем не менее все свои тексты. Может и заметить эти # и если немного опытный, то может сообразить - ага, так формула не учитывает всего, что короче 60-ти символов. Добавляет в формулу условие, что если ошибка, то оставлять всё так как есть. И вот он результат - если в конце текста есть длинное слово, начинающееся ранее 60-го символа и кончающееся после 70-го, то такой текст благополучно останется на месте целиком.
Я конечно не знаю, что там за тексты и зачем их нужно именно таким образом обрезать, но точно знаю, что с текстами нужно работать очень осторожно и сам уже бывало кое-что портил. Поэтому формулы должны учитывать либо все возможные варианты, либо некоторые варианты должны анализироваться вручную и игнорироваться за ненужностью.
Ещё раз повторю, виноват выбранный алгоритм. Таким образом обработать все возможные варианты не сможет не только новичок, но и многие асы.
В моём варианте алгоритм другой, хотя тоже там стопроцентно не уверен, что охвачены все возможные случаи и всё правильно. Сегодня вот там сделал корректировку из-за возможности слишком длинных слов. И кое-что конечно должно быть прояснено по условию задачи. Что например делать со словом длиннее 70-ти символов. Я вот там обрезаю например до 70-ти символов.

Сигма

Друзья, большое спасибо за такой интерес к моей проблеме. Скорректирую условия задачи:

1. Длина текста от 30 до 200 символов.
2. Двойных (и более) пробелов не встречается.
3. Слов длиннее 70 символов не встречается.
4. В остатке должно остаться максимально близкое к 70 число символов.

Прочитав первый пост Yakovа, я собственно говоря понял, что неверно задал условия задачи. И решил я её иначе, описывать долго, прикладываю файл примера (для варианта с 50 символами). Сначала вставляю формулы, затем сортирую по всем критериям сразу. Нужный текст выделен желтым фоном, осталось переместить его в один столбец и применить функцию "текст по столбцам" где разделить - "#". В первом столбце останется искомое.
Уважаемый Сeller, к сожалению сейчас у меня недостаток времени и я не могу проверить написанную Вами формулу. Обязательно сделаю это позже. Спасибо.

rami

#7
Цитата: Сигма от 20 июля 2015, 07:14Уважаемый Сeller, к сожалению сейчас у меня недостаток времени и я не могу проверить написанную Вами формулу. Обязательно сделаю это позже.
;D Ни в коем случае не пользуйтесь формулой celler'а, а не то появится избыток времени ;D

celler не зная точные условия перестраховался и написал "страшную" формулу, которая отлично работает.
Теперь же зная более подробные условия можно убрать из его формулы проверки на ненужные условия.

Если в ячейке B2 предложение, то в ячейке C2 формула: =LEFT(TRIM(B2);SEARCH("#";SUBSTITUTE(TRIM(B2);" ";"#";50-LEN(SUBSTITUTE(LEFT(TRIM(B2);50);" ";""))))-1)
А если вы утверждаете, что не будет двойных пробелов, то ещё проще: =LEFT(B2;SEARCH("#";SUBSTITUTE(B2;" ";"#";50-LEN(SUBSTITUTE(LEFT(B2;50);" ";""))))-1)

;D Администрация Форума предупреждает: длительное пребывание на Форуме увеличивает ваше свободное время ;D

Сигма

Последняя формула в ответе №7 прекрасно работает, за небольшим исключением - при длине исходного текста менее 50 символов выдает ошибку. Как бы её допилить?

rami

Цитата: Сигма от 30 июля 2015, 07:42Последняя формула в ответе №7 прекрасно работает, за небольшим исключением - при длине исходного текста менее 50 символов выдает ошибку. Как бы её допилить?
Ну, тогда верну одну проверку:=IF(LEN(B19)<50;B19;LEFT(B19;SEARCH("#";SUBSTITUTE(B19;" ";"#";50-LEN(SUBSTITUTE(LEFT(B19;50);" ";""))))-1))
Если длина строки меньше 50, то показываем её целиком.

Сигма


JohnSUN

Отлично! Теперь, когда задача окончательна решена, можешь рассказать а на пуркуа тебе нужно было так кастрировать строки текста? И много ли их у тебя вообще было?
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Сигма

Глупо писать об этом сейчас, а не в первом посте. Но если Вам интересно - для описания товаров в интернет магазинах. На разных площадках в поле "наименование товара" можно уместить ограниченное число символов - от 50 до 100 примерно. Плюс к этому есть поле "Описание товара", там около 200 символов. В "наименование товара" нужно поместить как можно больше информации, остальную можно втиснуть в "Описание товара" (специфика такова, что нет особой разницы, если какие то слова попадут из наименования в описание). Раньше при описании очень много времени уходило на контроль длины строки (про LEN я знаю). Вдруг какое то важное слово не помещалось в наименование, приходилось постоянно вырезать слова, менять их местами и т.п. Очень много времени терялось. С использованием формулы можно просто барабанить по клавишам, не обращая внимания ни на какие ограничения длины строки - следить только, что бы важная информация шла самой первой. Затем первые 50 (в зависимости от площадки) символов идут в "наименование товара". Вычитаем "наименование товара" из всего набранного текста и получаем "Описание товара".

JohnSUN

Да, действительно глупо неловко получилось...
Если бы речь шла именно о той задаче, которую ты озвучил в самом начале, то подошло бы, наверное, такое решение


Если тебя устраивает формула, то пусть уже так и будет.
Но если бы я ежедневно занимался такой вот работёнкой, то, скорее всего, набросал бы макрос... Скажем такой: по двойному клику на ячейке открывалось бы окно из четырех полей. Первое - совсем маленькое - просто допустимая длина строки "наименование товара". Второе - большое текстовое поле - исходный текст описания (полный) - в него попадал бы текст из первой колонки, "сырой", первоначальный. Третье - одна строка указанной длины - текст из ячейки во второй колонке, "наименование товара". Если еще не заполнен, то автоматом копировал бы первые слова с "сырца". Ну и последнее - опять большое - из третьей колонки, окончательное, отредактированное "Описание товара". Если еще не заполнено, то просто копировал бы исходный "сырец". И какие-то кнопки, разумеется: сохранить и закрыть, закрыть без сохранения и - Главная Кнопка - перенести выделенный во втором или четвертом поле текст в строку "наименование товара" в текущую позицию курсора... Само собой, после переноса всё что не влазит в размер - отсекается по общим правилам... Ну, то есть дважды кликнул на важной информации, чтобы её выделить, или просто курсором по ней провёл - и щелкай Главную Кнопку...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Сигма

Спасибо, но формула меня вполне устраивает. Вы решаете вопрос о заполнении данных, но у меня заполнение происходит по другим правилам (это отдельная тема), поэтому макрос с четырьмя полями не подойдет. Формула отлично решает изначально поставленный вопрос о рассечении текста по пробелу. Еще раз спасибо.