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