Как физически удалить запись из границ последовательности в 1С 8

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Разбор архитектуры последовательностей в 1С

Для начала проанализируем, как объект Последовательность устроен внутри платформы. Физически в базе данных под одну последовательность выделяется не одна, а минимум две таблицы:

  1. Основная таблица регистраций: В ней хранятся записи о документах, которые «входят» в эту последовательность. Когда мы делаем запрос к Последовательность.ПартионныйУчетБУ, мы обращаемся именно к ней.
  2. Таблица границ (виртуальная таблица границ): Здесь хранится актуальный момент времени, до которого последовательность считается восстановленной (в разрезе измерений, если они есть). К ней обращаются через Последовательность.ПартионныйУчетБУ.Границы.

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

Почему метод УстановитьГраницу не удаляет запись?

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


МоментВремениДокумента = Новый МоментВремени('00010101000000');
Отбор = Новый Структура("Организация", ВыбОрганизация);
Последовательности.ПартионныйУчетБУ.УстановитьГраницу(МоментВремениДокумента, Отбор);

При выполнении данного кода платформа выполняет операцию UPSERT (Update или Insert). Если записи для данной организации еще не было, она будет создана с пустой датой. Если она была — она будет обновлена. Но команда DELETE (удаление строки) в этот момент не вызывается. С точки зрения 1С, граница на 01.01.0001 — это просто «сброшенная» граница, но строка в таблице базы данных физически остается.

Способ 1. Использование прямого SQL-запроса (для клиент-серверных баз)

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

Проанализируем шаги, необходимые для выполнения этой операции:

  1. Определение имени таблицы: Таблицы границ в SQL обычно начинаются с префикса _SeqBnd. Чтобы узнать точное имя таблицы для последовательности ПартионныйУчетБУ, используем встроенную функцию:
    
    СтруктураТаблиц = ПолучитьСтруктуруХраненияБазыДанных();
    // Ищем в структуре таблицу, относящуюся к нашей последовательности
    
  2. Подготовка запроса: После того как имя таблицы (например, _SeqBnd123) определено, необходимо выполнить команду удаления. Внимание: всегда делайте бэкап перед прямым вмешательством в БД!
    
    DELETE FROM _SeqBnd123 WHERE _Fld456 = @P1 -- где _Fld456 - ID измерения (например, Организации)
    
  3. Очистка кэша: После удаления на уровне SQL платформа может некоторое время «видеть» старые данные из своего внутреннего кэша. Потребуется перезапуск сеанса или использование метода ОбновитьПовторноИспользуемыеЗначения().

Способ 2. Программный сброс основной таблицы

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


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

// 2. Устанавливаем границу в начало времен
ПустойМомент = Новый МоментВремени('00010101000000');
Последовательности.ПартионныйУчетБУ.УстановитьГраницу(ПустойМомент, Отбор);

Хотя это не удаляет строку физически, это приводит систему в логически чистое состояние, которое является штатным для 1С.

Способ 3. Административный метод (Конфигуратор)

Если задача стоит глобально — очистить все границы последовательности во всей базе — мы можем воспользоваться инструментами тестирования и исправления (ТиИ).

  1. Запустите информационную базу в режиме Конфигуратор.
  2. Перейдите в меню Администрирование — Тестирование и исправление....
  3. Выберите пункт «Очистка ссылок на несуществующие объекты». В некоторых случаях, если записи границ ссылаются на удаленные элементы справочников (битые ссылки), этот механизм позволит их вычистить.
  4. Если это не помогло, существует радикальный метод: временное исключение измерений из состава последовательности в дереве метаданных, сохранение конфигурации БД, а затем возврат их обратно. Это приведет к полной перегенерации таблиц _SeqBnd и их физической очистке. Однако помните, что это действие требует монопольного доступа и приведет к потере всех текущих границ для всех пользователей.

Выясним причины появления «лишних» границ

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

В этом случае эффективнее всего использовать SQL-метод, описанный выше, так как штатные средства УстановитьГраницу() могут выдавать ошибку при попытке передать в отбор «битую» ссылку.

Резюме

Мы выяснили, что в рамках встроенного языка 1С нет прямого метода для выполнения команды DELETE в таблице границ последовательности. Платформа предполагает, что граница — это константа состояния, которая может быть только изменена.

Для решения задачи мы рекомендуем:

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

← На главную