В процессе разработки конфигураций на платформе 1С:Предприятие часто возникает задача автоматического заполнения реквизитов документа при его создании. Это значительно ускоряет работу пользователя, минимизирует количество ошибок и позволяет задать специфическую логику, которая может отличаться от стандартных настроек пользователя. В данной статье мы разберем все доступные способы решения этой задачи: от простых свойств в конфигураторе до написания программного кода в различных модулях.
Первым делом проанализируем самый простой способ, заложенный в платформу. У каждого реквизита документа в конфигураторе есть свойство Значение заполнения. Рассмотрим, как оно работает и в каких случаях его уместно использовать.
Если мы укажем значение в этом поле, платформа автоматически подставит его при создании нового документа. Однако здесь есть существенное ограничение, с которым часто сталкиваются разработчики. В этом свойстве можно выбрать только те значения, которые доступны непосредственно в конфигураторе:
Число, Строка, Дата, Булево.Перечисления.СтатусыДокументов.Новый).Проанализируем ситуацию: если ваш реквизит имеет тип СправочникСсылка.Контрагенты, и в этом справочнике нет предопределенных элементов (созданных в конфигураторе), то при нажатии на кнопку выбора в поле «Значение заполнения» вы увидите пустое окно. Платформа не позволяет выбрать обычные данные из базы (которые создавал пользователь), так как конфигурация должна оставаться независимой от конкретных данных ИБ. Поэтому для динамических данных этот метод не подходит.
Если ваша конфигурация работает в режиме обычного приложения, то основным местом для инициализации значений является модуль формы документа. Разберем по шагам, как это реализовать.
Для начала нам необходимо создать обработчик события ПриОткрытии для формы документа. В этом обработчике мы должны проверить, является ли документ новым. Если мы проигнорируем эту проверку, значения будут перезаписываться каждый раз, когда пользователь открывает уже созданный и сохраненный документ, что недопустимо.
Рассмотрим пример кода для обычного приложения:
Процедура ПриОткрытии()
// Проверяем, что объект еще не записан в базу данных
Если ЭтоНовый() Тогда
// Устанавливаем значения для конкретных реквизитов
Организация = Справочники.Организации.НайтиПоНаименованию("Основная организация");
Склад = Справочники.Склады.НайтиПоКоду("00001");
// Можно также использовать параметры сеанса или общие модули
Автор = ПараметрыСеанса.ТекущийПользователь;
КонецЕсли;
КонецПроцедуры
В данном примере мы используем метод ЭтоНовый(), который возвращает истину, если ссылка на документ еще не сформирована в базе данных. Обратите внимание, что при обращении к реквизитам внутри модуля формы обычного приложения мы пишем их имена напрямую, так как контекст формы совпадает с контекстом объекта.
В режиме управляемого приложения логика работы с формой меняется. Основная работа происходит на сервере, а данные документа доступны через основной реквизит формы — Объект. Выясним причину, почему для этих целей лучше всего подходит событие ПриСозданииНаСервере.
Когда пользователь нажимает кнопку «Создать», платформа создает структуру формы на сервере. Именно в этот момент удобнее всего заполнить данные. Проанализируем код:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверка на новый объект в управляемых формах
// Если ссылка пустая — значит документ еще не записан
Если Объект.Ссылка.Пустая() Тогда
// Заполняем реквизиты через структуру "Объект"
Объект.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701234567");
// Пример получения значения из настроек (если используется БСП)
// Объект.Склад = Справочники.Склады.ПустаяСсылка();
КонецЕсли;
КонецПроцедуры
Важно помнить: в управляемом приложении обращение к реквизитам идет через префикс Объект. (например, Объект.Контрагент). Если вы попытаетесь обратиться просто по имени реквизита, система выдаст ошибку, так как будет искать это имя среди элементов формы или переменных модуля.
Хотя методы, описанные выше, работают, они имеют один существенный недостаток: заполнение происходит только при создании документа через интерфейс формы. Если вы решите создать документ программно (например, при загрузке из Excel или через веб-сервис), код в форме не сработает, и документ останется с пустыми полями.
Поэтому профессиональная разработка в 1С подразумевает использование процедуры ОбработкаЗаполнения в модуле самого объекта. Это событие вызывается платформой всегда при создании нового объекта, независимо от способа создания.
Разберем пример реализации в модуле объекта:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
// Данный метод вызывается при создании нового
// Параметр ДанныеЗаполнения может содержать объект-основание
Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
// Обработка передачи параметров через структуру
ИначеЕсли ДанныеЗаполнения = Неопределено Тогда
// Обычное создание нового документа (не на основании)
Организация = Справочники.Организации.НайтиПоНаименованию("Альфа");
Склад = Справочники.Склады.ОсновнойСклад;
КонецЕсли;
// Заполнение текущего пользователя всегда актуально
Автор = Пользователи.ТекущийПользователь();
КонецПроцедуры
Использование этого метода гарантирует целостность данных системы. Проанализируем ситуацию: если в будущем вы добавите обработку по созданию документов «на лету», вам не придется дублировать логику заполнения значений по умолчанию — она уже будет работать на уровне ядра объекта.
Часто возникает вопрос: нужно ли заполнять значения по умолчанию, если пользователь нажал кнопку «Скопировать»? По умолчанию платформа копирует все данные из старого документа в новый. Но иногда некоторые поля (например, дату, автора или статус) нужно сбросить или установить заново.
В процедуре ОбработкаЗаполнения при копировании в параметр ДанныеЗаполнения передается ссылка на документ-источник. Мы можем использовать это:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
// Это копирование. Возможно, мы хотим очистить склад?
Склад = Справочники.Склады.ПустаяСсылка();
КонецЕсли;
КонецПроцедуры
Выясним еще один нюанс, касающийся реквизитов с составным типом данных (когда поле может принимать значения разных справочников). В управляемых формах при программном заполнении такого поля важно сначала явно указать тип значения. Посмотрим на пример:
// Правильный подход для составного типа в управляемой форме
ОписаниеТипаСправочника = Новый ОписаниеТипов("СправочникСсылка.Контрагенты");
Объект.ВладелецИмущества = ОписаниеТипаСправочника.ПривестиЗначение(НайденнаяСсылка);
Без использования ОписаниеТипов платформа может некорректно отобразить элемент в форме, так как ей нужно понимать, какой именно тип из разрешенного списка выбран в данный момент.
Если вы работаете с типовой конфигурацией (например, 1С:Бухгалтерия или 1С:ERP) и не хотите снимать её с поддержки, рекомендуется использовать Расширения конфигурации. Вы можете создать расширение, добавить в него нужный документ и переопределить процедуру ОбработкаЗаполнения с аннотацией &После. Это позволит внедрить вашу логику заполнения значений по умолчанию, сохранив возможность легкого обновления основной конфигурации.
Таким образом, мы рассмотрели различные уровни настройки: от простых визуальных свойств до гибкого программирования бизнес-логики. Выбор метода зависит от сложности вашей задачи и используемой архитектуры приложения.