В процессе работы с 1С:Документооборот часто возникает задача автоматизировать заполнение типовых документов. Одна из таких задач — подготовка шаблонов, текст в которых должен меняться в зависимости от определенных условий. Например, при создании доверенности необходимо включать в нее разные блоки текста с полномочиями в зависимости от того, какое значение выбрано в специальном поле документа.
Рассмотрим на конкретном примере, как настроить такой механизм. Исходная задача: есть вид внутреннего документа «Доверенность» с дополнительным реквизитом «Полномочия, права». Этот реквизит может принимать значения «Лизинг», «УПД», «ГИБДД» и т.д. В зависимости от выбранного значения, в итоговый файл Word должен подставляться соответствующий юридический текст. Эту логику необходимо реализовать с помощью скрипта в настройках автозаполнения шаблона.
Часто пользователи, не имеющие опыта программирования в 1С, пытаются решить задачу «в лоб», сравнивая значение реквизита напрямую со строкой. Пример такого нерабочего кода:
РезультатОбработки = "";
Полномочие = ВладелецФайла.Ссылка.ДопРеквизиты.НайтиПоНаименованию("Полномочия, права")
Если
Полномочие = "Лизинг"
Тогда РезультатОбработки = "длинющий текст";
КонецЕсли;
Этот код не будет работать, потому что ВладелецФайла.Ссылка.ДопРеквизиты.НайтиПоНаименованию() возвращает не само значение (строку "Лизинг"), а объект — строку табличной части дополнительных реквизитов. Простое сравнение объекта со строкой всегда даст ложный результат. Для корректной работы нужно обращаться к свойству Значение этого объекта и правильно получать эталонные значения для сравнения.
Чтобы правильно реализовать логику, нужно выполнить несколько шагов: получить описание дополнительного реквизита, получить конкретное значение этого реквизита для нашего документа, а затем сравнить его с эталонными значениями.
Шаг 1. Получение описания дополнительного реквизита
Сначала нам нужно найти сам дополнительный реквизит в системе как объект метаданных. Это делается через план видов характеристик ДополнительныеРеквизитыИСведения.
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Полномочия, права");
Шаг 2. Получение эталонных значений для сравнения
Значения дополнительных реквизитов хранятся в справочнике ЗначенияСвойствОбъектов. Чтобы наше сравнение было корректным, нужно найти не строки, а ссылки на элементы этого справочника. Важно указать владельца — наш дополнительный реквизит, найденный на предыдущем шаге.
ЗначениеДопРеквизита = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Лизинг",,,ДопРеквизит);
Шаг 3. Получение значения реквизита из документа
Теперь нужно обратиться к текущему документу (владельцу файла) и получить из его табличной части ДополнительныеРеквизиты строку, соответствующую нашему реквизиту.
В контексте скрипта автозаполнения шаблона доступ к документу осуществляется через объект Файл. Правильный путь будет Файл.ВладелецФайла.
СтрокаДопРеквизита = Файл.ВладелецФайла.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");
Шаг 4. Сравнение и формирование результата
Наконец, мы можем сравнить значение из документа (СтрокаДопРеквизита.Значение) с эталонным значением, которое мы нашли на шаге 2. Результат работы скрипта необходимо присвоить переменной РезультатОбработки.
Вот как выглядит рабочий код для одного значения:
РезультатОбработки = "";
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Полномочия, права");
ЗначениеДопРеквизита = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Лизинг",,,ДопРеквизит);
Если ЗначениеЗаполнено(ДопРеквизит) Тогда
СтрокаДопРеквизита = Файл.ВладелецФайла.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");
Если НЕ СтрокаДопРеквизита = Неопределено Тогда
Если СтрокаДопРеквизита.Значение = ЗначениеДопРеквизита Тогда
РезультатОбработки = "длинющий текст про лизинг";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Наша задача — обрабатывать несколько возможных полномочий. Для этого расширим предыдущий код, используя конструкцию Если ... ИначеЕсли ... КонецЕсли. Сначала найдем все возможные эталонные значения, а затем будем последовательно сравнивать с ними значение из документа.
Финальный рабочий скрипт будет выглядеть так:
РезультатОбработки = "";
// Находим сам доп. реквизит по наименованию
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Полномочия, права");
// Заранее находим все возможные варианты значений этого реквизита
ЗначениеДопРеквизитаЛизинг = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Лизинг",,,ДопРеквизит);
ЗначениеДопРеквизитаУПД = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("УПД",,,ДопРеквизит);
ЗначениеДопРеквизитаГИБДД = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("ГИБДД",,,ДопРеквизит); // Обратите внимание на возможное расхождение в написании, например "ГИБДД" vs "ГИДББ"
Если ЗначениеЗаполнено(ДопРеквизит) Тогда
// Получаем строку с реквизитом из конкретного документа
СтрокаДопРеквизита = Файл.ВладелецФайла.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");
// Проверяем, что реквизит для этого документа вообще заполнен
Если НЕ СтрокаДопРеквизита = Неопределено Тогда
// Сравниваем значение из документа с нашими эталонами
Если СтрокаДопРеквизита.Значение = ЗначениеДопРеквизитаЛизинг Тогда
РезультатОбработки = "длинющий текст про лизинг";
ИначеЕсли СтрокаДопРеквизита.Значение = ЗначениеДопРеквизитаУПД Тогда
РезультатОбработки = "длинющий текст про УПД";
ИначеЕсли СтрокаДопРеквизита.Значение = ЗначениеДопРеквизитаГИБДД Тогда
РезультатОбработки = "длинющий текст про ГИБДД";
Иначе
// Ветка для случаев, когда значение не совпало ни с одним из ожидаемых
РезультатОбработки = "длинющий текст про то что мы не знаем про что писать";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Этот код полностью решает поставленную задачу. Он надежно получает все необходимые данные и корректно сравнивает их, подставляя нужный текст в итоговый документ.
Представленное выше решение является рабочим, но его можно сделать более производительным и читаемым, особенно если в документе много дополнительных реквизитов. Вместо многократного поиска каждого значения по наименованию, что создает нагрузку на базу данных, можно получить все реквизиты документа один раз и работать с ними как с коллекцией, а сравнение проводить по строковому представлению.
Пример оптимизированного скрипта:
РезультатОбработки = "";
// Получаем всю таблицу дополнительных реквизитов владельца файла один раз
ДопРеквизиты = Файл.ВладелецФайла.ДополнительныеРеквизиты;
// Находим в этой таблице нужную нам строку по имени свойства (реквизита)
СтрокаПолномочий = ДопРеквизиты.Найти("Полномочия, права", "Свойство");
// Проверяем, что реквизит найден и его значение заполнено
Если СтрокаПолномочий <> Неопределено И ЗначениеЗаполнено(СтрокаПолномочий.Значение) Тогда
// Получаем строковое представление значения дополнительного реквизита
НаименованиеЗначения = Строка(СтрокаПолномочий.Значение);
// В зависимости от строкового значения подставляем нужный текст
Если НаименованиеЗначения = "Лизинг" Тогда
РезультатОбработки = "длинющий текст про лизинг";
ИначеЕсли НаименованиеЗначения = "УПД" Тогда
РезультатОбработки = "длинющий текст про УПД";
ИначеЕсли НаименованиеЗначения = "ГИБДД" Тогда
РезультатОбработки = "длинющий текст про ГИБДД";
Иначе
РезультатОбработки = "длинющий текст про то что мы не знаем про что писать";
КонецЕсли;
КонецЕсли;
Этот подход более эффективен, так как сокращает количество обращений к базе данных и делает код проще для понимания и поддержки. Сравнение идет напрямую со строками, что избавляет от необходимости предварительного поиска ссылок на значения в справочнике ЗначенияСвойствОбъектов.
При работе со скриптами автозаполнения в 1С:Документооборот помните о следующих моментах:
РезультатОбработки.Файл.ВладелецФайла.