При разработке печатных форм в формате Word (OpenXML) с использованием Библиотеки стандартных подсистем (БСП) часто возникает задача вывода данных из табличной части. Особенно это актуально для договоров материальной ответственности, где требуется не просто перечислить сотрудников, но и привести их ФИО к формату «Фамилия И.О.», а также добавить контактную информацию, например, адрес проживания.
В этой статье мы разберем, как правильно структурировать код, чтобы эффективно получить данные, обработать их и передать в макет Word. Мы проанализируем типичные ошибки и рассмотрим по шагам процесс создания качественной печатной формы.
Прежде всего, проанализируем ситуацию, представленную в исходном вопросе. Автор пытается получить кадровые данные, сформировать строки и заполнить макет в одной большой функции. Это затрудняет отладку. Рассмотрим более правильный подход: разделим процедуру формирования на три логических этапа:
.docx через механизмы УправлениеПечатью.Одной из главных проблем является получение адресов сотрудников в цикле. Если в табличной части 20 сотрудников, вызов функции получения КИ (контактной информации) 20 раз создаст лишнюю нагрузку на сервер. Разберем, как сделать это оптимально. Мы соберем все ссылки на физических лиц и получим их адреса одним запросом.
Рассмотрим пример кода для подготовки данных:
// Сначала выгружаем массив сотрудников из табличной части
МассивСотрудников = Объект.Сотрудники.ВыгрузитьКолонку("Сотрудник");
// Получаем массив физических лиц для получения адресов
МассивФизЛиц = Новый Массив;
Для Каждого Сотр Из МассивСотрудников Цикл
МассивФизЛиц.Добавить(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Сотр, "ФизическоеЛицо"));
КонецЦикла;
// Получаем адреса всех сотрудников одним вызовом (используем БСП)
ТаблицаАдресов = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъектов(
МассивФизЛиц,
Справочники.ВидыКонтактнойИнформации.АдресМестаПроживанияФизическиеЛица,
ТекущаяДатаСеанса());
Проанализируем этот подход: использование метода КонтактнаяИнформацияОбъектов позволяет избежать множественных обращений к базе данных, что значительно ускоряет формирование документа.
Чтобы вывести сотрудника в формате «Иванов И.И.», вместо полного наименования СтрокаСотр.Сотрудник.Наименование, выясним причину использования системных функций. В 1С есть готовые механизмы в модулях ФизическиеЛицаКлиентСервер или ФизическиеЛицаУТ.
Для получения инициалов используем следующий метод:
// Пример формирования ФИО с инициалами
ФИОСИнициалами = ФизическиеЛицаКлиентСервер.ФамилияИнициалы(СтрокаСотр.СотрудникНаименование);
// Или более гибкий вариант, если есть ФизЛицо:
ФИОСИнициалами = ФизическиеЛицаКлиентСервер.ФорматФИО(Фамилия, Имя, Отчество, 2);
Здесь важно помнить, что если вы используете справочник Сотрудники, то ФИО часто хранится в связанном справочнике ФизическиеЛица. Поэтому данные лучше получать через кадровый учет БСП.
Для вывода табличной части в Word используется метод ПрисоединитьИЗаполнитьКоллекцию. Чтобы он сработал, нам нужно подготовить массив структур, где ключи структуры соответствуют параметрам в фигурных скобках в макете Word (например, {ФИОИнициалы} и {Адрес}).
Разберем процесс формирования массива для вывода:
ДанныеДляТаблицы = Новый Массив;
Для Каждого СтрокаСотр Из КадровыеДанные Цикл
НоваяСтрока = Новый Структура;
// Формируем инициалы
НоваяСтрока.Вставить("ФИОИнициалы", ФизическиеЛицаКлиентСервер.ФамилияИнициалы(СтрокаСотр.Сотрудник));
// Ищем адрес в нашей предварительно полученной таблице адресов
ОтборКИ = Новый Структура("Объект", СтрокаСотр.ФизическоеЛицо);
НайденныеАдреса = ТаблицаАдресов.НайтиСтроки(ОтборКИ);
Если НайденныеАдреса.Количество() > 0 Тогда
НоваяСтрока.Вставить("Адрес", НайденныеАдреса[0].Представление);
Иначе
НоваяСтрока.Вставить("Адрес", "Адрес не указан");
КонецЕсли;
НоваяСтрока.Вставить("Должность", СтрокаСотр.ТекущаяДолжность);
ДанныеДляТаблицы.Добавить(НоваяСтрока);
КонецЦикла;
Выясним, как правильно разметить макет Word. Чтобы программа поняла, что данные нужно выводить в таблицу, область в коде должна быть объявлена как СтрокаТаблицы. В самом файле .docx создайте таблицу, и в одной из строк пропишите параметры, например: {ФИОИнициалы} в первой колонке и {Адрес} во второй.
Рассмотрим финальный фрагмент кода для вывода этой таблицы:
// Инициализируем область строки таблицы
ОбластьСтрока = УправлениеПечатью.ОбластьМакета(Макет, ОписаниеОбластей["СтрокаТаблицаСот"]);
// Заполняем коллекцию данных в печатную форму
УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФорма, ОбластьСтрока, ДанныеДляТаблицы);
Важный момент: Метод ПрисоединитьИЗаполнитьКоллекцию автоматически размножит строку таблицы в Word столько раз, сколько элементов находится в массиве ДанныеДляТаблицы. Это избавляет нас от ручного написания циклов формирования областей.
В договорах материальной ответственности часто требуется выводить сотрудников в родительном падеже. Для этого проанализируем возможность использования функции СклонениеПредставленийОбъектов. Она позволяет просклонять ФИО и должности программно, что делает документ юридически грамотным.
Посмотрим, как это интегрировать:
РезультатСклонения = "";
Если СклонениеПредставленийОбъектов.ПросклонятьПредставление(СтрокаСотр.Сотрудник, 2, РезультатСклонения) Тогда
НоваяСтрока.Вставить("ФИОРодительный", РезультатСклонения);
КонецЕсли;
Подведем итоги. Чтобы успешно вывести сотрудников с их персональными данными в Word, мы выполнили следующие действия: ушли от неэффективных запросов в цикле, подготовили единый массив структур с нужными полями (инициалы, адрес) и использовали стандартные механизмы БСП для заполнения табличных областей. Такой подход обеспечивает высокую скорость работы и легкость поддержки кода.