Часто у начинающих разработчиков возникает соблазн автоматизировать пересчет данных в документах, вызывая уже написанные обработчики событий формы, например, ПриИзменении. Однако, при попытке сделать это из внешней обработки, возникает масса ошибок: от «поле объекта не обнаружено» до проблем с контекстом исполнения. Давайте разберем, почему так происходит и как правильно организовать архитектуру кода, чтобы избежать подобных трудностей.
Рассмотрим причину возникновения ошибок. Процедуры событий, такие как ПриИзменении, жестко привязаны к контексту формы. Когда вы вызываете такой метод из внешнего кода, происходят следующие критические проблемы:
Элемент ожидает объект типа ПолеФормы. Передача произвольного значения или просто ссылки на данные приведет к тому, что платформа не сможет обратиться к свойствам элемента.Если вам нужно пересчитать данные (например, обновить сумму в табличной части при изменении количества), не стоит пытаться имитировать действия пользователя. Самым надежным решением является вынос общей логики в общие модули или модули объектов.
Разберем по шагам, как это сделать правильно:
Посмотрим на пример правильного подхода к пересчету сумм в документе:
// В общем модуле (например, РаботаСДокументами)
Процедура ПересчитатьСуммуСтроки(СтрокаТабличнойЧасти) Экспорт
СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
КонецПроцедуры
Теперь вы можете использовать эту процедуру в любом месте: как в модуле формы, так и в вашей внешней обработке, просто вызывая её для нужной строки объекта.
Для массовых изменений данных в документах рекомендуется работать непосредственно с ДокументОбъект. Вместо того чтобы открывать форму, вы должны:
Ссылка.ПолучитьОбъект().Объект.Записать().Рассмотрим, как это выглядит в коде:
Выборка = Документы.РеализацияТоваровУслуг.Выбрать();
Пока Выборка.Следующий() Цикл
Объект = Выборка.Ссылка.ПолучитьОбъект();
Для Каждого Строка Из Объект.Товары Цикл
Если Строка.Количество = 1 Тогда
Строка.Количество = 3;
// Вызываем логику пересчета без участия формы
РаботаСДокументами.ПересчитатьСуммуСтроки(Строка);
КонецЕсли;
КонецЦикла;
Объект.Записать();
КонецЦикла;
Подводя итог, можно выделить несколько правил дисциплинированного программирования в 1С:
Следуя этим простым рекомендациям, вы сможете избежать «тупняков» при разработке и сделать свой код профессиональным, предсказуемым и легким в обслуживании.