В практике администраторов и разработчиков 1С нередко возникают ситуации, когда необходимо внести точечные правки в документы прошлых периодов. Типичный пример — исправление «сбившейся» нумерации, которая мешает корректной выписке новых документов. Главная сложность здесь заключается в том, что период уже закрыт, установлена дата запрета изменения данных, а любое вмешательство может привести к необходимости перепроводить документы и перезакрывать месяцы за полгода. В этой статье мы подробно разберем, как обойти эти ограничения программными средствами, сохранив целостность учета.
Прежде чем приступать к кодингу, проанализируем ситуацию. В современных решениях на базе Библиотеки стандартных подсистем (БСП), таких как ERP 2.5, УТ 11 или БП 3.0, проверка даты запрета реализована через подписки на события ПередЗаписью. Это означает, что при попытке вызова метода Записать() система обращается к общим модулям, которые сверяют дату документа с настройками в регистре сведений ДатыЗапретаИзменения.
Важно понимать, что обычное включение Привилегированного режима не поможет. Проверка даты запрета — это не ограничение прав доступа (RLS), а программный алгоритм, который работает даже под пользователем с полными правами.
Самый простой и быстрый способ, который часто используют разработчики, — это установка признака загрузки данных. Рассмотрим пример кода:
ОбъектДокумента = СсылкаНаДокумент.ПолучитьОбъект();
ОбъектДокумента.Номер = "НовыйНомер001";
ОбъектДокумента.ОбменДанными.Загрузка = Истина;
Попытка
ОбъектДокумента.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Номер успешно изменен");
Исключение
Сообщить("Ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;
Почему это работает: В коде типовых подписок на события практически всегда стоит условие: если ОбменДанными.Загрузка = Истина, то выполнение всех проверок (включая дату запрета, контроль остатков и проверку заполнения реквизитов) прекращается.
Риски: У этого метода есть существенный недостаток. Устанавливая этот флаг, мы отключаем всю бизнес-логику. Документ может не зарегистрироваться в планах обмена, не обновятся связанные регистры, и не сработают важные алгоритмы проверки уникальности. Пользуйтесь этим методом только для изменения нефинансовых реквизитов, таких как номер или комментарий.
Если мы работаем в конфигурации на БСП, существует более элегантный и «чистый» способ. Мы можем временно отключить механизм проверки дат запрета только для нашего программного кода, не затрагивая других пользователей. Разберем по шагам, как это сделать:
// Отключаем проверку для текущего сеанса
ДатыЗапретаИзменения.ОтключитьПроверкуДляТекущегоСеанса(Истина);
Попытка
ОбъектДокумента = СсылкаНаДокумент.ПолучитьОбъект();
ОбъектДокумента.Номер = "НужныйНомер";
// Записываем документ в обычном режиме, чтобы сработала остальная логика
ОбъектДокумента.Записать(РежимЗаписиДокумента.Запись);
Финализировать
// Обязательно возвращаем проверку в исходное состояние
ДатыЗапретаИзменения.ОтключитьПроверкуДляТекущегоСеанса(Ложь);
КонецПопытки;
Этот метод предпочтительнее, так как он отключает именно проверку даты, оставляя включенными остальные механизмы контроля платформы.
В некоторых версиях БСП предусмотрена возможность передать в объект документа специальный параметр, который скажет системе пропустить проверку даты запрета конкретно для этого действия. Проанализируем пример:
Объект = СсылкаНаДокумент.ПолучитьОбъект();
Объект.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);
// В некоторых конфигурациях ключ может называться "ОбойтиДатуЗапрета"
Объект.ДополнительныеСвойства.Вставить("ОбойтиДатуЗапрета", Истина);
Объект.Записать();
Этот вариант удобен тем, что он точечный — действует только на один конкретный вызов метода Записать().
Одной из главных проблем при изменении документов в прошлом является то, что система помечает месяц как «требующий перезакрытия». В ERP и УТ 11 за это отвечают специальные регистры заданий. Даже если вы изменили просто номер, система увидит факт записи объекта и создаст записи в регистре Задания к расчету себестоимости или Задания к отражению в регл. учете.
Чтобы избежать необходимости перезакрывать месяц, проанализируем ситуацию в регистрах после нашей правки. Если документ не влияет на финансовый результат (вы изменили только номер), необходимо программно удалить записи из следующих регистров:
РегистрСведений.ЗаданияКРасчетуСебестоимостиРегистрСведений.ЗаданияКОтражениюВРегламентированномУчетеРегистрСведений.ЗаданияКРасчетуЭтаповПроизводстваВыясним причину их появления: подписка на событие реагирует на любую запись. Рассмотрим пример очистки таких записей:
НаборЗаписей = РегистрыСведений.ЗаданияКРасчетуСебестоимости.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ОбъектДанных.Установить(СсылкаНаДокумент);
НаборЗаписей.Записать(); // Записываем пустой набор, тем самым удаляя задание
Важно: Делайте это только в том случае, если вы на 100% уверены, что ваши изменения (например, правка номера или комментария) не влияют на суммы, количество, счета учета или даты движений.
При ручном изменении номера в закрытом периоде мы можем столкнуться с проблемой уникальности. Проанализируем ситуацию: если вы установите номер, который уже существует в текущем (открытом) периоде, система может выдать ошибку или, что хуже, «сбить» счетчик автонумерации.
После внесения правок в старые номера рекомендуется выполнить следующие действия:
Для успешного изменения данных в закрытом периоде мы рекомендуем придерживаться следующего алгоритма:
ДатыЗапретаИзменения.ОтключитьПроверкуДляТекущегоСеанса(Истина) для обхода логических блокировок.ОбменДанными.Загрузка = Истина только в крайних случаях, когда нужно обойти жесткие проверки в коде конфигурации.Помните, что любые манипуляции в закрытом периоде — это ответственность разработчика. Тщательно проверяйте, не изменились ли движения документа (проводки) при его простой перезаписи.