Как программно изменить статус заказа в 1С:ERP или Комплексной автоматизации?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет IT и автоматизация бизнеса
← На главную

В современных конфигурациях 1С, таких как 1С:ERP Управление предприятием или Комплексная автоматизация 2, простое изменение реквизита Статус у документа часто приводит к возникновению ошибок при записи, особенно если требуется редактирование реквизита Статус в закрытом периоде. Это связано с тем, что система выполняет множество проверок в подписках на события и в модуле объекта, проверяя корректность перехода из одного состояния в другое. В рамках данной статьи мы подробно проанализируем, как правильно подойти к решению этой задачи программными средствами.

Разберем стандартный подход через объектную модель

Для начала рассмотрим самый очевидный способ — изменение реквизитов документа через его объектную модель. Нам необходимо получить объект, изменить значение перечисления и попытаться его записать. Однако здесь важно учитывать режим записи. Если мы используем РежимЗаписиДокумента.Запись, статус может измениться, но если логика системы требует проведения для фиксации изменений в регистрах, этого будет недостаточно.

Проанализируем пример кода для изменения статуса в ЗаказКлиента:


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

// Устанавливаем новый статус из соответствующего перечисления
ОбъектЗаказа.Статус = Перечисления.СтатусыЗаказовКлиентов.КВыполнению;

// Попытка записи документа с проведением
Попытка
    ОбъектЗаказа.Записать(РежимЗаписиДокумента.Проведение);
    Сообщить("Статус успешно изменен");
Исключение
    Сообщить("Ошибка при изменении статуса: " + КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

Как мы увидим на практике, этот метод часто выдает ошибку "Переход из статуса X в статус Y невозможен". Это происходит из-за работы механизмов проверки в типовых решениях.

Выясним причину блокировки и используем ДополнительныеСвойства

В конфигурациях на базе ERP разработчики предусмотрели специальные механизмы и обход проверки запрета изменения, позволяющие обходить некоторые блокировки, если действие выполняется программно или в рамках специфических бизнес-процессов. Для этого используется коллекция ДополнительныеСвойства, которая доступна у любого объекта документа.

Рассмотрим подробнее, какие флаги мы можем передать в объект перед его записью. Наиболее часто используемым параметром является ПропуститьПроверкуСтатуса или аналогичные ему, в зависимости от версии конфигурации. Это позволяет системе "понять", что разработчик осознает свои действия и проверку логических переходов выполнять не нужно.

Посмотрим на пример реализации с обходом проверок:


ОбъектЗаказа = СсылкаНаЗаказ.ПолучитьОбъект();
ОбъектЗаказа.Статус = Перечисления.СтатусыЗаказовКлиентов.Закрыт;

// Добавляем специальное свойство для отключения контроля переходов
ОбъектЗаказа.ДополнительныеСвойства.Вставить("ПропуститьПроверкуСтатуса", Истина);
// Также часто требуется отключение проверки заполнения обязательных реквизитов для закрытия
ОбъектЗаказа.ДополнительныеСвойства.Вставить("ОтключитьКонтрольИзмененийПриПроведении", Истина);

Попытка
    // Используем ОбменДанными.Загрузка = Истина, если нужно максимально "тихо" записать объект
    // Но помните, что это отключит вообще все проверки и движения в регистрах могут не обновиться
    // ОбъектЗаказа.ОбменДанными.Загрузка = Истина; 
    
    ОбъектЗаказа.Записать(РежимЗаписиДокумента.Проведение);
Исключение
    Предупреждение("Не удалось закрыть заказ: " + ОписаниеОшибки());
КонецПопытки;

Использование типовых процедур и функций

Проанализируем более "чистый" с точки зрения архитектуры способ. В типовых конфигурациях существуют программные интерфейсы (API), предназначенные для группового изменения статусов. Вместо того чтобы вручную манипулировать объектом, мы можем вызвать экспортные процедуры из общих модулей. Обычно они называются УправлениеЗаказамиКлиентов, УправлениеЗаказамиПоставщикам или ЗаказыСервер.

Почему это лучше? Потому что внутри этих процедур уже прописана правильная последовательность действий, включая заполнение необходимых ДополнительныеСвойства и обработку связанных объектов (например, создание документов ЗакрытиеЗаказов).

Разберем пример вызова такой функции (названия модулей могут варьироваться):


// Пример для закрытия заказа через типовой механизм
МассивЗаказов = Новый Массив;
МассивЗаказов.Добавить(СсылкаНаЗаказ);

// Вызываем процедуру, которая штатно закрывает заказы
// В ERP 2.5 часто используется работа через фоновые задания или специальные менеджеры
УправлениеЗаказамиКлиентов.ЗакрытьЗаказы(МассивЗаказов);

Нюансы при работе с режимом ОбменДанными.Загрузка

Многие программисты пытаются решить проблему установкой Объект.ОбменДанными.Загрузка = Истина. Давайте выясним, почему к этому методу стоит прибегать в последнюю очередь. При активации этого режима:

  1. Не выполняются проверки в модуле объекта и подписках.
  2. Не формируются движения по регистрам (если документ проводится в этом режиме, он просто помечается как проведенный, но записи в регистрах накопления не создаются).
  3. Нарушается целостность данных, так как статус в документе может перестать соответствовать состоянию регистров сведений, отвечающих за состояния заказов.

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

Пошаговый алгоритм безопасного изменения статуса

Подводя итог, сформируем последовательность действий, которую мы должны выполнить для корректного программного изменения статуса:

  1. Определяем целевой статус и убеждаемся, что он существует в соответствующем перечислении Перечисления.СтатусыЗаказов....
  2. Создаем массив ссылок на документы, которые подлежат обработке.
  3. Проверяем возможность перехода. Если это массовая обработка, лучше предварительно проверить текущий статус документа. Нелогично переводить "Закрытый" заказ в статус "К оформлению" без понимания последствий.
  4. Используем блокировку объекта перед изменением, чтобы избежать конфликтов при одновременной работе пользователей.
  5. Заполняем ДополнительныеСвойства. Если мы работаем в 1С:ERP, обязательно изучите содержимое процедуры ПередЗаписью в модуле объекта, чтобы найти флаги, управляющие проверками.
  6. Выполняем запись в режиме проведения.
  7. Обрабатываем результат. Обязательно используйте конструкцию Попытка...Исключение, так как отказ в проведении может возникнуть из-за отсутствия остатков на складах или нехватки прав доступа у текущего пользователя.

Соблюдение этих правил позволит вам корректно автоматизировать работу с заказами в 1С, сохраняя при этом целостность системы и корректность управленческого учета.

← На главную