При пакетной обработке данных начинающие разработчики нередко сталкиваются с вопросом: нужно ли открывать экранную форму каждого элемента справочника, чтобы обновить и сохранить его реквизиты? Проанализируем, как устроена работа с объектами метаданных на платформе 1С:Предприятие, и разберем корректные способы программной записи данных.
Для изменения реквизитов объекта открывать форму не требуется. Форма в 1С — это лишь графический интерфейс для интерактивного взаимодействия пользователя с данными. Программная работа с базой данных строится через обращение к самим объектам прикладного решения.
Открытие экранных форм в цикле создает лишнюю нагрузку на графическую подсистему и клиентское приложение, а также существенно замедляет выполнение обработки. Поэтому для массового заполнения реквизитов всегда используется непосредственная работа с объектной моделью справочника.
Рассмотрим стандартный шаблон кода для обновления реквизитов по списку ссылок. Сначала получаем ссылку на элемент, затем вызываем метод ПолучитьОбъект(), меняем значение нужного реквизита и вызываем метод Записать().
Для Каждого Сотрудник Из СписокСотрудников Цикл
СправочникОбъект = Сотрудник.ПолучитьОбъект();
Если СправочникОбъект <> Неопределено Тогда
СправочникОбъект.ТвойРеквизит = ЗначениеРеквизита;
СправочникОбъект.Записать();
КонецЕсли;
КонецЦикла;
Разберем по шагам, что происходит в этом фрагменте:
ПолучитьОбъект() из объектной ссылки получаем экземпляр типа СправочникОбъект, доступный для редактирования.Записать(), который сохраняет изменения в информационной базе и вызывает обработчики событий модуля объекта (ПередЗаписью, ПриЗаписи).Если после выполнения кода значение в базе не изменилось или возникла ошибка, проанализируем возможные причины:
СотрудникиОрганизаций отображаются данные из связанного справочника ФизическиеЛица или периодических регистров сведений. Если реквизит был добавлен не в сам справочник сотрудников, а в физическое лицо, записывать необходимо объект физического лица:
ФизЛицоОбъект = СсылкаНаСотрудника.Физлицо.ПолучитьОбъект();
ФизЛицоОбъект.ИмяРеквизита = ЗначениеРеквизита;
ФизЛицоОбъект.Записать();
Записать() выполняются встроенные проверки конфигурации. Если они блокируют сохранение данных или перезаписывают реквизит по умолчанию, используем флаг отключения проверок при загрузке:
СправочникОбъект = СсылкаНаСотрудника.ПолучитьОбъект();
СправочникОбъект.ОбменДанными.Загрузка = Истина;
СправочникОбъект.ИмяРеквизита = ЗначениеРеквизита;
СправочникОбъект.Записать();
ОбменДанными.Загрузка = Истина позволяет обойти проверки модуля объекта и подписок на события.ПередЗаписьюВФорме), то прямая запись объекта эти обработчики не вызывает. В таком случае правильным решением является перенос алгоритма в модуль обработки или объекта.Если логика заполнения жестко завязана на контекст формы обычного приложения и ее невозможно перенести в обработку, можно программно открыть форму, заполнить реквизиты и инициировать сохранение:
Форма = СсылкаНаСотрудника.ПолучитьФорму();
Форма.Открыть();
Форма.ИмяРеквизитаФормы = ЗначениеРеквизита;
Форма.ЗаписатьВФорме();
Форма.Закрыть();
Помните, что такой подход является исключительной мерой и должен применяться только тогда, когда прямая запись объекта через ПолучитьОбъект() по архитектурным причинам не применима.