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

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

В процессе работы с 1С:Документооборот часто возникает задача автоматизировать заполнение типовых документов. Одна из таких задач — подготовка шаблонов, текст в которых должен меняться в зависимости от определенных условий. Например, при создании доверенности необходимо включать в нее разные блоки текста с полномочиями в зависимости от того, какое значение выбрано в специальном поле документа.

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

Анализ начальной проблемы и первые шаги

Часто пользователи, не имеющие опыта программирования в 1С, пытаются решить задачу «в лоб», сравнивая значение реквизита напрямую со строкой. Пример такого нерабочего кода:


РезультатОбработки = "";
Полномочие = ВладелецФайла.Ссылка.ДопРеквизиты.НайтиПоНаименованию("Полномочия, права")
Если
Полномочие = "Лизинг"
Тогда РезультатОбработки = "длинющий текст";
КонецЕсли;

Этот код не будет работать, потому что ВладелецФайла.Ссылка.ДопРеквизиты.НайтиПоНаименованию() возвращает не само значение (строку "Лизинг"), а объект — строку табличной части дополнительных реквизитов. Простое сравнение объекта со строкой всегда даст ложный результат. Для корректной работы нужно обращаться к свойству Значение этого объекта и правильно получать эталонные значения для сравнения.

Построение работающего решения

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

Шаг 1. Получение описания дополнительного реквизита

Сначала нам нужно найти сам дополнительный реквизит в системе как объект метаданных. Это делается через план видов характеристик ДополнительныеРеквизитыИСведения.


ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Полномочия, права");

Шаг 2. Получение эталонных значений для сравнения

Значения дополнительных реквизитов хранятся в справочнике ЗначенияСвойствОбъектов. Чтобы наше сравнение было корректным, нужно найти не строки, а ссылки на элементы этого справочника. Важно указать владельца — наш дополнительный реквизит, найденный на предыдущем шаге.


ЗначениеДопРеквизита = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Лизинг",,,ДопРеквизит);

Шаг 3. Получение значения реквизита из документа

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

В контексте скрипта автозаполнения шаблона доступ к документу осуществляется через объект Файл. Правильный путь будет Файл.ВладелецФайла.


СтрокаДопРеквизита = Файл.ВладелецФайла.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");

Шаг 4. Сравнение и формирование результата

Наконец, мы можем сравнить значение из документа (СтрокаДопРеквизита.Значение) с эталонным значением, которое мы нашли на шаге 2. Результат работы скрипта необходимо присвоить переменной РезультатОбработки.

Вот как выглядит рабочий код для одного значения:


РезультатОбработки = "";
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Полномочия, права");
ЗначениеДопРеквизита = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Лизинг",,,ДопРеквизит);

Если ЗначениеЗаполнено(ДопРеквизит) Тогда 
    СтрокаДопРеквизита = Файл.ВладелецФайла.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");
    Если НЕ СтрокаДопРеквизита = Неопределено Тогда 
        Если СтрокаДопРеквизита.Значение = ЗначениеДопРеквизита Тогда 
            РезультатОбработки = "длинющий текст про лизинг";
        КонецЕсли;  
    КонецЕсли;
КонецЕсли;

Решение для нескольких значений реквизита

Наша задача — обрабатывать несколько возможных полномочий. Для этого расширим предыдущий код, используя конструкцию Если ... ИначеЕсли ... КонецЕсли. Сначала найдем все возможные эталонные значения, а затем будем последовательно сравнивать с ними значение из документа.

Финальный рабочий скрипт будет выглядеть так:


РезультатОбработки = "";

// Находим сам доп. реквизит по наименованию
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Полномочия, права");

// Заранее находим все возможные варианты значений этого реквизита
ЗначениеДопРеквизитаЛизинг = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Лизинг",,,ДопРеквизит);
ЗначениеДопРеквизитаУПД = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("УПД",,,ДопРеквизит);
ЗначениеДопРеквизитаГИБДД = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("ГИБДД",,,ДопРеквизит); // Обратите внимание на возможное расхождение в написании, например "ГИБДД" vs "ГИДББ"

