Как вывести список сотрудников из табличной части в печатную форму Word (OpenXML)

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке печатных форм в формате MS Word (OpenXML) с использованием подсистемы «Печать» из состава Библиотеки стандартных подсистем (БСП) программисты часто сталкиваются с трудностями. Основные проблемы обычно связаны с неправильным заполнением параметров макета, ошибками при обходе табличных частей и выводом данных в виде коллекций (таблиц). В этой статье мы подробно разберем, как правильно сформировать список сотрудников, избежать дублирования или перезаписи данных и корректно вывести их в документ.

Разбор ошибки «Поле объекта не обнаружено (СтрокаСотрудников)»

Одной из самых распространенных ошибок является исключение Поле объекта не обнаружено при вызове метода СформироватьДокумент или ПрисоединитьОбластьИЗаполнитьПараметры. Проанализируем причину ее возникновения. Когда мы используем механизм БСП, система сканирует макет Word на наличие тегов вида {v8 ИмяПараметра}. Если в макете такой тег присутствует, то в структуре данных, передаваемой для заполнения, обязательно должен быть ключ с аналогичным именем.

Рассмотрим ситуацию: если в вашем макете внутри области СтрокаСотрудников указан параметр {v8 СтрокаСотрудников}, а в коде вы передаете структуру ДанныеОбъекта, в которой нет ключа СтрокаСотрудников, БСП выдаст ошибку. Выясним, почему это происходит: подсистема печати пытается сопоставить каждый тег из файла с ключом структуры. Если соответствие не найдено, выполнение прерывается.

Важное правило: Всегда проверяйте соответствие имен в макете и в коде 1С. Если вы добавили параметр в Word, не забудьте добавить его в структуру через Вставить().

Проблема перезаписи данных в цикле

Часто при обходе табличной части сотрудники выводятся некорректно — в документ попадает только последний человек из списка. Разберем код, который приводит к такой ошибке:


Для каждого СтрокаСотр Из КадровыеДанные Цикл
    // ОШИБКА: СтрокаМассива каждый раз инициализируется заново
    СтрокаМассива = ПредставлениеИмени + ", таб.№ " + СЭ_ТабНомер; 
КонецЦикла;
// В итоге в переменную попадет только последняя итерация
ДанныеОбъекта.Вставить("СтрокаСотрудников", СтрокаМассива);

Чтобы решить эту задачу, нам необходимо накапливать значения в строковой переменной. Посмотрим на правильный алгоритм:

  1. Инициализируем переменную пустой строкой до начала цикла.
  2. Внутри цикла прибавляем новые данные к уже существующему значению переменной.
  3. После завершения цикла передаем итоговую строку в структуру данных.

Как вывести список через запятую без лишних знаков в конце

Проанализируем ситуацию, когда нам нужно вывести список сотрудников через запятую, но так, чтобы после последнего сотрудника запятая не ставилась. Для этого удобно использовать логический флаг (булево значение), указывающий на первую итерацию цикла.

Рассмотрим пример кода, реализующий эту логику:


СтрокаМассива = "";
Первый = Истина;

Для каждого СтрокаСотр Из КадровыеДанные Цикл
    // Если это не первая итерация, добавляем разделитель
    Если НЕ Первый Тогда
        СтрокаМассива = СтрокаМассива + ", ";
    КонецЕсли;
    
    // Формируем строковое представление
    ПредставлениеСотрудника = СтрокаСотр.Сотрудник.Наименование + " (таб. № " + СтрокаСотр.ТабельныйНомер + ")";
    СтрокаМассива = СтрокаМассива + ПредставлениеСотрудника;
    
    // Снимаем флаг первой итерации
    Первый = Ложь;
КонецЦикла;

ДанныеОбъекта.Вставить("СтрокаСотрудников", СтрокаМассива);

Такой подход гарантирует чистоту форматирования текста в итоговом документе Word.

Вывод данных в таблицу макета (Коллекции)

Если задача стоит сложнее — например, вывести сотрудников не одной строкой, а в виде полноценной таблицы в Word — нам потребуется метод УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию. Проанализируем основные нюансы работы с коллекциями.

В макете Word область таблицы должна быть оформлена специальными тегами начала и конца области, например: {v8 Область.СтрокаТаблицы} и {/v8 Область.СтрокаТаблицы}. Внутри этой области располагаются параметры (колонки), такие как {v8 ФИО} и {v8 Должность}.

Выясним причину, по которой данные могут не выводиться: метод ПрисоединитьИЗаполнитьКоллекцию ожидает на вход массив структур. Если вы передаете массив ссылок или таблицу значений, в которой имена колонок не совпадают с тегами в макете, данные не отобразятся или возникнет ошибка типа.

Рассмотрим по шагам правильное заполнение таблицы с дополнительными данными (адреса, инициалы):


// 1. Создаем массив для хранения строк таблицы
ДанныеТаблицы = Новый Массив;

Для каждого СтрокаТЧ Из Объект.Сотрудники Цикл
    // Подготавливаем данные по каждому сотруднику
    СтруктураСтроки = Новый Структура;
    
    // Получаем инициалы через типовые функции
    ИмяИнициалы = ФизическиеЛицаКлиентСервер.ФамилияИнициалыФизЛица(СтрокаТЧ.Сотрудник.Наименование);
    СтруктураСтроки.Вставить("СотрудникИнициалы", ИмяИнициалы);
    
    // Получаем контактную информацию (пример)
    Адрес = "г. Москва, ул. Ленина"; // Здесь должен быть вызов функции получения КИ
    СтруктураСтроки.Вставить("АдресПроживания", Адрес);
    
    // Добавляем заполненную строку в массив
    ДанныеТаблицы.Добавить(СтруктураСтроки);
КонецЦикла;

// 2. Выводим область таблицы в печатную форму
Область = УправлениеПечатью.ОбластьМакета(Макет, ОписаниеОбластей["СтрокаТаблицыСот"]);
УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФорма, Область, ДанныеТаблицы);

Оптимизация получения данных

При работе с большим количеством сотрудников (например, в коллективных договорах материальной ответственности) крайне важно избегать выполнения запросов внутри цикла. Рассмотрим подробнее: если для каждого из 50 сотрудников вы будете вызывать функцию УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта, это приведет к 50 отдельным обращениям к базе данных, что существенно замедлит формирование документа.

Рекомендация: Используйте пакетные методы получения данных. Сначала соберите массив всех физических лиц из табличной части, затем одним запросом (или вызовом специализированной функции БСП) получите всю необходимую информацию (адреса, телефоны, паспортные данные) и поместите ее во временную таблицу или соответствие. В цикле обхода сотрудников просто извлекайте уже готовые данные из этой коллекции.

Для получения кадровых данных (должность, подразделение, табельный номер) оптимально использовать метод КадровыйУчет.КадровыеДанныеСотрудников. Он позволяет за один вызов получить структуру данных для всего списка сотрудников на нужную дату.

Резюмируем: Для успешного вывода сотрудников в Word необходимо строго соблюдать соответствие имен параметров в коде и макете, правильно аккумулировать строковые данные в циклах и использовать массивы структур для заполнения табличных областей. Понимание механизмов работы подсистемы УправлениеПечатью позволяет создавать профессиональные и быстродействующие печатные формы любой сложности.

← На главную