Как исправить скрипт автозаполнения адресата документа в 1С:Документооборот 2.1

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

Работа с шаблонами документов в 1С:Документооборот 2.1 КОРП часто требует написания пользовательских скриптов для автозаполнения. Одной из наиболее частых задач является формирование списка адресатов с их должностями и подразделениями. Однако при реализации таких скриптов разработчики сталкиваются с двумя критическими проблемами: некорректная обработка пустых дополнительных реквизитов (ошибка преобразования к Булево) и игнорирование символов переноса строки в результирующем файле MS Word. Разберем подробно, как решить эти задачи и оптимизировать код.

Проблема 1: Ошибка преобразования значения к типу Булево

Рассмотрим ситуацию, когда скрипт обращается к дополнительному реквизиту объекта (например, "Несколько адресатов"). Если этот реквизит в документе не был заполнен или вообще не был создан для данного типа документа, функция ПолучитьЗначениеДопРеквизитаОбъекта может вернуть значение Неопределено. Проанализируем, почему стандартная проверка Если МногоАдресатов Тогда в этом случае вызывает аварийное завершение скрипта.

В языке 1С попытка использовать Неопределено в условии логического оператора Если приводит к ошибке "Преобразование значения к типу Булево не может быть выполнено". Чтобы избежать этого, нам необходимо использовать безопасную проверку. Рассмотрим правильный вариант написания кода:


МногоАдресатов = ПолучитьЗначениеДопРеквизитаОбъекта(Файл.ВладелецФайла, "Несколько адресатов");

// Безопасная проверка: проверяем, что значение заполнено и оно Истина
Если ЗначениеЗаполнено(МногоАдресатов) И МногоАдресатов = Истина Тогда
    РезультатОбработки = "Руководителям подразделений (по списку)";
Иначе
    // Обработка одиночных адресатов
КонецЕсли;

Использование функции ЗначениеЗаполнено позволяет корректно отсечь варианты Неопределено, NULL или пустые значения, предотвращая падение скрипта при заполнении файла.

Проблема 2: Символы переноса строки в MS Word

Выясним причину, по которой стандартная константа Символы.ПС (перенос строки) часто не срабатывает при передаче данных в шаблон Word. При заполнении полей через механизм COM-соединения или XML-структуру, Word интерпретирует символы управления текстом иначе, чем текстовый редактор 1С. Часто Символы.ПС просто заменяется обычным пробелом.

Для решения этой проблемы в MS Word рекомендуется использовать альтернативные коды символов:

  1. Символ(11) — вертикальная табуляция. В Word этот символ интерпретируется как "мягкий перенос строки" (аналог нажатия Shift+Enter). Это наиболее стабильный вариант для формирования многострочного текста внутри одного абзаца.
  2. Символ(13) — возврат каретки. Часто воспринимается Word как конец абзаца.
  3. Символы.ВК + Символы.ПС — классическая комбинация для Windows-систем, которая иногда помогает в старых версиях Word 2010.

Проанализируем пример формирования строки адресата с использованием Символ(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, дадим несколько дополнительных советов:

Таким образом, комбинируя правильную проверку на Неопределено и используя Символ(11) для управления разрывами строк, мы получаем надежный инструмент для автоматизации подготовки документов в 1С:Документооборот.

← На главную