Почему не стоит проводить документ программным вызовом формы объекта в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет Промышленность, строительство и АПК
← На главную

Часто в практике разработки на 1С возникает задача программного изменения документа и его последующего проведения. Нередко разработчики пытаются решить её путем программного открытия формы объекта, вызова её методов (например, Пересчет()) и последующей записи через формаЗаказа.Записать(). Давайте разберемся, почему этот подход является опасным, неэффективным и как правильно реализовать подобную функциональность в современных типовых решениях, таких как 1С:ERP Управление предприятием.

Почему вызов через форму — это антипаттерн?

Рассмотрим причины, по которым попытка «прожать кнопки» программно созданной формы приводит к проблемам:

  1. Проблемы с правами доступа: Когда вы используете ПолучитьФорму(), платформа проверяет интерактивные права пользователя. Если у пользователя, под которым работает код (например, фоновое задание или регламентное задание), нет прав на интерактивное открытие формы, процесс завершится ошибкой.
  2. Избыточная нагрузка на систему: Создание формы — это не просто вызов одной процедуры. Платформа инициализирует элементы управления, подписки на события формы, проверяет доступность реквизитов и выполняет клиентский код. Это потребляет значительные ресурсы, даже если вы не вызываете метод Открыть().
  3. Непредсказуемость при обновлении: Типовые конфигурации (особенно ERP) постоянно развиваются. Логика работы форм часто меняется, добавляются новые проверки и условия. Завязывая свою логику на «интерфейсные» методы, вы гарантированно столкнетесь с ошибками после обновления конфигурации.

Разберем альтернативный и правильный подход

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

Шаг 1: Перенос логики в серверные общие модули

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

Примерно так выглядит поиск правильной логики:


// Вместо попытки вызвать форму:
// формаЗаказа.Пересчет(); 

// Найдите в коде процедуры, отвечающие за пересчет:
ЗаказПоставщикуСервер.ПересчитатьСуммыВСтроках(Объект);

Шаг 2: Программная запись и проведение объекта

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


// Получаем объект документа
ДокОбъект = ДокСсылка.ПолучитьОбъект();

// Выполняем необходимые расчеты через общие модули
// Например:
ЗаказПоставщикуСервер.ПриИзмененииКоличества(ДокОбъект);

// Записываем документ с проведением
ПараметрыЗаписи = Новый Структура;
ПараметрыЗаписи.Вставить("РежимЗаписи", РежимЗаписиДокумента.Проведение);
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);

Шаг 3: Использование расширений для дополнения логики

Если вам кажется, что типовой механизм «не дотягивает» или работает не так, как нужно, не стоит пытаться обмануть систему через форму. Используйте Расширения конфигурации. С помощью аннотаций &Вместо, &Перед или &После вы можете вклиниться в типовой процесс проведения или пересчета, не снимая конфигурацию с поддержки.

Преимущества данного метода:

В заключение, проанализируем ситуацию: стремление сделать решение «один раз и надолго» — это похвально. Но достигать этой цели нужно через использование публичного программного интерфейса API типовых решений, а не через попытки программного взаимодействия с клиентскими формами.

← На главную