1с проверить помещается ли в ячейку текст
В 1С существует замечательный метод ПроверитьВывод, о котором, к сожалению, знают далеко не все разработчики.
В самой справке (в синтаксис-помощнике) об этом методе сказано следующее: «Проверяет, умещаются ли переданные табличные документы на страницу при печати».
А теперь поподробнее о том, что это за метод и для чего он существует…
Не редко при выводе регламентированных многостраничных печатных форм перед разработчиком встает проблема самостоятельного, программного деления содержимого табличного документа на страницы. Например, если не допускается, чтобы на последней странице присутствовали только подписи и абсолютно необходимо наличие как минимум одной информативной строки. В подобных случаях необходимо предупреждать появление разрыва страниц, и ставить его (разрыв) в документ самостоятельно (после нужной правильной строки).
Как это делается.
Метод табличного документа ПроверитьВывод(МассивТаблиц) имеет один параметр МассивТаблиц - массив из таблиц или табличный документ. Метод проверяет, если к существующему табличному документу (такому, какой он есть сейчас) добавить еще строки – МассивТаблиц – будет ли произведен переход на следующую, новую страницу. Если говорить проще, «влезет» МассивТаблиц на текущую страницу табличного документа или нет. Соответственно, метод возвращает Истину или Ложь в качестве результата свой работы. А дальше, разработчик сам, «ручками», обрабатывает сложившуюся ситуацию:
На что следует обратить внимание при использовании этого метода.
Деление табличного документа на страницы зависит от настроек печати: от принтера по умолчанию, от отступов слева, справа, снизу, сверху, от размера колонтитулов и пр. Поэтому, в случае необходимости не стоит забывать/лениться указывать параметры печати табличного документа в тексте.
В качестве параметра метода МассивТаблиц передается массив таблиц. Здесь должны быть указаны только те таблицы, «умещение» которых мы проверяем. Не надо забывать чистить этот массив перед следующей проверкой.
Перед помещением таблицы в МассивТаблиц, ее необходимо заполнить таблицу всеми необходимыми параметрами. Это важно потому, что одна и та же таблица может иметь различную высоту в зависимости от заполняющих ее данных.
Примечание: в качестве массива таблиц может выступать массив областей макета табличного документа.
Здесь можно скачать пример отчета на платформе 8.2, использующего эту функцию.
Периодически возникает вопрос: поместится ли текст в ячейке табличного документа? Хоть возникает он редко, но всё-таки возникает. В этой статье рассказывается как можно получить ответ на этот вопрос.
Спасибо, за находку, +10$m
предлагаю поменять название на "подгонка размера шрифта под размеры ячейки". - смысл статьи как обходить случаи кода весь текст не помещается в ячейке.
(1) Признаться честно, над названием статьи я, наверное, даже больше просидел, чем над самой статьей. Но с предложенным названием не согласен: статья у меня как раз не как обходить такие случаи, а как их выявить программно. С этим возникает сложность. А вот что делать при таких случаях - это уже у кого на что фантазии хватит.
(1) и спасибо за 10$m. Я и не знал что их можно перекидывать. Правда, я не знаю что с ними надо делать :)
Кстати, да, задача редкая, но не тривиальная.
В прошлом году было подобное, но использовал другую методику, основанную на подгонке строки в ячейке и вычислении получившегося количества символов.
Но получилось достаточно корректно, по крайней мере для того набора строк высота строки вычислялась верно.
Автору огромное спасибо за качественную и достаточно универсальную реализацию недостающей в 1С функции.
(2) Поручик, эта реализация мне понравилась больше, чем указанная вами.
Пригодилось в печати спецификации на "разлинованной" таблице.
Пока внедрял, наткнулся на то, что 1С (рел. 8.2.13.219) при крайних значениях заполнения в ячейке (когда текст чуть-чуть не умещается и переносится на другую строку) не правильно отрабатывает высоту (через картинку). При отладке видно, что текст ПЕРЕНЁССЯ, а высота картинки возвращается такой же, как и без переноса.
Решил проблему дополнительной проверкой с добавлением одного символа:
//Функция для определения вместится ли текст в ячейку:
Функция ТекстУмещаетсяВЯчейке(пОбласть, пТабДок, пТекст)
ВысотаДо = ВысотаОбластиВмм(пОбласть, пТабДок);
// Скопируем область в новый табличный документ.
// И там уже будем играть с её свойствами.
ВремТабДок = Новый ТабличныйДокумент;
ВремТабДок.Вывести(пТабДок);
ВремОбласть = ВремТабДок.Область(пОбласть.Имя);
ВремОбласть.АвтоВысотаСтроки = Истина;
ВремОбласть.ВысотаСтроки = 0;
ВремОбласть.Текст = пТекст;
ВысотаПосле = ВысотаОбластиВмм(ВремОбласть, ВремТабДок);
Если ВысотаДо >= ВысотаПосле Тогда
//Попробуем отловить умещение "на грани": добавим символ
ВремОбласть.Текст = пТекст + "Щ";
ВысотаПослеСимв = ВысотаОбластиВмм(ВремОбласть, ВремТабДок);
Если ВысотаДо >= ВысотаПослеСимв Тогда
Возврат(Истина);
Иначе
Возврат(Ложь);
КонецЕсли;
Иначе
Возврат(Ложь);
КонецЕсли;
Также на базе этой функции написал ПолучитьМассивУмещающихсяСтрок(пОбласть, пТабДок, пТекст), в которой текст разбивается на несколько умещающихся в указанную ячейку строк.
Постраничный вывод в табличный документ
Для некоторых отчетов необходимо, чтобы в конце страницы содержалась некоторая область, которая бы сообщала информацию о содержимом страницы. Это может быть, например, информация о сумме по странице, количестве строк на странице и т.п. Во встроенном языке 1С:Предприятия предусмотрены специальные средства для разбиения табличного документа на страницы. В данном разделе рассказывается, каким образом можно организовать постраничный вывод при выводе информации в табличный документ.
Метод табличного документа ПроверитьВывод()
Объект ТабличныйДокумент имеет метод ПроверитьВывод() , предназначенный для того, чтобы проверить, поместится ли список областей на текущую страницу. В случае если метод вернет значение Истина , вывод областей, переданных в метод, не приведет к созданию новой страницы, иначе, для того, чтобы вывести области, в табличном документе будет создана новая страница. Данный метод работает с учетом настроек печати документа, у которого вызывается метод.
Рассмотрим пример. Пусть нам необходимо создать отчет "Платежная ведомость". Требуется, чтобы на первой странице был заголовок, отображающий информацию о ведомости в целом, на остальных страницах - заголовок, содержащий только шапку таблицы ведомости. В подвалах страницы необходимо иметь информацию о сумме по странице. В подвале последней страницы необходимо иметь итоговую информацию по всей ведомости.
Для того чтобы реализовать подобный отчет нам потребуется использовать метод ПроверитьВывод() . Пример алгоритма отчета будет выглядеть так:
1. выводим в результирующий табличный документ область - заголовок первой страницы;
2. для каждой строки из ведомости:
2.1. проверяем, вмещается ли на текущую страницу область со строкой ведомости и область итога по странице;
2.2. если области помещаются на странице - выводим строку области;
2.3. иначе - выводим подвал страницы, выводим горизонтальный разделитель страницы, выводим шапку страницы, выводим строку ведомости;
3. выводим подвал отчета.
Ниже приведен пример того, как подобный алгоритм может быть реализован на встроенном языке 1С:Предприятия 8.0:
Метод табличного документа ПроверитьПрисоединение()
Метод табличного документа ПроверитьПрисоединение() работает аналогично методу ПроверитьВывод() , с тем отличием, что данный метод проверяет, изменится ли количество страниц по горизонтали при выводе в отчет областей при помощи метода Присоединить() .
Набор процедур и функций для подбора такого максимального размера шрифта ячейки табличного документа, при котором текст целиком помещается в ячейке. Последний раз обработка успешно протестирована на релизе 1С:Предприятие 8.3, учебная версия (8.3.8.1933).
Есть фиксированный макет, разработанный для печати этикетки фиксированного размера. Текст, который выводится в этот макет, может иметь различную, плохо прогнозируемую длину.
Если мы выберем маленький размер шрифта для короткого текста, возникнет резонное замечание – а зачем тут столько пустого места?
Если выберем шрифт больше и попадется длинный текст – возникает вопрос еще более резонный: а что тут напечатано? Часть текста пропала.
Но, увы, этот способ очень медленный.
Если нужно вывести 1-3 простых ценника – это идеальный вариант. Если большой набор этикеток выводит Ответственный или Важный менеджер и это займет у него 30 минут – тоже не вопрос: он "работает". Но если работник с ТСД нажимает кнопку ОК и больше минуты не получает отклика – этот способ совершенно неприемлем.
Не смотря на простоту постановки, задача оказалась весьма сложной.
Конечно, есть вообще уникально-элементарное решение:
Но это все нужно писать под каждый макет, под каждую ячейку отдельно. Это работает кое-как. И это крайне утомительно, скучно и грустно.
Поэтому пришлось искать свое, рабочее решение.
Самый простой способ (который и приводится в примере) – это построить таблицу ширин символов и высот строк для каждого размера шрифта.
Основная проблема в том, что размер символа не линейно зависит от размера шрифта. Множественные попытки применить математику для расчета или прогнозирования ширин и высот не увенчались успехом.
И вот наступил момент, когда стало понятно: время, потраченное на решение задачи, превышает удовольствие от ее решения (иногда эти величины соизмеримы. Особенно когда тратишь на это свое свободное время).
Следующим этапом был вывод:
– если не ставить задачу так строго, то в каком-то очень практичном приближении задачу решить все-таки можно.
Причем, тут нет никакой эмпирики. Все очень строго. Но требует статичного массива информации. (Кто постарше - помните "Таблицы Брадиса"?)
В результате появилась достаточно простая схема: каждый символ имеет некую ширину, которую можно определить. Каждая строка имеет определенную высоту, не зависящую от набора символов в ней. Размер ячейки определяется как: Ширина = (сумма ширин символов строки) + (поля по ширине); Высота = (высота одной строки)*(количество строк) + (вертикальные поля).
Все эти величины удалось определить различными способами (в том числе помог подсмотренный в упомянутой статье метод с рисунком).
К публикации прилагается тестовый фрагмент таблицы размеров шрифта Arial (обычный, курсив, полужирный, полужирный курсив) от 8 до 48.
Ширины расчитаны для букв латиницы, кириллицы (в т.ч. украинских Ї, Ґ ), цифр и основоного набора символов.
Далее – просто ремесло.
Набор предложенных функций реализует следующий механизм:
1. Как и в стандартной схеме мы
1.1. создаем/получаем табличный документ
1.2. получаем/создаем макет
1.3. наполняем макет информацией (заполняем значения параметров и проч.)
1.4. выводим/присоединяем область макета в конечный документ
2. Стандартные методы табличного документа "Вывести" и "Присоединить" заменяются функциями "ВывестиИПодогнатьТекст" и "ПрисоединитьИПодогнатьТекст".
В качестве параметров передаются:
ТабДокПриемник - документ, в который собственно осуществляется вывод
ТабДокИсточник - область макета с заполненными параметрами (или другой табличный документ),
Ячейки - строка с именами или адресами ячеек, для которых необходимо подобрать размер шрифта
Минимальный допустимый размер шрифта
Обязательными являются только два первых параметра.
Если не указаны имена ячеек – подгоняется текст во всех ячейках источника, имеющих "ТипЗаполнения" "Параметр" или "Шаблон".
Если не указан минимальный размер – будет взят минимальный размер, присутствующий в таблице ширин (он же будет использован, если в параметре передано меньшее значение)
УдалятьПробелыПереноса. Кому-то этот параметр покажется смешным и бесполезным. Но я не смог его проигнорировать (тем более что реализуется его назначение в рамках основной задачи очень просто). Суть в следующем.
Например, мы выводим в ячейку несколько однотипных значений (например, цифровых артикулов). По ширине в строках вмещается одинаковое их количество. Если в ячейке установлены размещение текста "Переносить" и Горизонтальное выравнивание Центр, то получится, что последняя строка несколько смещается вправо (см. Рис). Если же заменить пробелы, по которым происходят переносы строк, символами ПС – картинка выглядит гораздо приятнее.
В качестве максимального (с него начинается расчет) принимается размер, указанный разработчиком/дизайнером в макете.
В алгоритме принципиально не учитываются стандартные вертикальные поля и, где это возможно – горизонтальные.
Если возникнет желание их учитывать – в коде есть необходимые комментарии (сами значения в таблице ширин присутствуют).
Ячейки с типом размещения текста "Забивать" и "Обрезать" - не рассматриваются.
Таблицу ширин можно загружать из файла или из справочника. В модуле обработки необходимо внести изменения в шаблоне функции загрузки таблицы ширин.
Я храню ее в глобальной переменной и загружаю при первом вызове процедуры подбора (хотя и не уверен, что это хорошо. подскажите, гуру).
Предложение загрузить файл ширин выводится при открытии обработки. Но это можно зделать и позже по кнопке "Прочитать параметры шрифтов". Также на форме есть две кнопки: Тест1 (подгоняет произвольный текст в ячейку таб.документа на форме) и Тест2 (выводит несколько примеров на основании макета в табличный документ).
Вот, по сути, и все.
В прилагаемой обработке показан упрощенный алгоритм (для облегчения понимания).
В рабочей версии присутствует дополнительный функционал:
* коэффициент высоты (позволяет принудительно управлять размером вертикальных полей)
* интерполяция размера (если в таблице ширин отсутствует необходимый размер)
Не уверен, что этот функционал необходим. Это я добавлял уже под собственные задачи.
Пробуйте. Могут возникнуть неточности при других версиях шрифта и специфических драйверах принтеров.
В 1С существует замечательный метод ПроверитьВывод, о котором, к сожалению, знают далеко не все разработчики.
В самой справке (в синтаксис-помощнике) об этом методе сказано следующее: «Проверяет, умещаются ли переданные табличные документы на страницу при печати».
А теперь поподробнее о том, что это за метод и для чего он существует…
Не редко при выводе регламентированных многостраничных печатных форм перед разработчиком встает проблема самостоятельного, программного деления содержимого табличного документа на страницы. Например, если не допускается, чтобы на последней странице присутствовали только подписи и абсолютно необходимо наличие как минимум одной информативной строки. В подобных случаях необходимо предупреждать появление разрыва страниц, и ставить его (разрыв) в документ самостоятельно (после нужной правильной строки).
Как это делается.
Метод табличного документа ПроверитьВывод(МассивТаблиц) имеет один параметр МассивТаблиц - массив из таблиц или табличный документ. Метод проверяет, если к существующему табличному документу (такому, какой он есть сейчас) добавить еще строки – МассивТаблиц – будет ли произведен переход на следующую, новую страницу. Если говорить проще, «влезет» МассивТаблиц на текущую страницу табличного документа или нет. Соответственно, метод возвращает Истину или Ложь в качестве результата свой работы. А дальше, разработчик сам, «ручками», обрабатывает сложившуюся ситуацию:
На что следует обратить внимание при использовании этого метода.
Деление табличного документа на страницы зависит от настроек печати: от принтера по умолчанию, от отступов слева, справа, снизу, сверху, от размера колонтитулов и пр. Поэтому, в случае необходимости не стоит забывать/лениться указывать параметры печати табличного документа в тексте.
В качестве параметра метода МассивТаблиц передается массив таблиц. Здесь должны быть указаны только те таблицы, «умещение» которых мы проверяем. Не надо забывать чистить этот массив перед следующей проверкой.
Перед помещением таблицы в МассивТаблиц, ее необходимо заполнить таблицу всеми необходимыми параметрами. Это важно потому, что одна и та же таблица может иметь различную высоту в зависимости от заполняющих ее данных.
Примечание: в качестве массива таблиц может выступать массив областей макета табличного документа.
Здесь можно скачать пример отчета на платформе 8.2, использующего эту функцию.
Читайте также: