Как убрать «фантомные» записи с датами 2001 и 5999 года в таблицах итогов 1С:Предприятие

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

Администраторы баз данных и разработчики 1С при анализе таблиц на SQL-сервере (например, через SSMS) иногда сталкиваются с пугающей картиной: в таблицах итогов регистров накопления обнаруживаются миллионы записей с датами из далекого прошлого (2001 год) и далекого будущего (5999 год). При этом в базе данных включено стандартное смещение дат на 2000 лет. Подобные аномалии приводят к катастрофическому раздуванию таблиц СУБД, замедлению работы запросов и зависанию регламентных операций.

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

Физический смысл дат 2001 и 5999 в СУБД SQL Server

Для начала проанализируем, откуда берутся эти даты в таблицах СУБД при использовании смещения дат (+2000 лет):

Почему пустая дата порождает миллионы записей

Механизм расчета итогов регистров накопления остатков устроен так, что платформа хранит остатки помесячно. Если в регистр записывается движение с периодом 01.01.0001 (в SQL — 2001 год), система считает себя обязанной рассчитать и хранить остатки на конец каждого месяца, начиная с 1-го года нашей эры и до текущего момента (то есть за 2000 лет!).

Даже если физический баланс по этим записям в итоге сворачивается в ноль, в таблице итогов _AccumRgT генерируются тысячи «пустых» (нулевых) записей для каждого месяца за последние два тысячелетия. Ситуация усугубляется механизмом разделения итогов (Splitter): для исключения транзакционных блокировок платформа плодит дубли строк с разными значениями разделителя (поле _DimHash или _Splitter). В результате таблица итогов разрастается до гигантских размеров, перегружая память и дисковую подсистему СУБД.

Выясняем причину: уязвимость в типовом коде

Рассмотрим, как пустая дата может незаметно попасть в регистр. Типичным примером является регистр РасчетыСПоставщиками в конфигурациях на базе ERP / КА / УТ. Проанализируем фрагмент запроса формирования движений:


|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|    КОНЕЦПЕРИОДА(&ДатаПлатежа, День)                          КАК Период,
|    &Период                                                   КАК ДатаРегистратора,
|    &ДатаПлатежа                                              КАК ДатаПлатежа,
...

Если в документе-регистраторе (например, в документе Корректировка поступления или Корректировка долга) реквизит ДатаПлатежа оказался незаполненным, то функция КОНЕЦПЕРИОДА(&ДатаПлатежа, День) вернет пустую дату 01.01.0001. Платформа запишет движение в регистр накопления именно этой пустой датой.

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

Шаг 1. Локализация документов-виновников

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


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

Если запрос вернул документы-регистраторы, их необходимо обработать:

  1. Заполнить в них корректную дату платежа (или дату самого документа).
  2. Перепровести исправленные документы. Если период закрыт для редактирования, движения можно скорректировать программно (например, через внешнюю обработку, временно отключив проверку даты запрета изменения для администратора).

Шаг 2. Безопасная очистка и пересчет таблиц итогов

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

Способ 1. Отключение и включение итогов (Рекомендуемый в 1С)

Самый простой и безопасный способ очистить физическую таблицу итогов в СУБД без использования сторонних SQL-скриптов — это временное отключение итогов для конкретного регистра. Пройдем по шагам этот процесс:

  1. Запустите базу данных в режиме «1С:Предприятие» от имени администратора.
  2. Перейдите в меню «Функции для технического специалиста» (или «Все функции») и откройте стандартную обработку «Управление итогами».
  3. Найдите в списке проблемный регистр (например, РегистрНакопления.РасчетыСПоставщиками).
  4. Снимите флаг «Использовать итоги» для этого регистра и примените изменения. В этот момент платформа 1С отправляет к СУБД быструю команду очистки таблицы (фактически выполняется TRUNCATE или DROP для таблицы _AccumRgT). Миллионы фантомных записей мгновенно удаляются.
  5. Установите флаг «Использовать итоги» обратно.
  6. Нажмите кнопку «Полный пересчет итогов» (или выполните его из Конфигуратора). Поскольку таблица итогов теперь абсолютно пуста, система быстро рассчитает новые итоги только на основании корректных, существующих движений (в которых пустых дат больше нет).

Способ 2. Очистка через SQL (Для очень больших баз данных)

Если база данных настолько огромна, что даже стандартные интерфейсы 1С работают со сбоями, администратор БД может очистить таблицу напрямую в SQL Server Management Studio (SSMS).

Важно: Все операции напрямую в СУБД должны выполняться строго на резервной копии базы данных и при отсутствии активных пользователей!

  1. Выясните имя SQL-таблицы итогов для вашего регистра. Это можно сделать с помощью функции платформы ПолучитьСтруктуруХраненияБазыДанных(). Допустим, имя таблицы итогов — _AccumRgT12345.
  2. В SSMS выполните команду быстрой очистки таблицы: TRUNCATE TABLE _AccumRgT12345;
  3. Запустите Конфигуратор 1С в монопольном режиме.
  4. Откройте меню «Администрирование» — «Тестирование и исправление».
  5. Установите единственную галочку «Пересчет итогов» и запустите процесс выполнения. Поскольку SQL-таблица итогов была полностью очищена, пересчет пройдет максимально быстро и корректно.

Предотвращение проблемы в будущем

Чтобы исключить повторное появление подобных инцидентов, выполните профилактические настройки:

  1. Настройте дату запрета изменения данных. Установите дату запрета редактирования хотя бы на уровне 01.01.2000 для всех пользователей, включая администраторов. Это не позволит случайно записать или провести старые документы «нулевым» годом.
  2. Обновите конфигурацию. В современных релизах типовых конфигураций 1С логика заполнения дат платежей была переработана, а проверки на пустые значения перед проведением стали более строгими.

Мы успешно локализовали проблему, очистили базу данных от лишнего информационного мусора и обеспечили стабильную, быструю работу механизмов расчета итогов!

← На главную