Если ЗначениеЗаполнено(ДопРеквизит) Тогда 
    // Получаем строку с реквизитом из конкретного документа
    СтрокаДопРеквизита = Файл.ВладелецФайла.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");
    
    // Проверяем, что реквизит для этого документа вообще заполнен
    Если НЕ СтрокаДопРеквизита = Неопределено Тогда 
        
        // Сравниваем значение из документа с нашими эталонами
        Если СтрокаДопРеквизита.Значение = ЗначениеДопРеквизитаЛизинг Тогда 
            РезультатОбработки = "длинющий текст про лизинг";
        ИначеЕсли  СтрокаДопРеквизита.Значение = ЗначениеДопРеквизитаУПД Тогда
            РезультатОбработки = "длинющий текст про УПД"; 
        ИначеЕсли  СтрокаДопРеквизита.Значение = ЗначениеДопРеквизитаГИБДД Тогда
            РезультатОбработки = "длинющий текст про ГИБДД";  
        Иначе
            // Ветка для случаев, когда значение не совпало ни с одним из ожидаемых
            РезультатОбработки = "длинющий текст про то что мы не знаем про что писать";
        КонецЕсли;  
        
    КонецЕсли;
КонецЕсли;

Этот код полностью решает поставленную задачу. Он надежно получает все необходимые данные и корректно сравнивает их, подставляя нужный текст в итоговый документ.

Оптимизация и альтернативные подходы

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

Пример оптимизированного скрипта:


РезультатОбработки = "";

// Получаем всю таблицу дополнительных реквизитов владельца файла один раз
ДопРеквизиты = Файл.ВладелецФайла.ДополнительныеРеквизиты;

// Находим в этой таблице нужную нам строку по имени свойства (реквизита)
СтрокаПолномочий = ДопРеквизиты.Найти("Полномочия, права", "Свойство");

// Проверяем, что реквизит найден и его значение заполнено
Если СтрокаПолномочий <> Неопределено И ЗначениеЗаполнено(СтрокаПолномочий.Значение) Тогда
    
    // Получаем строковое представление значения дополнительного реквизита
    НаименованиеЗначения = Строка(СтрокаПолномочий.Значение);
    
    // В зависимости от строкового значения подставляем нужный текст
    Если НаименованиеЗначения = "Лизинг" Тогда
        РезультатОбработки = "длинющий текст про лизинг";
    ИначеЕсли НаименованиеЗначения = "УПД" Тогда
        РезультатОбработки = "длинющий текст про УПД";
    ИначеЕсли НаименованиеЗначения = "ГИБДД" Тогда
        РезультатОбработки = "длинющий текст про ГИБДД";
    Иначе
        РезультатОбработки = "длинющий текст про то что мы не знаем про что писать";
    КонецЕсли;
    
КонецЕсли;

Этот подход более эффективен, так как сокращает количество обращений к базе данных и делает код проще для понимания и поддержки. Сравнение идет напрямую со строками, что избавляет от необходимости предварительного поиска ссылок на значения в справочнике ЗначенияСвойствОбъектов.

Важные рекомендации

При работе со скриптами автозаполнения в 1С:Документооборот помните о следующих моментах:

  1. Обязательная переменная. Результат работы скрипта всегда должен присваиваться переменной с именем РезультатОбработки.
  2. Контекст выполнения. Скрипты выполняются на сервере. Это значит, что в них недоступны методы и объекты, предназначенные для работы на клиенте (например, диалоговые окна).
  3. Доступ к документу. Для получения данных из документа, к которому прикреплен файл шаблона, используйте конструкцию Файл.ВладелецФайла.
  4. Проверка скрипта. В форме настройки правил заполнения полей есть кнопка для проверки скрипта. Используйте ее для быстрой отладки без необходимости каждый раз создавать и заполнять документ.
  5. Глобальная настройка. Убедитесь, что в настройках программы (раздел "Настройка и администрирование" -> "Настройка программы" -> "Работа с файлами") установлен флаг "Использовать автозаполнение шаблонов файлов".
← На главную