В современных конфигурациях 1С, таких как 1С:ERP Управление предприятием или Комплексная автоматизация 2, простое изменение реквизита Статус у документа часто приводит к возникновению ошибок при записи, особенно если требуется редактирование реквизита Статус в закрытом периоде. Это связано с тем, что система выполняет множество проверок в подписках на события и в модуле объекта, проверяя корректность перехода из одного состояния в другое. В рамках данной статьи мы подробно проанализируем, как правильно подойти к решению этой задачи программными средствами.
Для начала рассмотрим самый очевидный способ — изменение реквизитов документа через его объектную модель. Нам необходимо получить объект, изменить значение перечисления и попытаться его записать. Однако здесь важно учитывать режим записи. Если мы используем РежимЗаписиДокумента.Запись, статус может измениться, но если логика системы требует проведения для фиксации изменений в регистрах, этого будет недостаточно.
Проанализируем пример кода для изменения статуса в ЗаказКлиента:
// Получаем объект документа по ссылке
ОбъектЗаказа = СсылкаНаЗаказ.ПолучитьОбъект();
// Устанавливаем новый статус из соответствующего перечисления
ОбъектЗаказа.Статус = Перечисления.СтатусыЗаказовКлиентов.КВыполнению;
// Попытка записи документа с проведением
Попытка
ОбъектЗаказа.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Статус успешно изменен");
Исключение
Сообщить("Ошибка при изменении статуса: " + КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Как мы увидим на практике, этот метод часто выдает ошибку "Переход из статуса X в статус Y невозможен". Это происходит из-за работы механизмов проверки в типовых решениях.
В конфигурациях на базе ERP разработчики предусмотрели специальные механизмы и обход проверки запрета изменения, позволяющие обходить некоторые блокировки, если действие выполняется программно или в рамках специфических бизнес-процессов. Для этого используется коллекция ДополнительныеСвойства, которая доступна у любого объекта документа.
Рассмотрим подробнее, какие флаги мы можем передать в объект перед его записью. Наиболее часто используемым параметром является ПропуститьПроверкуСтатуса или аналогичные ему, в зависимости от версии конфигурации. Это позволяет системе "понять", что разработчик осознает свои действия и проверку логических переходов выполнять не нужно.
Посмотрим на пример реализации с обходом проверок:
ОбъектЗаказа = СсылкаНаЗаказ.ПолучитьОбъект();
ОбъектЗаказа.Статус = Перечисления.СтатусыЗаказовКлиентов.Закрыт;
// Добавляем специальное свойство для отключения контроля переходов
ОбъектЗаказа.ДополнительныеСвойства.Вставить("ПропуститьПроверкуСтатуса", Истина);
// Также часто требуется отключение проверки заполнения обязательных реквизитов для закрытия
ОбъектЗаказа.ДополнительныеСвойства.Вставить("ОтключитьКонтрольИзмененийПриПроведении", Истина);
Попытка
// Используем ОбменДанными.Загрузка = Истина, если нужно максимально "тихо" записать объект
// Но помните, что это отключит вообще все проверки и движения в регистрах могут не обновиться
// ОбъектЗаказа.ОбменДанными.Загрузка = Истина;
ОбъектЗаказа.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Предупреждение("Не удалось закрыть заказ: " + ОписаниеОшибки());
КонецПопытки;
Проанализируем более "чистый" с точки зрения архитектуры способ. В типовых конфигурациях существуют программные интерфейсы (API), предназначенные для группового изменения статусов. Вместо того чтобы вручную манипулировать объектом, мы можем вызвать экспортные процедуры из общих модулей. Обычно они называются УправлениеЗаказамиКлиентов, УправлениеЗаказамиПоставщикам или ЗаказыСервер.
Почему это лучше? Потому что внутри этих процедур уже прописана правильная последовательность действий, включая заполнение необходимых ДополнительныеСвойства и обработку связанных объектов (например, создание документов ЗакрытиеЗаказов).
Разберем пример вызова такой функции (названия модулей могут варьироваться):
// Пример для закрытия заказа через типовой механизм
МассивЗаказов = Новый Массив;
МассивЗаказов.Добавить(СсылкаНаЗаказ);
// Вызываем процедуру, которая штатно закрывает заказы
// В ERP 2.5 часто используется работа через фоновые задания или специальные менеджеры
УправлениеЗаказамиКлиентов.ЗакрытьЗаказы(МассивЗаказов);
Многие программисты пытаются решить проблему установкой Объект.ОбменДанными.Загрузка = Истина. Давайте выясним, почему к этому методу стоит прибегать в последнюю очередь. При активации этого режима:
Мы рекомендуем использовать этот метод только для исправления технических ошибок в данных, когда стандартные методы проведения не срабатывают из-за критических противоречий в базе.
Подводя итог, сформируем последовательность действий, которую мы должны выполнить для корректного программного изменения статуса:
Перечисления.СтатусыЗаказов....ПередЗаписью в модуле объекта, чтобы найти флаги, управляющие проверками.Попытка...Исключение, так как отказ в проведении может возникнуть из-за отсутствия остатков на складах или нехватки прав доступа у текущего пользователя.Соблюдение этих правил позволит вам корректно автоматизировать работу с заказами в 1С, сохраняя при этом целостность системы и корректность управленческого учета.