Почему зависает оборотно-сальдовая ведомость по счету на этапе вывода 0% и как это исправить

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

В процессе работы с крупными базами данных «1С:Предприятие» пользователи и администраторы нередко сталкиваются с ситуацией, когда стандартный отчет Оборотно-сальдовая ведомость по счету наглухо зависает при попытке сформировать данные за определенный период. При этом в строке состояния отображается сообщение Вывод отчета 0%, в то время как другие отчеты (например, Карточка счета, Анализ счета или Шахматка) могут отрабатывать штатно. Ситуация осложняется, если информационная база имеет значительный объем (более 100–150 Гб), и запуск полного тестирования и исправления (ТиИ) грозит простоем системы на несколько суток.

Разберем детально, почему возникает такая ошибка, как она связана с ошибочно проведенными документами в далеком будущем, структурой субконто и механизмами СУБД, а также рассмотрим пошаговые методы быстрого решения проблемы.

Выясняем причину зависания на этапе компоновки данных

Проанализируем техническую сторону формирования отчета. Сообщение Вывод отчета 0% указывает на то, что сам запрос СКД к виртуальным таблицам базы данных уже выполнился, однако система остановилась на этапе генерации макета и вывода результата. Выделим основные факторы, приводящие к такому поведению:

  1. Документы с датами в далеком будущем (например, 2201 год). Это одна из самых коварных ошибок пользователей. При проведении документа будущей датой платформа 1С автоматически сдвигает границу рассчитанных итогов регистра бухгалтерии на сотни лет вперед. В результате СУБД генерирует пустые помесячные срезы итогов. При построении виртуальной таблицы остатков и оборотов за текущий период платформа пытается восстановить остатки от ближайшей точки рассчитанных итогов, что порождает чтение огромного массива служебных записей.
  2. Группировки по субконто в СКД. Если без субконто отчет формируется быстро, а при добавлении хотя бы одного субконто зависает, генератор СКД не может сопоставить поля представлений или натыкается на декартово произведение. Такое происходит при нарушении ссылочной целостности (битые ссылки вида Объект не найден в проводках) или значениях Неопределено в реквизитах составного типа.
  3. Неоптимальные планы запросов SQL (Parameter Sniffing). Сервер MS SQL Server кэширует планы выполнения параметризованных запросов sp_executesql. Если первый план был оптимизирован под пустой или селективный счет, а затем запрос выполняется по счету с миллионами проводок, оптимизатор СУБД выбирает неэффективные алгоритмы соединения таблиц (например, Nested Loops вместо Hash Match).
  4. Устаревшая статистика СУБД. В больших базах таблицы движений регистра бухгалтерии и таблицы итогов меняются непрерывно. При отсутствии регулярного обновления статистики оптимизатор SQL строит заведомо ошибочные планы чтения.

Способ 1. Устранение документов будущих периодов и сдвиг границы итогов

Рассмотрим первоочередные действия, если в информационной базе обнаружен проведенный документ с некорректной датой (например, 2201 годом). Важно помнить: простая отмена проведения документа или исправление его даты не возвращает назад границу рассчитанных итогов и не удаляет лишние записи из физических таблиц СУБД.

Разберем по шагам, как корректно восстановить работу регистра:

  1. Найдем и распроведем все ошибочные документы будущих периодов. Исправим их дату на актуальную.
  2. Вернем границу рассчитанных итогов регистра бухгалтерии назад с помощью вызова штатного метода через внешнюю обработку или консоль кода:

ИмяРегистра = "Типовой"; // Укажите имя регистра бухгалтерии вашей конфигурации
НоваяГраница = КонецМесяца(ТекущаяДата());

РегистрыБухгалтерии[ИмяРегистра].УстановитьПериодРассчитанныхИтогов(НоваяГраница);

Данная операция удалит раздутые срезы итогов за будущие века и вернет штатную производительность виртуальных таблиц без необходимости многочасового полного пересчета всей базы.

Способ 2. Точечный пересчет итогов по конкретному регистру

Когда база данных занимает сотни гигабайт, выполнять общее тестирование и исправление нецелесообразно. Рассмотрим, как пересчитать итоги исключительно по проблемному регистру бухгалтерии за определенный период:


НачалоИнтервала = '20170101000000';
КонецИнтервала  = '20171231235959';

РегистрыБухгалтерии.Типовой.ПересчитатьИтоги(НачалоИнтервала, КонецИнтервала);

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

Способ 3. Проверка субконто на битые ссылки

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


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

Если запрос выявит строки со значениями «Объект не найден» или некорректными типами данных, не соответствующими ПланСчетов, такие записи необходимо перезаписать корректными ссылками либо очистить.

Способ 4. Обслуживание MS SQL Server: очистка процедурного кэша и обновление статистики

Если данные проверены, а отчет продолжает зависать, необходимо устранить возможное залипание неоптимального плана выполнения запроса на стороне СУБД. Разберем регламентные действия администратора баз данных:

  1. Обновление статистики: выполним процедуру sp_updatestats для текущей базы данных или настроим план обслуживания с полным пересчетом статистики (FULLSCAN) по таблицам _AccRg* (таблицы регистра бухгалтерии).
  2. Сброс кэша планов: для принудительного перестроения планов запросов по конкретной информационной базе выполним SQL-инструкцию:

DECLARE @DatabaseID INT = DB_ID();
DBCC FLUSHPROCINDB(@DatabaseID);

Это заставит сервер СУБД сгенерировать новые, оптимальные планы для виртуальных таблиц СКД при следующем открытии отчета ОСВ.

Применяя указанный комплекс мер, мы устраняем причину зависания ОСВ без длительной остановки рабочих процессов и многодневного ожидания полного ТиИ.

← На главную