Работа с шаблонами документов в 1С:Документооборот 2.1 КОРП часто требует написания пользовательских скриптов для автозаполнения. Одной из наиболее частых задач является формирование списка адресатов с их должностями и подразделениями. Однако при реализации таких скриптов разработчики сталкиваются с двумя критическими проблемами: некорректная обработка пустых дополнительных реквизитов (ошибка преобразования к Булево) и игнорирование символов переноса строки в результирующем файле MS Word. Разберем подробно, как решить эти задачи и оптимизировать код.
Рассмотрим ситуацию, когда скрипт обращается к дополнительному реквизиту объекта (например, "Несколько адресатов"). Если этот реквизит в документе не был заполнен или вообще не был создан для данного типа документа, функция ПолучитьЗначениеДопРеквизитаОбъекта может вернуть значение Неопределено. Проанализируем, почему стандартная проверка Если МногоАдресатов Тогда в этом случае вызывает аварийное завершение скрипта.
В языке 1С попытка использовать Неопределено в условии логического оператора Если приводит к ошибке "Преобразование значения к типу Булево не может быть выполнено". Чтобы избежать этого, нам необходимо использовать безопасную проверку. Рассмотрим правильный вариант написания кода:
МногоАдресатов = ПолучитьЗначениеДопРеквизитаОбъекта(Файл.ВладелецФайла, "Несколько адресатов");
// Безопасная проверка: проверяем, что значение заполнено и оно Истина
Если ЗначениеЗаполнено(МногоАдресатов) И МногоАдресатов = Истина Тогда
РезультатОбработки = "Руководителям подразделений (по списку)";
Иначе
// Обработка одиночных адресатов
КонецЕсли;
Использование функции ЗначениеЗаполнено позволяет корректно отсечь варианты Неопределено, NULL или пустые значения, предотвращая падение скрипта при заполнении файла.
Выясним причину, по которой стандартная константа Символы.ПС (перенос строки) часто не срабатывает при передаче данных в шаблон Word. При заполнении полей через механизм COM-соединения или XML-структуру, Word интерпретирует символы управления текстом иначе, чем текстовый редактор 1С. Часто Символы.ПС просто заменяется обычным пробелом.
Для решения этой проблемы в MS Word рекомендуется использовать альтернативные коды символов:
Проанализируем пример формирования строки адресата с использованием Символ(11):
Адресат1Полный = НаимПодрАдресат1 + Символ(11) + СклАдресатДолжность1 + Символ(11) + СклАдресатФИО1;
РезультатОбработки = Адресат1Полный;
Посмотрим на исходный код: он содержит много дублирующихся фрагментов для каждого из четырех адресатов. Это затрудняет поддержку. Разберем, как можно оптимизировать скрипт, используя цикл и программное формирование имен реквизитов. Также важно правильно использовать функции склонения, чтобы должности и ФИО выводились в дательном падеже (кому?).
Предлагаем рассмотреть универсальный и надежный вариант скрипта:
РезультатОбработки = "";
ДокументОбъект = Файл.ВладелецФайла;
// 1. Проверяем признак множественности
МногоАдресатов = ПолучитьЗначениеДопРеквизитаОбъекта(ДокументОбъект, "Несколько адресатов");
Если ЗначениеЗаполнено(МногоАдресатов) И МногоАдресатов = Истина Тогда
РезультатОбработки = "Руководителям подразделений (по списку)";
Иначе
МассивАдресатов = Новый Массив;
// 2. Проходим циклом по возможным реквизитам адресатов (от 1 до 4)
Для Инд = 1 По 4 Цикл
ИмяРеквизита = "Подразделение адресата" + ?(Инд = 1, "1", " " + Инд);
АдресатПодразделение = ПолучитьЗначениеДопРеквизитаОбъекта(ДокументОбъект, ИмяРеквизита);
Если ЗначениеЗаполнено(АдресатПодразделение) Тогда
// Извлекаем наименование подразделения (убираем код, если он есть в строке)
СтрПодразделение = Строка(АдресатПодразделение);
ПозПробела = СтрНайти(СтрПодразделение, " ");
НаимПодразделения = Прав(СтрПодразделение, СтрДлина(СтрПодразделение) - ПозПробела);
// Получаем данные руководителя
Руководитель = АдресатПодразделение.Руководитель;
Если ЗначениеЗаполнено(Руководитель) Тогда
ДанныеРегистра = РегистрыСведений.СведенияОПользователяхДокументооборот.ПолучитьСведенияОПользователе(Руководитель);
Должность = ДанныеРегистра.Должность;
// Склоняем должность и ФИО в Дательный падеж (3)
СклДолжность = СклонениеПредставленийОбъектов.ПросклонятьПредставление(Строка(Должность), 3);
ФИОПредставление = Руководитель.ПредставлениеВДокументах;
СклФИО = СклонениеПредставленийОбъектов.ПросклонятьПредставление(Строка(ФИОПредставление), 3);
// Формируем блок адресата. Используем Символ(11) для переноса внутри блока.
ТекстАдресата = НаимПодразделения + Символ(11) + СклДолжность + Символ(11) + СклФИО;
МассивАдресатов.Добавить(ТекстАдресата);
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Соединяем всех адресатов, разделяя их пустыми строками для визуального разделения
РезультатОбработки = СтрСоединить(МассивАдресатов, Символ(13) + Символ(13));
КонецЕсли;
Проанализировав поведение MS Word, дадим несколько дополнительных советов:
.dotx. Если для поля автозаполнения задана "Точная" высота строки, то перенос текста будет виден лишь частично или скроется совсем. Установите множитель "Одинарный" или "1.5 строки".РегистрыСведений.СведенияОПользователяхДокументооборот. Убедитесь, что у пользователя, запускающего формирование файла, есть права на чтение этого регистра, иначе скрипт вернет пустую должность.Символ(11) не помогает, попробуйте сформировать результат в виде простого текстового сообщения через Сообщить() в тестовой обработке, чтобы убедиться, что логика сбора данных работает верно.Таким образом, комбинируя правильную проверку на Неопределено и используя Символ(11) для управления разрывами строк, мы получаем надежный инструмент для автоматизации подготовки документов в 1С:Документооборот.