В практической работе с крупными базами 1С:ERP Управление предприятием бухгалтеры и системные администраторы часто сталкиваются со странным и пугающим поведением программы: после запуска процедуры закрытия месяца оборотно-сальдовая ведомость (ОСВ) по регистру бухгалтерии становится абсолютно пустой или начинает "краснеть" (показывать некорректные, необоснованно отрицательные остатки). При этом сами документы проведены, проводки существуют, но стандартные отчеты их упорно не видят.
Проанализируем эту ситуацию детально. Выясним причину, почему слетают итоги, как устроен этот механизм на уровне платформы 1С и СУБД, а также разберем по шагам, как восстановить работоспособность системы и не допустить повторения проблемы в будущем.
Прежде чем переходить к решению, разберем теорию вопроса. В платформе 1С:Предприятие 8 для регистров (как накопления, так и бухгалтерии) используется двухтабличная архитектура хранения данных. Это классическая попытка объединить OLTP (транзакционную систему) и OLAP (аналитическую систему):
Когда мы строим оборотно-сальдовую ведомость, платформа не сканирует всю таблицу движений с начала времен. Вместо этого она берет остатки на ближайшую контрольную точку из таблицы итогов и быстро прибавляет к ним движения за текущий период. Это обеспечивает высокую скорость работы отчетов. Если итоги отключены, отчеты либо не могут получить остатки вообще (ОСВ становится пустой), либо начинают рассчитывать их "на лету" с колоссальными задержками и ошибками.
Рассмотрим механизм расчета себестоимости и распределения затрат в 1С:ERP. Это чрезвычайно ресурсоемкая операция, которая решает сложнейшую систему линейных алгебраических уравнений (СЛАУ) и формирует сотни тысяч новых проводок по регистру бухгалтерии. При возникновении ошибок на этом этапе пригодится материал по устранению ошибки переполнения стека при расчете себестоимости.
Чтобы ускорить запись этих проводок в базу данных, разработчики 1С применили стандартный оптимизационный маневр. В настройках регламентной операции "Распределение затрат и расчет себестоимости" по умолчанию включен параметр оптимизации итогов. Проанализируем алгоритм работы этой оптимизации:
УстановитьИспользованиеИтогов(Ложь).ПересчитатьИтоги().В чем же кроется проблема? Если в процессе выполнения этого ресурсоемкого этапа происходит аварийное завершение сеанса (например, принудительное завершение фонового процесса пользователем, перезагрузка сервера СУБД, нехватка оперативной памяти или аппаратная ошибка), транзакция прерывается на полпути. Программа просто не успевает выполнить обратное включение и пересчет. В результате итоги в регистре бухгалтерии (Хозрасчетный) остаются выключенными, а таблицы остатков — неактуальными. Для диагностики и устранения причин зависания процессов можно воспользоваться руководством по устранению зависаний при закрытии месяца.
Разберем по шагам, как локализовать проблему и убедиться, что дело именно в отключенных итогах:
Ошибка при вызове метода контекста (УстановитьМинимальныйИМаксимальныйПериодыРассчитанныхИтогов) или нарушения уникальности индексов в таблицах СУБД.Если физических повреждений таблиц СУБД нет, восстановить итоги можно штатными средствами платформы 1С. Рассмотрим этот процесс:
Выясним, как автоматизировать этот процесс или решить проблему, если стандартный интерфейс недоступен или выдает ошибки. Мы можем написать простую внешнюю обработку или выполнить код в консоли разработчика.
Рассмотрим пример программного принудительного включения и пересчета итогов по регистру бухгалтерии:
// Включаем использование текущих итогов для регистра бухгалтерии Хозрасчетный
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Истина);
// Запускаем полный пересчет итогов регистра
РегистрыБухгалтерии.Хозрасчетный.ПересчитатьИтоги();
На крупных базах полный пересчет всех итогов с момента начала ведения учета может парализовать работу пользователей на часы. Чтобы избежать этого, мы можем пересчитывать итоги порционно — только за те периоды, которые подверглись изменениям. Рассмотрим пример пересчета за конкретный месяц:
// Определяем границы периода для актуализации данных
НачалоПериода = НачалоМесяца(ТекущаяДата());
КонецПериода = КонецМесяца(ТекущаяДата());
// Пересчитываем итоги за выбранный интервал времени
РегистрыБухгалтерии.Хозрасчетный.ПересчитатьИтогиЗаПериод(НачалоПериода, КонецПериода);
Иногда при попытке включить или пересчитать итоги стандартными средствами 1С система выдает неустранимую ошибку СУБД. Например: Cannot insert duplicate key row in object 'dbo._AccRgAT...' with unique index.... Это происходит из-за появления логического мусора в SQL-таблицах остатков. Стандартное «Тестирование и исправление» (ТиИ) в режиме 1С:Предприятие в таких случаях часто оказывается бессильным.
Проанализируем, как решить эту задачу на уровне базы данных (на примере MS SQL Server):
_AccRgAT (например, _AccRgAT123). Точное имя таблицы для вашей конфигурации можно узнать с помощью функции платформы ПолучитьСтруктуруХраненияБазыДанных()._AccRgED) и не пострадают. Выполним SQL-запрос:
TRUNCATE TABLE dbo._AccRgAT123;
Чтобы минимизировать риски внезапного отключения итогов, рекомендуем придерживаться следующих правил: