В процессе сопровождения конфигураций 1С (особенно классических решений на обычных формах, таких как «Бухгалтерия предприятия 2.0») перед разработчиками нередко возникает задача точечного изменения реквизитов документов в закрытых периодах. Это могут быть чисто информационные поля: «Комментарий», «Основание», «Сделка», ссылка на входящий документ или, как в рассматриваемом случае, «Основание счета на оплату» на вкладке «Дополнительно».
Стандартными интерактивными методами изменить такие реквизиты невозможно, поскольку система выдаст ошибку о нарушении даты запрета изменения данных. Более того, простое программное изменение и последующее проведение документа крайне нежелательны: перепроведение документов «задним числом» может привести к искажению бухгалтерских и налоговых итогов, а также к нежелательному сдвигу границы последовательности проведения документов.
В данной статье мы подробно разберем, как решить эту задачу изящно и безопасно: обойти проверку даты запрета редактирования, обновить только нужный реквизит без изменения проводок и зарегистрировать изменения для планов обмена, чтобы обновленные данные корректно ушли в другие базы (например, в «Управление торговлей»).
Для реализации этой задачи нам потребуется задействовать два важнейших механизма платформы 1С:Предприятие:
ОбменДанными.Загрузка.РежимЗаписиДокумента.Запись.Рассмотрим подробнее, как работает свойство ОбменДанными.Загрузка. В типовых конфигурациях 1С проверка даты запрета редактирования и проверка бизнес-логики (заполнение обязательных полей, сверка остатков и т.д.) реализованы через специализированные подписки на события (например, ПередЗаписьюДокумента). Внутри обработчиков этих подписок первой строкой всегда стоит проверка:
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Установив это свойство в значение Истина, мы сообщаем платформе, что объект записывается в режиме распределенной базы данных (РИБ) или обмена данными. В этом режиме система отключает принудительные контроли проведения, проверки заполнения реквизитов и, самое главное, полностью игнорирует установленную в системе дату запрета изменения данных.
Второй критически важный момент — использование правильного режима записи. Если мы используем метод Записать(РежимЗаписиДокумента.Запись), система перезапишет только шапку и табличные части самого документа, но при этом не будет очищать или перезаписывать движения документа по регистрам бухгалтерии и накопления. Это полностью гарантирует сохранность финансовой отчетности.
Давайте пошагово разберем, как спроектировать и написать код для нашей внешней обработки. Нам понадобится получить ссылку на изменяемый документ, модифицировать его реквизит, обойти защиту закрытого периода и принудительно зарегистрировать изменения для последующего обмена данными.
Ниже приведен готовый шаблон кода, который можно использовать в модуле вашей обработки:
// Выбираем документ-источник (например, Реализация товаров и услуг)
СсылкаНаДокумент = ...; // Здесь должна быть ваша ссылка на документ
// Получаем объект документа для редактирования
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// Заполняем нужный реквизит. В нашем примере — это Основание счета на оплату
// Мы берем связанный документ "Заказ покупателя" из структуры подчиненности или из реквизита сделки
ДокОбъект.ОснованиеСчетаНаОплату = СсылкаНаЗаказ;
// Устанавливаем признак загрузки данных.
// Это ключевой шаг для обхода даты запрета изменения данных!
ДокОбъект.ОбменДанными.Загрузка = Истина;
// Записываем документ строго в режиме ЗАПИСЬ.
// Проводки документа не изменятся, граница последовательности останется на месте.
Попытка
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Документ " + Строка(СсылкаНаДокумент) + " успешно изменен в закрытом периоде!");
Исключение
Сообщить("Не удалось записать документ: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Обратим внимание на важный нюанс, который часто упускают начинающие разработчики. Поскольку мы принудительно установили признак ОбменДанными.Загрузка = Истина, встроенные подписки на события автоматической регистрации изменений для планов обмена также были проигнорированы платформой. Это означает, что если ваша информационная база находится в регулярном обмене с другой системой (например, УТ 10.3 или УТ 11), то внесенные вами изменения в закрытом периоде не выгрузятся автоматически при следующем сеансе обмена.
Чтобы решить эту проблему, нам необходимо выполнить программную регистрацию изменений на узлах обмена вручную. Метод ПланыОбмена.ЗарегистрироватьИзменения() работает напрямую с таблицами регистрации изменений, не вызывая обработчиков событий и проверок дат запрета.
Давайте модернизируем наш код и добавим в него универсальный обход узлов плана обмена для регистрации изменений:
// Записываем документ
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
// Программная регистрация изменений для синхронизации с другими базами
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УзлыОбмена.Ссылка КАК Ссылка
|ИЗ
| ПланОбмена.ОбменУправлениеТорговлейБухгалтерияПредприятия КАК УзлыОбмена
|ГДЕ
| УзлыОбмена.Ссылка <> &ЭтотУзел";
// Исключаем текущий предопределенный узел "ЭтотУзел"
Запрос.УстановитьПараметр("ЭтотУзел", ПланыОбмена.ОбменУправлениеТорговлейБухгалтерияПредприятия.ЭтотУзел());
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Регистрируем измененный документ на каждом узле обмена
ПланыОбмена.ЗарегистрироватьИзменения(Выборка.Ссылка, СсылкаНаДокумент);
Сообщить("Изменение зарегистрировано для узла: " + Строка(Выборка.Ссылка));
КонецЦикла;
Используя данный подход, вы можете быть абсолютно уверены, что реквизит успешно изменится в вашей базе, а при очередном автоматическом обмене измененное «Основание счета на оплату» безболезненно улетит во вторую базу, не вызывая конфликтов блокировки периодов. Для настройки регулярной синхронизации по расписанию может применяться инструмент регулярного обмена данными по расписанию.
Необходимо помнить базовое правило разработки в 1С: использование свойства ОбменДанными.Загрузка = Истина для изменения реквизитов задним числом является безопасным исключительно для реквизитов, не влияющих на движения по регистрам.
Если вам требуется изменить такие реквизиты, как сумма документа, контрагент, склад, номенклатура, ставка НДС или дата документа — данный метод использовать категорически запрещено! Изменение этих параметров без перепроведения приведет к тяжелейшей рассинхронизации данных, когда в самом документе (в его шапке или табличной части) будут записаны одни значения, а в регистрах накопления и бухгалтерии (которые и формируют баланс, отчет о прибылях и убытках, ведомости по взаиморасчетам) останутся старые данные. В таких ситуациях необходимо только полноценное перепроведение с временным открытием периода. Для оперативного контроля и поиска подобных расхождений в проводках и документах используется инструмент автоматической сверки бухгалтерских и налоговых проводок.
Если вы не хотите писать внешнюю обработку с нуля, можно воспользоваться готовым решением от фирмы 1С. Для обычного приложения (конфигурации на платформе 8.2 / 8.3 без управляемых форм) существует универсальная обработка «Групповая обработка справочников и документов» или более современная внешняя обработка «Групповое изменение реквизитов», которую можно легально скачать с диска или сайта ИТС. Также для подобных задач подойдёт групповая обработка документов с поддержкой режима загрузки.
Для того чтобы обойти дату запрета с помощью типовой обработки, выполним следующие действия: