Почему пересчет итогов в 1С зависает или длится много часов и как это исправить?

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

При выполнении регламентных процедур администрирования, таких как «Тестирование и исправление информационной базы» (ТиИ), специалисты нередко сталкиваются с ситуацией, когда процедура «Пересчет итогов» выполняется аномально долго — десятки часов — либо зависает полностью, даже на относительно небольших файловых базах объемом 2–3 ГБ. Разберем внутренние механизмы платформы 1С, выясним причину такого поведения и рассмотрим пошаговые методы локализации и устранения неисправности.

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

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

Если пользователь или обработка загрузки данных случайно ошибается при вводе даты документа (например, указывает дату 10.05.0112 вместо 10.05.2012 или вводит далекое будущее вроде 3999 года), платформа при попытке пересчитать итоги начинает создавать помесячные срезы за все пропущенные столетия. Для интервала с 112 по 2024 год системе требуется сгенерировать и записать более 22 900 пустых срезов итогов по каждому счету, субконто или измерению регистра.

Это приводит к следующим негативным последствиям:

  1. Экспоненциальный рост времени обработки: платформа выполняет циклическую обработку колоссального массива интервалов.
  2. Переполнение файловых таблиц: в файловой базе (*.1CD*) внутренний размер отдельной таблицы и ее индексов ограничен (2–4 ГБ), что вызывает аварийные остановки с ошибками СУБД или повреждением файла.
  3. Исчерпание оперативной памяти: 32-разрядный клиентский процесс платформы ограничен 2–3 ГБ адресуемого адресного пространства, из-за чего при длительном формировании служебных структур возникает ошибка нехватки памяти.

Шаг 1. Диагностика и поиск записей с аномальными датами

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

Посмотрим на пример запроса для поиска некорректных записей в регистре бухгалтерии:


ВЫБРАТЬ
    Хозрасчетный.Период КАК Период,
    Хозрасчетный.Регистратор КАК Регистратор,
    Хозрасчетный.НомерСтроки КАК НомерСтроки,
    Хозрасчетный.СчетДт КАК СчетДт,
    Хозрасчетный.СчетКт КАК СчетКт,
    Хозрасчетный.Сумма КАК Сумма
ИЗ
    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Период < ДАТАВРЕМЯ(2000, 1, 1, 0, 0, 0)
    ИЛИ Хозрасчетный.Период > ДАТАВРЕМЯ(2050, 1, 1, 0, 0, 0)

Аналогичным образом проанализируем регистры накопления. Если запрос возвращает строки, выясним документ-регистратор. Часто дата искажена непосредственно в шапке первичного документа, откуда при проведении она попадает во все зависимые регистры.

Шаг 2. Корректное исправление ошибочных движений

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

Разберем программный пример безопасного отключения и включения итогов:


// Отключаем использование итогов для регистра, чтобы избежать пересчета при записи
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Ложь);

// Получаем объект документа и исправляем дату
ДокументОбъект = НайденныйРегистратор.ПолучитьОбъект();
ДокументОбъект.Дата = ДАТАВРЕМЯ(2012, 5, 10, 12, 0, 0);
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

// Перезаписываем набор записей с правильным периодом
Набор = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументОбъект.Ссылка);
Набор.Прочитать();

Для Каждого Запись Из Набор Цикл
    Запись.Период = ДокументОбъект.Дата;
КонецЦикла;

Набор.Записать();

// Включаем использование итогов обратно
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Истина);

Шаг 3. Управление периодом рассчитанных итогов

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

Рассмотрим, как задать актуальный период программно:


КонецПрошлогоМесяца = НачалоМесяца(ТекущаяДата()) - 1;

// Устанавливаем границу для регистров бухгалтерии и накопления
РегистрыБухгалтерии.Хозрасчетный.УстановитьПериодРассчитанныхИтогов(КонецПрошлогоМесяца);
РегистрыБухгалтерии.Хозрасчетный.ПересчитатьИтоги();

Дополнительные рекомендации при проблемах с итогами

  1. Проверка утилитой chdbfl.exe: перед масштабным пересчетом итогов в файловой базе обязательно выполним проверку физической целостности с помощью утилиты chdbfl.exe (находится в папке bin установленной платформы), чтобы исключить циклические ссылки и повреждения страниц файла базы.
  2. Анализ зависших остатков («расползание итогов»): если даты корректны, но пересчет идет долго, причиной может быть расхождение аналитики (например, приход лег на пустое субконто, а расход списан с заполненного). Это плодит сотни тысяч неустранимых положительных и отрицательных записей в таблице остатков.
  3. Временный перенос в клиент-серверный вариант (SQL): при значительном объеме данных и нехватке памяти в файловом режиме имеет смысл выгрузить базу в *.dt, развернуть ее на сервере СУБД (PostgreSQL, MS SQL Server) под управлением 64-разрядного сервера 1С, выполнить пересчет итогов серверными мощностями и вернуть базу обратно в файловый режим.
← На главную