При работе с конфигурацией «Управление торговлей 10.3» (УТ 10.3) программисты часто сталкиваются с ситуацией, когда необходимо внести незначительные изменения в документ (например, скорректировать комментарий или служебный реквизит), который находится в уже закрытом периоде. Стандартная попытка вызвать метод Записать() приводит к системной ошибке: «Редактирование данных этого периода запрещено. Изменения не могут быть записаны...». Это происходит из-за работы механизмов контроля даты запрета редактирования.
В этой статье мы подробно разберем, почему стандартные методы вроде ОбменДанными.Загрузка = Истина могут не срабатывать, и рассмотрим проверенные способы решения этой задачи, основываясь на архитектурных особенностях обычных форм и платформы 1С:Предприятие 8.1/8.2/8.3.
Многие разработчики, привыкшие к логике «1С:Бухгалтерии 3.0» или других современных конфигураций на управляемых формах, полагают, что установка свойства ОбменДанными.Загрузка = Истина автоматически отключает все проверки. Однако в УТ 10.3 проверка даты запрета зачастую вынесена в подписки на события (например, ПередЗаписью). Проанализируем типичный код такой подписки: если внутри процедуры проверки разработчики конфигурации не прописали явное условие игнорирования при загрузке данных, то проверка сработает в любом случае, блокируя запись объекта.
Это один из самых эффективных и распространенных методов. В УТ 10.3 границы даты запрета для текущего пользователя хранятся в ПараметрыСеанса.ГраницыЗапретаИзмененияДанных. Мы можем временно очистить это значение, выполнить запись и вернуть границы обратно. Рассмотрим пример кода, который реализует этот алгоритм:
// Сохраняем текущие настройки границ во временную переменную
Границы = ПараметрыСеанса.ГраницыЗапретаИзмененияДанных;
// Очищаем границы запрета, устанавливая пустое ХранилищеЗначения
ПараметрыСеанса.ГраницыЗапретаИзмененияДанных = Новый ХранилищеЗначения(Неопределено, Новый СжатиеДанных(0));
// Получаем объект документа и вносим изменения
ТекОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ТекОбъект.Комментарий = "Изменено программно в закрытом периоде";
// Важно: используем режим записи "Запись", чтобы не провоцировать перепроведение
ТекОбъект.Записать(РежимЗаписиДокумента.Запись);
// Восстанавливаем границы запрета обратно
ПараметрыСеанса.ГраницыЗапретаИзмененияДанных = Границы;
Важный нюанс: данный код должен выполняться в одном контексте. Если между очисткой границ и их восстановлением произойдет критическая ошибка, пользователь останется с «открытым» периодом до конца сеанса. Поэтому рекомендуется оборачивать такие действия в конструкцию Попытка ... Исключение.
В некоторых редакциях УТ 10.3 реализована проверка константы, которая определяет, распространяется ли дата запрета на пользователей с полными правами. Если у вас есть полные права, мы можем временно отключить эту проверку. Проанализируем ситуацию, когда необходимо не просто записать комментарий, но и выполнить отмену проведения в закрытом периоде.
// 1. Запоминаем текущее значение константы
ЗначениеКонстанты = Константы.ПрименятьДатуЗапретаДляПолныхПрав.Получить();
// 2. Разрешаем редактирование для полных прав
Константы.ПрименятьДатуЗапретаДляПолныхПрав.Установить(Ложь);
// 3. Обновляем параметры сеанса через типовую процедуру (обычно в модуле ПолныеПрава)
ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных();
// 4. Выполняем действия с документом
ОбъектДокумента = СсылкаНаДокумент.ПолучитьОбъект();
ОбъектДокумента.Записать(РежимЗаписиДокумента.ОтменаПроведения);
// 5. Возвращаем константу и обновляем параметры сеанса обратно
Константы.ПрименятьДатуЗапретаДляПолныхПрав.Установить(ЗначениеКонстанты);
ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных();
Рассмотрим риски этого метода: так как константа хранится в базе данных, ее изменение влияет на всех пользователей системы. Если в момент выполнения вашего кода другой администратор решит изменить старый документ, система ему это позволит. Используйте этот метод с осторожностью и только в моменты низкой активности пользователей.
Если ваша база работает на платформе 8.1, метод УстановитьПривилегированныйРежим(Истина) может быть недоступен напрямую в коде формы. Выясним причину: в старых версиях платформы привилегированный режим включается только для Общих модулей, у которых в свойствах установлена галочка «Привилегированный».
Для решения задачи создадим в таком модуле процедуру:
Процедура ЗаписатьДокументБезПроверок(ДокументОбъект) Экспорт
// Внутри привилегированного модуля проверки прав платформой игнорируются
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры
Однако помните: программные проверки, написанные в модуле самого документа через Если ... Тогда Отказ = Истина, всё равно могут сработать, если они не проверяют роль пользователя или флаг привилегированного режима.
При работе в закрытом периоде крайне важно правильно выбирать РежимЗаписиДокумента. Проанализируем три доступных варианта:
Посмотрим на финальный пример безопасной модификации документа из формы списка, объединяющий лучшие практики:
// В форме списка документа
ТекСтрока = ЭлементыФормы.ДокументСписок.ТекущаяСтрока;
Если ТекСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
ТекОбъект = ТекСтрока.ПолучитьОбъект();
// Используем ДополнительныеСвойства, если в конфигурации есть их обработка
ТекОбъект.ДополнительныеСвойства.Вставить("ОтключитьКонтрольПериода", Истина);
Попытка
// Очищаем границы для текущего сеанса
СтарыеГраницы = ПараметрыСеанса.ГраницыЗапретаИзмененияДанных;
ПараметрыСеанса.ГраницыЗапретаИзмененияДанных = Новый ХранилищеЗначения(Неопределено);
ТекОбъект.Комментарий = "Корректировка " + ТекущаяДата();
ТекОбъект.Записать(РежимЗаписиДокумента.Запись);
// Возвращаем настройки
ПараметрыСеанса.ГраницыЗапретаИзмененияДанных = СтарыеГраницы;
Сообщить("Документ успешно обновлен!");
Исключение
ПараметрыСеанса.ГраницыЗапретаИзмененияДанных = СтарыеГраницы;
Сообщить("Ошибка записи: " + ОписаниеОшибки());
КонецПопытки;
Таким образом, мы выяснили, что для обхода ограничений в УТ 10.3 наиболее надежным инструментом является манипуляция параметрами сеанса ГраницыЗапретаИзмененияДанных в сочетании с режимом записи Запись. Это позволяет сохранять целостность данных, не нарушая работу бухгалтерских и управленческих итогов.