Поместится ли текст в ячейке? (с примерами использования: авторазмер шрифта, перенос строк)
На просторах интернета я встречал различные решения, но все они носили "вероятностный" характер и строились на определении среднего размера символа (или максимального размера), вычислением длины строки, количеством строк, используя всяческие эмпирические коэффициенты, и всё равно не могли гарантировать, что текст поместится в ячейку.
Единственное решение, близкое к задаче, которое я нашел: Автоматический подбор размера шрифта в объекте РисунокТабличногоДокумента. Но оно для размещения текста в РисунокТабличногоДокумента, а не в область как в данной статье. Оно требует предварительной подготовки, но ничего проще именно для РисункаТабличногоДокумента на данный момент мне неизвестно (попытку упрощения см ниже).
Дальнейший поиск в интернете подтвердил существование как самой проблемы, так и наличие сложностей с её решением. Стоит признать, обсуждения сводились, как это часто бывает, к тому, что автор вопроса просит о никому не нужном функционале. И вообще, автор такого вопроса в ходе осуждения приобретал статус борца с ветрянными мельницами.
Сам я эту проблему зачастую обходил теми или иными путями. И это всех удовлетворяло: и меня, и заказчиков. Видимо, из-за того, что встречается она редко:
1. В ценниках. Наименование товара обычно центрируют по высоте, и при очень длинном наименовании его начало и конец имеют риск не поместиться в отведенное ему место (а в ценниках обычно отключают автовысоту). Из этого положения два выхода:
а) Выбирать тот или иной шаблон ценника. Не реализовано в примерах.
б) Подгонять размер текста под ценник. Реализовано в примерах:
2. И когда наименование нужно написать на несколько строк:
В типовых это реализовано так:
мне же больше по душе выводить его так (с автоматическим переносом слов):
Решение:
Намучавшись за два вечера, пришел, надеюсь, к простому решению:
1. Запоминаем исходный размер ячейки в мм.
2. Назначаем ячейке свойство АвтоВыстота = Истина
3. Вставляем текст и опять смотрим высоту ячейки.
4. Если высота ячейки изменилась в большую сторону - значит, текст не помещается.
Высоту ячейки в мм будем измерять с помощью вставки в ячейку Рисунка и измерением его размеров.
Подробно:
Функция получения высоты ячейки:
Функция для определения вместится ли текст в ячейку:
Для возможности использования этого метода необходимо соблюдать следующие условия:
1. Необходимо как-нибудь назвать область.
2. Заполнение области = Текст, а не Параметр или Шаблон. В принципе, можно использовать и то и другое, но код становиться мудрёней. Во всяком случае, я ничего простого не придумал. И так как жизнь это усложняет не сильно не стал заморачиваться из-за этого.
3. Размещение текста = Перенос. Вот это нужно обязательно! Размещение текста програмно поставить можно, но эффект от изменения, насколько я понял, появляется только после отображения табличного документа с этой ячейкой.
4. Область из одной строки. Т.е. объединять ячейки по вертикали нельзя (в тех которых должен проверяться текст). Исправлено в процессе публикации: создается копия табличного документа с областью и уже меняются её свойства, а не самого табличного документа.
В файлах вы найдете:
1. Пример с подбором размера шрифта с использованием функций из статьи.
2. Оптимизированный по быстродействию пример подбора размера шрифта с небольшой модификацией кода (но подбор размера шрифта - не оптимальный. Ниже есть некая попытка его вычилить а не уменьшать каждый раз на 1).
3. Вывод длинных строк в несколько ячеек.
4. Подбор размера шрифта в элементе "Рисунок табличного документа".
Рисунок табличного документа (Надпись):
Скажу сразу, на больших текстах, работает ужасно долго.
Так вот, с рисунком табличного документа (далее "надписью") пришлось повозиться. Всё дело в том, что при установленом свойстве "Авторазмер" сами размеры подгоняются под текст только после их отображения. Здесь вариантов два:
1. либо ждать какое время и затем смотреть размеры, например так: ПодключитьОбработчикОжидания("ИзмеритьРазмеры", 0.1, Истина)
2. либо "заставить" эту заразу отображаться принудительно.
Первый - рабочий. Однако код с ним получается сложный. И на каждую иттерацию - минимум по 0.1 секунды. В итоге это очень долго. Но работает (вроверял на поле таблчного документа).
А вот второй. С помощью применения маленькой хитрости - всё шикарно работает. А хитрость в том, что есть у ТабличногоДокумента метод Показать(). Хорош он тем, что как раз после его исполнения, размеры надписи уже становятся реальными, подогнанными под размер текста. Но плох он тем, что окрывает окно, которое программно или не закроешь, или я просто не знаю как.
Думал, я думал. А точнее, экперементировал, я экспериментировал. И вот до чего дошел:
Создаем на форме элемент "ПолеТабличногоДокумента" выводим туда нашу надпись. И вуаля - вызов метода "ЭлементыФормы.ПолеТабличногоДокумента.Показать()" не открывает никаких дополнительных окон, да что там, пользователь вообще этого не заметит. Зато мы это заметим. Да и мало того, что заметим, так еще и поэксплуатируем в своих корыстных целях! Ведь после вызова этого метода все высоты и ширины устанавливаются в соответсвие с установленной настройкой "АвтоРазмер = Истина". Красота. Но самое замечательное, что полеТабличногоДокумента можно даже не отображать! Разве, что форму с этим самым полем надо обязательно открывать, что накладывает некоторые ограничения на использование данного метода. Но эту форму можно с прогрессбаром сделать, и ни у кого не будет вопросов насчет открытия каких-то лишних форм.
Код приводить в человеческий вид мне лень. Если что, то есть файл в примерах.