При формировании печатных форм (например, трудовых договоров или соглашений) разработчики часто сталкиваются с ситуацией, когда дата в табличном документе выводится вместе со временем (например, 15.04.1985 0:00:00 вместо требуемого 15.04.1985). Дополнительно задача усложняется, если одна обработка использует несколько разных макетов, состав параметров в которых различается. Попытка прямого обращения к параметру через Макет.Параметры.ИмяПараметра приводит к падению программы с ошибкой «Поле объекта не обнаружено», если в текущем макете такой параметр отсутствует.
Выясним причину такого поведения платформы 1С:Предприятие и разберем по шагам наиболее эффективные способы решения этой задачи.
В свойствах ячеек табличного документа есть возможность задать форматную строку. Однако здесь важно учитывать особенности работы платформы:
Параметр.«Работник: [ФИО], дата рождения: [ДатаРожденияРаботника]»), ячейка имеет тип заполнения Шаблон. В этом случае платформенное форматирование ячейки игнорируется, а все переменные внутри квадратных скобок неявно преобразуются к строковому типу по умолчанию (для типа Дата — полный формат с часами, минутами и секундами).Таким образом, значение даты необходимо преобразовать в строковый вид нужного формата еще до того, как оно попадет в макет.
Проанализируем самый универсальный и безопасный подход. У объекта ПараметрыОбластиТабличногоДокумента есть встроенный метод Заполнить(). Он принимает в качестве источника объект типа Структура, СтрокаТаблицыЗначений или ВыборкаИзРезультатаЗапроса.
Главное достоинство метода Заполнить() заключается в том, что он автоматически сопоставляет имена параметров области макета с ключами структуры и игнорирует несовпадения без вызова исключительных ситуаций. Если параметра нет в конкретном макете, ошибка не возникает.
Посмотрим на пример реализации:
// 1. Получаем область макета
ОбластьМакета = Макет.ПолучитьОбласть("Шапка");
// 2. Создаем структуру данных и заполняем ее из выборки запроса
ДанныеДляЗаполнения = Новый Структура;
ЗаполнитьЗначенияСвойств(ДанныеДляЗаполнения, Выборка);
// 3. Форматируем необходимые даты в нужный строковый вид
Если ЗначениеЗаполнено(Выборка.ДатаРожденияРаботника) Тогда
ДанныеДляЗаполнения.Вставить("ДатаРожденияРаботника", Формат(Выборка.ДатаРожденияРаботника, "ДЛФ=DD"));
КонецЕсли;
Если ЗначениеЗаполнено(Выборка.ДатаДоговора) Тогда
ДанныеДляЗаполнения.Вставить("ДатаДоговора", Формат(Выборка.ДатаДоговора, "ДЛФ=Д"));
КонецЕсли;
// 4. Заполняем параметры области (лишние параметры будут проигнорированы платформой)
ОбластьМакета.Параметры.Заполнить(ДанныеДляЗаполнения);
// 5. Выводим область в результирующий документ
ТабличныйДокумент.Вывести(ОбластьМакета);
Если запрос возвращает множество колонок с датами и форматировать каждое поле вручную неудобно, преобразуем данные пакетно через ТаблицаЗначений:
Дата.
ТаблицаДанных = Запрос.Выполнить().Выгрузить();
// Добавим строковые колонки или обойдем строки для форматирования
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
// Подменяем дату на строковый формат в структуре строки
ДанныеСтроки = Новый Структура;
ЗаполнитьЗначенияСвойств(ДанныеСтроки, СтрокаДанных);
ДанныеСтроки.ДатаРожденияРаботника = Формат(СтрокаДанных.ДатаРожденияРаботника, "ДЛФ=Д");
ОбластьСтрока.Параметры.Заполнить(ДанныеСтроки);
ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
Рассмотрим вариант точечного присвоения параметров. Если нет необходимости переписывать всю логику заполнения документа, можно перехватывать обращение к отсутствующим в макете параметрам с помощью блока Попытка ... Исключение.
Попытка
ОбластьМакета.Параметры.ДатаРожденияРаботника = Формат(Выборка.ДатаРожденияРаботника, "ДЛФ=Д");
Исключение
// Если параметра в текущем макете нет, исключение подавляется
КонецПопытки;
Этот способ прост в реализации, однако при большом объеме выводимых строк или значительном количестве разных параметров код может стать громоздким, а частое возникновение системных исключений снижает производительность.
В некоторых случаях строковое представление даты можно получить непосредственно в тексте запроса, разложив дату на составляющие с помощью функций ГОД(), МЕСЯЦ() и ДЕНЬ(), сформировав итоговую строку нужного вида через строковые операции.
Однако в реальной разработке такой способ применяется редко из-за чрезмерной сложности конструкции запроса. Оптимальным и рекомендуемым стандартом разработки 1С остается использование строкового форматирования через Формат() в коде модуля в сочетании с методом Область.Параметры.Заполнить().