Как удалить зависшие записи из регистра «Расчеты с поставщиками по срокам» при непроведенном документе?

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

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

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

В этой статье мы подробно проанализируем архитектуру взаиморасчетов в новых конфигурациях и рассмотрим способы корректного удаления таких фантомных записей.

Понимаем архитектуру: почему движения остались?

Прежде чем приступать к исправлению, давайте разберемся, почему так происходит. В отличие от старых конфигураций (например, УПП 1.3), в КА 2 и ERP используется механизм отложенного проведения взаиморасчетов.

Этот механизм работает следующим образом:

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

Именно поэтому, когда мы распроводим «Ввод остатков», движения в регистре сроков могут остаться, если цепочка обновлений дала сбой (например, регламентное задание не отработало или запись из очереди заданий исчезла).

Способ 1. Штатное обновление через регламентные задания

Самый безопасный и методологически верный способ исправить ситуацию — заставить систему саму пересчитать итоги. Нам не нужно лезть в базу кодом или прямыми запросами, если мы можем инициировать штатный пересчет.

Для этого выполним следующие действия:

  1. Перейдем в раздел НСИ и Администрирование -> Обслуживание.
  2. Откроем Регламентные и фоновые задания.
  3. Найдем задание с названием, похожим на Выполнение отложенных движений по расчетам с партнерами (название может незначительно отличаться в зависимости от релиза).
  4. Выполним это задание вручную (команда «Выполнить сейчас»).

Если в регистре сведений ЗаданияКРасчетуВзаиморасчетов есть записи, относящиеся к нашему партнеру, система пересчитает регистры и автоматически удалит лишние записи из РасчетыСПоставщикамиПоСрокам, так как первичного документа (основания) уже нет в проведенном состоянии.

Способ 2. «Подталкивание» системы через регистр заданий

Иногда бывает так, что регламентное задание отрабатывает, но ничего не меняется. Это происходит, если регистр ЗаданияКРасчетуВзаиморасчетов пуст — система «думает», что всё уже посчитано верно.

В этом случае нам нужно искусственно создать необходимость пересчета:

  1. Откроем регистр сведений ЗаданияКРасчетуВзаиморасчетов (через «Функции технического специалиста»).
  2. Вручную добавим запись. В качестве аналитики (объекта расчетов) укажем Договор, Заказ или Партнера, по которому у нас возникла проблема.
  3. Запишем изменения.
  4. Снова запустим регламентное задание из Способа 1 или подождем пару минут (если фоновые задания работают автоматически).

Также иногда помогает просто открыть карточку Объекта расчетов (например, Договора с поставщиком) и просто пересохранить её. При записи объекта расчетов система часто формирует задание на актуализацию взаиморасчетов.

Способ 3. Использование встроенных диагностических обработок

Разработчики 1С предусмотрели инструменты для лечения подобных коллизий — в дополнение к ним можно использовать обработку поиска и исправления ошибок учета в КА и ERP. Давайте воспользуемся ими.

В меню «Функции технического специалиста» (ранее «Все функции») поищем обработки по ключевым словам:

Например, обработка ЗаполнениеРегистровВзаиморасчетов позволяет выбрать конкретную АналитикуУчетаПоПартнерам и ОбъектРасчетов. Запустив её, мы инициируем принудительное переформирование движений именно по выбранным разрезам. Это часто помогает убрать «хвосты» от распроведенных документов.

Способ 4. Программное удаление (для разработчиков)

Если штатные средства не помогают, и мы уверены, что записи являются мусором, придется удалить их программно. В простых случаях может помочь универсальная корректировка и чтение остатков регистра накопления, но здесь кроется главная ошибка: мы не можем просто отобрать записи по регистратору «Ввод остатков», так как он не является регистратором в этом регистре. Также здесь не сработает стандартное сторнирование документа, так как цепочка связи с регистратором разорвана.

Разберем алгоритм правильного удаления (для понимания механики полезно изучить примеры того, как выполняется корректировка записей регистра и ОперацияБух в примерах):

  1. Нам нужно найти записи в регистре РасчетыСПоставщикамиПоСрокам по измерению ОбъектРасчетов или АналитикаУчетаПоПартнерам, которые ссылаются на наш проблемный документ.
  2. В этих записях мы должны посмотреть, кто является реальным Регистратором. Скорее всего, это будет документ вида Документ.РегистраторРасчетов.
  3. Создать набор записей именно для этого найденного регистратора, прочитать его и удалить лишние строки.

Посмотрим на примерный код, который поможет очистить регистр. Будьте предельно осторожны и обязательно сделайте резервную копию перед выполнением:


// 1. Ищем проблемные записи. Допустим, мы знаем проблемный ОбъектРасчетов (ссылка на документ или договор)
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	Рез.Регистратор КАК Регистратор
    |ИЗ
    |	РегистрНакопления.РасчетыСПоставщикамиПоСрокам КАК Рез
    |ГДЕ
    |	Рез.ОбъектРасчетов = &ПроблемныйОбъект";

Запрос.УстановитьПараметр("ПроблемныйОбъект", СсылкаНаВводОстатковИлиДоговор);
Выборка = Запрос.Выполнить().Выбрать();

// 2. Обходим найденные документы-регистраторы (это будут РегистраторыРасчетов)
Пока Выборка.Следующий() Цикл
    
    // Создаем набор записей для найденного регистратора
    Набор = РегистрыНакопления.РасчетыСПоставщикамиПоСрокам.СоздатьНаборЗаписей();
    Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
    Набор.Прочитать();
    
    // 3. Анализируем и удаляем лишнее
    // Вариант А: Если мы уверены, что весь этот регистратор ошибочный (в нем только мусор)
    // Набор.Очистить(); 
    
    // Вариант Б: Аккуратное удаление только строк по нашему объекту
    МассивКУдалению = Новый Массив;
    Для Каждого Запись Из Набор Цикл
        Если Запись.ОбъектРасчетов = СсылкаНаВводОстатковИлиДоговор Тогда
            МассивКУдалению.Добавить(Запись);
        КонецЕсли;
    КонецЦикла;
    
    Если МассивКУдалению.Количество() > 0 Тогда
        Для Каждого УдаляемаяЗапись Из МассивКУдалению Цикл
            Набор.Удалить(УдаляемаяЗапись);
        КонецЦикла;
        
        // ВАЖНО: При записи набора с отбором по регистратору, 1С перезаписывает движения этого регистратора.
        // Поэтому важно было прочитать существующие и удалить только лишние.
        Набор.Записать();
        Сообщить("Скорректированы записи для регистратора: " + Выборка.Регистратор);
    КонецЕсли;
    
КонецЦикла;

Важное примечание: Документ РегистраторРасчетов может содержать движения сразу по нескольким партнерам и документам (он собирает "пачку" изменений). Поэтому нельзя просто очищать набор записей без разбора — нужно удалять только строки, относящиеся к вашему проблемному объекту, как показано в «Варианте Б» выше.

Заключение

Проблема «неудаляемых» движений в КА 2 / ERP — это следствие сложной архитектуры отложенных расчетов. Ключ к решению — понимание того, что реальным регистратором является не первичный документ, а служебный РегистраторРасчетов.

Мы рекомендуем всегда начинать с использования штатных механизмов (Способ 1 и 2), так как ручное вмешательство в регистры (Способ 4) может привести к нарушению целостности данных, если не учесть всех нюансов связей между таблицами.

← На главную