Почему дублируются границы последовательности в 1С и как это исправить

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

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

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

Как устроена таблица границ последовательности на уровне СУБД

Чтобы понять природу проблемы, заглянем «под капот» платформы «1С:Предприятие 8». Для каждой последовательности, созданной в конфигураторе, СУБД резервирует две основные физические таблицы:

  1. Таблица регистрации документов (обычно имеет имя вида _Seq<n>) — в ней хранятся ссылки на документы, которые должны быть выстроены в хронологическом порядке, а также состояние их проведения.
  2. Таблица границ последовательности (имеет имя вида _SeqB<n>) — именно здесь записывается точка актуальности (граница), до которой документы гарантированно проведены правильно. Граница состоит из полей периода (дата) и ссылки на документ-регистратор.

Если в свойствах последовательности в конфигураторе не заданы Измерения (например, «Организация» или «Склад»), то с точки зрения логики СУБД в таблице границ должна существовать ровно одна строка. Эта строка определяет общую точку актуальности для всей информационной базы.

Но что делать, если запрос к виртуальной таблице Последовательность.ПартионныйУчет.Границы внезапно возвращает сотни строк с разными документами и датами? Давайте выясним основные причины этой аномалии.

Причина 1. Скрытые или технические измерения в типовых конфигурациях

Очень часто разработчики полагают, что у последовательности партионного учета нет измерений, поскольку они не видят их в пользовательском интерфейсе. Однако в конфигурациях старого поколения (таких как «Управление производственным предприятием 1.3» или «Комплексная автоматизация 1.1») у последовательностей могут присутствовать служебные измерения. Например, булево измерение ПроведенВХронологическойПоследовательности.

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


// Неправильный вызов метода без учета структуры измерений
Последовательности.ПартионныйУчет.УстановитьГраницу(МоментВремени);

Если в структуре метаданных измерение существует, а в метод УстановитьГраницу() вторым параметром не передана структура отбора с конкретным значением этого измерения, платформа не может обновить существующую строку. Вместо операции обновления существующей записи (UPDATE) СУБД выполняет операцию вставки новой строки (INSERT) с дефолтными или пустыми значениями незаданных измерений. Повторение таких вызовов лавинообразно увеличивает количество строк в таблице _SeqB<n>.

Причина 2. «Осиротевшие» записи после изменения метаданных в конфигураторе

Представим ситуацию: в процессе кастомизации базы разработчик удалил ранее существовавшее измерение последовательности (например, «Организация»), решив сделать последовательность общей.

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

Причина 3. Механизмы разделения данных (облачные технологии)

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

Почему восстановление последовательности начинает «зависать»

Когда вы запускаете стандартную процедуру восстановления последовательности:

Последовательности.ПартионныйУчет.Восстановить(МоментВремени);

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

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

Как безопасно решить проблему: пошаговое руководство

Прибегать к прямому удалению записей в СУБД с помощью команды DELETE FROM sequencebound крайне не рекомендуется. Это нарушает целостность кэша платформы и может привести к непредсказуемым ошибкам в транзакциях. Рассмотрим штатные и безопасные способы лечения базы данных.

Способ 1. Полная очистка и перерегистрация последовательности (Рекомендуемый)

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

Рассмотрим по шагам, как это сделать программно в режиме «1С:Предприятие»:


// Шаг 1. Полностью очищаем таблицы последовательности партионного учета
Последовательности.ПартионныйУчет.Очистить();

// Шаг 2. Программно заполняем таблицу регистрации заново нужными документами
// Например, выберем все проведенные документы поступления и реализации за период
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	РеализацияТоваровУслуг.Ссылка КАК Ссылка,
    |	РеализацияТоваровУслуг.Дата КАК Дата
    |ИЗ
    |	Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
    |ГДЕ
    |	РеализацияТоваровУслуг.Проведен = ИСТИНА";

РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    // Записываем документ в последовательность без перепроведения
    Последовательности.ПартионныйУчет.Зарегистрировать(ВыборкаДетальныеЗаписи.Ссылка);
КонецЦикла;

Этот метод гарантирует, что таблица границ _SeqB<n> полностью очистится, и после первой же регистрации или ручной установки границы в ней появится ровно одна корректная строка.

Способ 2. Использование утилиты «Тестирование и исправление»

Если вы не хотите писать программный код, можно принудительно заставить платформу реструктуризировать таблицы и удалить «осиротевшие» строки. Для этого:

  1. Запустите информационную базу в режиме Конфигуратора.
  2. Предварительно обязательно создайте резервную копию базы данных!
  3. Перейдите в меню Администрирование -> Тестирование и исправление...
  4. Установите флажки напротив следующих пунктов:
    • Реиндексация таблиц информационной базы
    • Проверка логической целостности
    • Сжатие таблиц информационной базы
  5. Нажмите кнопку Выполнить.

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

Способ 3. Программный «схлоп» через установку пустых границ

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


// Создаем структуру отбора со старым (или пустым) разрезом измерения
Отбор = Новый Структура;
Отбор.Вставить("Организация", Справочники.Организации.ПустаяСсылка());

// Определяем пустой момент времени (начало времен)
ПустойМомент = Новый МоментВремени('00010101', Документы.РеализацияТоваровУслуг.ПустаяСсылка());

// Принудительно перезаписываем «мусорную» границу в базе данных
Последовательности.ПартионныйУчет.УстановитьГраницу(ПустойМомент, Отбор);

Этот код перезапишет проблемную строку. СУБД перестанет спотыкаться об нее при попытке рассчитать актуальное состояние последовательности документов.

Заключение

Размножение границ последовательностей в 1С — неочевидная техническая проблема, способная парализовать расчет себестоимости на крупных предприятиях. Понимание принципов работы таблиц СУБД _SeqB<n> позволяет быстро диагностировать эту ошибку с помощью обычного консольного запроса. Помните, что регулярное проведение профилактических работ, таких как тестирование и исправление базы данных, а также аккуратное использование метода УстановитьГраницу() с указанием явной структуры измерений уберегут вашу систему от непредвиденных сбоев.

← На главную