Почему в отчете по взаиморасчетам за короткий период долг есть, а за длинный его нет, и как это исправить?

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

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

Рассмотрим подробно, почему возникает такое аномальное поведение, как диагностировать расхождение данных и как полностью восстановить правильность учета.

Выясним причину расхождения данных

В платформе 1С регистры накопления (в данном случае ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов) хранят информацию в двух типах физических таблиц СУБД:

  1. Таблица движений: хранит детальные записи (приход/расход), создаваемые документами-регистраторами (реализациями, платежными поручениями, корректировками долга).
  2. Таблица итогов: хранит рассчитанные агрегированные остатки на начало каждого месяца.

Виртуальные таблицы платформы (такие как ОстаткиИОбороты или Остатки) работают по оптимизированному алгоритму: чтобы не высчитывать итоги с самого начала времен, система берет сохраненное значение начального остатка из таблицы итогов за ближайший рассчитанный месяц и прибавляет к нему реальные движения из таблицы регистраторов за выбранный интервал.

Если в результате программного сбоя, некорректного завершения транзакции или сбоя СУБД таблица итогов за конкретный месяц повреждается, там появляется «фантомный» остаток. При запросе за один месяц платформа считывает битый остаток из таблицы итогов. При запросе за длинный период выборка начинается с более раннего (неповрежденного) месяца, и последовательный расчет по таблице движений перекрывает ошибку, показывая реальное отсутствие долга.

Проанализируем диагностику с помощью запросов

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


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

Если при отмене проведения всех документов по этой цепочке расчетов запрос в 1С к таблице движений возвращает пустой результат, а прямым запросом к таблице итогов в MS SQL Server данные всё равно выбираются, мы имеем дело с повреждением таблицы итогов.

Пример запроса к физической таблице итогов регистра в MS SQL Server (название таблицы может отличаться, например _AccumRgT8580):


SELECT
    РегистрНакопления._Period AS Период,
    РегистрНакопления._Fld8577,
    РегистрНакопления._Fld8572_RRRef
FROM _AccumRgT8580 AS РегистрНакопления
WHERE
    РегистрНакопления._Fld8576RRef = 0xBA43001A64B74BAF11E162C2742E8247
AND
    РегистрНакопления._Fld8572_RRRef = 0xAD91001A64B74BAE11E74DB8A31A9273

Если такой запрос возвращает строки с остатками на 01.06, 01.07 и 01.08 при отсутствии соответствующих регистраторов в таблице движений, это подтверждает расхождение итогов.

Разберем алгоритм исправления проблемы

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

Рассмотрим пошагово порядок действий для полного устранения сбоя:

  1. Локализация периода возникновения ошибки: Путем последовательного построения отчетов сдвигаем начальную дату назад по месяцам (август, июль, июнь и т. д.), пока не определим конкретный месяц, с которого началось расхождение.
  2. Пересчет итогов с захватом проблемного месяца: В режиме конфигуратора или через стандартную обработку «Управление итогами» выполняем пересчет итогов, указав дату начала периода ранее месяца возникновения сбоя (например, если ошибка проявляется с июля, пересчет необходимо выполнять с 01.06 или с начала времен).
  3. Программное сбрасывание и пересчет итогов (альтернативный вариант): Если база работает в монопольном режиме, можно выполнить полный сброс итовгов регистра через внешнюю обработку или встроенный язык:
    
    РегистрыНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.УстановитьИспользованиеИтогов(Ложь);
    РегистрыНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.УстановитьИспользованиеИтогов(Истина);
    
    Метод УстановитьИспользованиеИтогов(Ложь) физически очищает и удаляет таблицу итогов соответствующего регистра, а последующее включение УстановитьИспользованиеИтогов(Истина) полностью заново заносит и просчитывает данные на основании реальных записей из таблицы движений.
  4. Техническое обслуживание СУБД: Если информационная база работает на MS SQL Server, рекомендуем дополнительно выполнить обновление статистики (UPDATE STATISTICS) и реиндексацию (ALTER INDEX REBUILD) для всех таблиц регистров накопления.

После выполнения пересчета итогов с захватом месяца первичного сбоя фантомные остатки исчезают, а данные в отчете «Ведомость по взаиморасчетам с контрагентами» начинают сходиться вне зависимости от выбранного интервала времени.

← На главную