При выполнении регламентных процедур администрирования, таких как «Тестирование и исправление информационной базы» (ТиИ), специалисты нередко сталкиваются с ситуацией, когда процедура «Пересчет итогов» выполняется аномально долго — десятки часов — либо зависает полностью, даже на относительно небольших файловых базах объемом 2–3 ГБ. Разберем внутренние механизмы платформы 1С, выясним причину такого поведения и рассмотрим пошаговые методы локализации и устранения неисправности.
Платформа 1С:Предприятие в регистрах накопления и бухгалтерии использует механизм хранения рассчитанных агрегатов (итогов) с помесячной дискретностью. Это означает, что система формирует и сохраняет точки остатков на начало каждого календарного месяца между самой ранней датой движения в базе и установленной границей рассчитанных итогов.
Если пользователь или обработка загрузки данных случайно ошибается при вводе даты документа (например, указывает дату 10.05.0112 вместо 10.05.2012 или вводит далекое будущее вроде 3999 года), платформа при попытке пересчитать итоги начинает создавать помесячные срезы за все пропущенные столетия. Для интервала с 112 по 2024 год системе требуется сгенерировать и записать более 22 900 пустых срезов итогов по каждому счету, субконто или измерению регистра.
Это приводит к следующим негативным последствиям:
Проанализируем информационную базу и найдем ошибочные записи в регистрах и документах. Для этого выполним поиск через консоль запросов или внешнюю обработку. Проверим все таблицы движений на наличие дат за пределами разумного диапазона учета (например, ранее 2000 года или позднее текущего десятилетия).
Посмотрим на пример запроса для поиска некорректных записей в регистре бухгалтерии:
ВЫБРАТЬ
Хозрасчетный.Период КАК Период,
Хозрасчетный.Регистратор КАК Регистратор,
Хозрасчетный.НомерСтроки КАК НомерСтроки,
Хозрасчетный.СчетДт КАК СчетДт,
Хозрасчетный.СчетКт КАК СчетКт,
Хозрасчетный.Сумма КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Период < ДАТАВРЕМЯ(2000, 1, 1, 0, 0, 0)
ИЛИ Хозрасчетный.Период > ДАТАВРЕМЯ(2050, 1, 1, 0, 0, 0)
Аналогичным образом проанализируем регистры накопления. Если запрос возвращает строки, выясним документ-регистратор. Часто дата искажена непосредственно в шапке первичного документа, откуда при проведении она попадает во все зависимые регистры.
Если мы попытаемся стандартно перепровести документ или отредактировать набор записей с включенными итогами, система снова попытается пересчитать агрегаты за сотни лет и зависнет прямо в момент записи. Чтобы избежать этого, перед изменением даты отключим использование итогов в проблемном регистре программно, скорректируем дату документа и набора записей, а затем включим итоги обратно.
Разберем программный пример безопасного отключения и включения итогов:
// Отключаем использование итогов для регистра, чтобы избежать пересчета при записи
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Ложь);
// Получаем объект документа и исправляем дату
ДокументОбъект = НайденныйРегистратор.ПолучитьОбъект();
ДокументОбъект.Дата = ДАТАВРЕМЯ(2012, 5, 10, 12, 0, 0);
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
// Перезаписываем набор записей с правильным периодом
Набор = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументОбъект.Ссылка);
Набор.Прочитать();
Для Каждого Запись Из Набор Цикл
Запись.Период = ДокументОбъект.Дата;
КонецЦикла;
Набор.Записать();
// Включаем использование итогов обратно
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Истина);
Вместо полного запуска глобального тестирования базы можно выполнить точечную установку границы итогов через встроенную обработку «Управление итогами» в режиме «1С:Предприятие» либо программным методом. Это позволяет сдвинуть актуальность агрегатов только на нужный рабочий период (например, на начало текущего месяца), исключая холостую нагрузку.
Рассмотрим, как задать актуальный период программно:
КонецПрошлогоМесяца = НачалоМесяца(ТекущаяДата()) - 1;
// Устанавливаем границу для регистров бухгалтерии и накопления
РегистрыБухгалтерии.Хозрасчетный.УстановитьПериодРассчитанныхИтогов(КонецПрошлогоМесяца);
РегистрыБухгалтерии.Хозрасчетный.ПересчитатьИтоги();
chdbfl.exe: перед масштабным пересчетом итогов в файловой базе обязательно выполним проверку физической целостности с помощью утилиты chdbfl.exe (находится в папке bin установленной платформы), чтобы исключить циклические ссылки и повреждения страниц файла базы.*.dt, развернуть ее на сервере СУБД (PostgreSQL, MS SQL Server) под управлением 64-разрядного сервера 1С, выполнить пересчет итогов серверными мощностями и вернуть базу обратно в файловый режим.