Почему при онлайн-взаиморасчетах некорректно работает дата запрета редактирования и как это исправить

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

Переход на новую архитектуру взаиморасчетов (режим «Онлайн») в решениях 1С:ERP и 1С:Комплексная автоматизация приносит не только высокую детализацию расчетов в реальном времени, но и ряд технических сложностей. Одна из наиболее острых проблем — невозможность перепроведения или изменения управленческих документов (например, Заказ клиента или Заказ поставщику) в закрытых периодах, даже если изменения не касаются финансовых показателей. Рассмотрим подробнее, почему так происходит, проанализируем программный код и найдем способы решения этой ситуации.

Суть проблемы: конфликт механизмов пересчета

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

Проблема заключается в том, что алгоритм пересчета затрагивает данные, которые могут находиться глубоко в закрытом периоде. Программа обнаруживает, что для актуализации текущего заказа ей нужно «перетрогать» записи регистров прошлых месяцев, и тут срабатывает механизм ДатыЗапретаИзменения, выбрасывая исключение «При записи».

Анализ программного кода в модуле расчета

Выясним причину ошибки на уровне исходного кода. В конфигурациях ERP и КА основным узлом, где происходит инициация проверки, является общий модуль ОперативныеВзаиморасчетыСервер и модуль менеджера регистра РасчетСКлиентами. Проанализируем типичный фрагмент кода, вызывающий прерывание транзакции:


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

Внутри процедуры РассчитатьПоИзменениям система определяет минимальный период, за который требуется пересчет. Если в цепочке расчетов есть старые авансы или неоплаченные накладные, «минимальный период» может уйти на несколько месяцев назад. Далее вызывается стандартная проверка дат запрета, которая выглядит примерно так:


Если ДатыЗапретаИзменения.НайденЗапретИзмененияДанных(ДанныеДляПроверки, НаборЗаписейПоСрокам) Тогда
    Отказ = Истина;
    ОписаниеОшибки = НСтр("ru = 'Изменяемые данные взаиморасчетов находятся в закрытом периоде.'");
    ВызватьИсключение ОписаниеОшибки;
КонецЕсли;

Важный момент: система проверяет не только дату самого документа, который вы редактируете, но и даты движений, которые порождаются этим редактированием в регистрах расчетов.

Разделы учета, блокирующие запись документа

При использовании онлайн-взаиморасчетов проверка дат запрета становится «ультимативной». Разберем по шагам, какие именно разделы система требует держать открытыми. Как правило, для успешной записи документа программа проверяет следующие сущности в шаблоне данных:

  1. Взаимозачеты и списания задолженности: этот раздел проверяется практически всегда, так как онлайн-механизм постоянно перераспределяет оплаты между документами.
  2. Продажи / Закупки: даже если вы меняете только Заказ клиента, система может инициировать проверку по разделу фактических отгрузок, если заказ связан с реализацией.
  3. Регламентные операции: так как расчеты напрямую влияют на финансовый результат и закрытие месяца.
  4. Бухгалтерский учет: это наиболее критичный момент. В ряде случаев (например, при зачете авансов в валюте) система пытается проверить возможность изменения данных в разрезе организаций по разделу регламентированного учета.

Рассмотрим пример формирования структуры проверки в коде:


ДанныеДляПроверки = ДатыЗапретаИзменения.ШаблонДанныхДляПроверки;
НоваяСтрока = ДанныеДляПроверки.Добавить();
НоваяСтрока.Дата = НачалоДня(ВыборкаМинимальногоПериода.Период);
НоваяСтрока.Раздел = "ВзаимозачетыСписанияЗадолженности";

НоваяСтрока = ДанныеДляПроверки.Добавить();
НоваяСтрока.Дата = НачалоДня(ВыборкаМинимальногоПериода.Период);
НоваяСтрока.Раздел = "РегламентныеОперации";

Как решить проблему: практические рекомендации

На текущий момент в типовых конфигурациях 1С:ERP и КА данное поведение считается архитектурной особенностью. Однако мы можем предложить несколько стратегий для минимизации негативного эффекта.

Вариант 1. Настройка исключений в датах запрета

Проанализируем возможность настройки дат запрета с разбивкой по пользователям и разделам. Вместо того чтобы открывать весь период для всех, попробуйте установить для менеджеров более раннюю дату по разделу «Продажи», но оставить жесткую дату по разделу «Бухгалтерский учет». Однако, как показывает практика, онлайн-расчеты часто требуют открытия всех четырех вышеуказанных разделов одновременно.

Вариант 2. Использование фонового расчета взаиморасчетов

В настройках системы (НСИ и администрирование — Казначейство и взаиморасчеты) существует опция «Выполнять расчет взаиморасчетов при записи документов». Если снять этот флаг, расчет будет выполняться фоновым заданием. Важное преимущество: при записи документа менеджер не получит ошибку ВызватьИсключение, так как расчет будет происходить позже в контексте системного пользователя. Риск: данные в отчетах по задолженности могут появляться с задержкой, а ошибки пересчета будут скапливаться в очереди, которую придется разбирать администратору.

Вариант 3. Использование расширения для обхода проверки

Для опытных программистов решением может стать создание расширения. Необходимо перехватить процедуру проверки даты запрета в момент, когда она вызывается из механизмов онлайн-взаиморасчетов. Мы можем программно «смягчить» проверку, если регистратором является Заказ клиента или Заказ поставщику, и изменения не затрагивают суммы документа.

Пример логики в расширении (псевдокод):


&Вместо("НайденЗапретИзмененияДанных")
Функция Моя_НайденЗапретИзмененияДанных(Данные, НаборЗаписей)
    Если ПараметрыСеанса.ИмяТекущегоУзлаОбмена = "РасчетВзаиморасчетов" Тогда // Условный признак
        Возврат Ложь; // Пропускаем проверку для онлайн-расчетов
    КонецЕсли;
    Возврат ПродолжитьВызов(Данные, НаборЗаписей);
КонецФункции

Вариант 4. Контроль актуальности расчетов

Часто система лезет в далекое прошлое из-за того, что «Дата актуальности расчетов» сбита. Если в регистре ОчередьДвиженийДенежныхСредств висят записи годовой давности, любая текущая операция будет пытаться пересчитать весь год. Рекомендация: регулярно проверяйте и очищайте очередь пересчета, а также следите, чтобы закрытие месяца (в части взаиморасчетов) выполнялось без ошибок.

Резюме

Проблема взаимодействия онлайн-взаиморасчетов и дат запрета является следствием стремления системы к абсолютной точности данных. Пока 1С не выпустила официальный патч, разделяющий управленческие и финансовые проверки в этом механизме, наиболее стабильным решением остается использование фонового режима расчета или точечное открытие периодов для разделов «Взаимозачеты» и «Регламентные операции».

← На главную