Как найти неиспользуемую номенклатуру в 1С 7.7 с помощью прямых SQL-запросов?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

В чем заключается ошибочность использования ROW_ID для определения даты создания

Рассмотрим логику, которую часто пытаются применить: получить максимальный идентификатор строки ROW_ID для номенклатуры, по которой были движения до определенной даты, а затем отобрать все позиции без движений, у которых значение ROW_ID меньше полученного числа. На первый взгляд кажется, что поле с автоинкрементом строго отражает хронологию добавления записей. Однако в архитектуре СУБД MS SQL под управлением 1С 7.7 это предположение ошибочно по следующим причинам:

  1. Пересоздание таблиц при выгрузке и загрузке данных. При выполнении стандартной административной процедуры «Выгрузка данных» / «Загрузка данных» через Конфигуратор база данных пересоздается. Все строки таблиц справочников физически перезаписываются заново, а счетчик IDENTITY сбрасывается и генерируется в новом порядке. В результате вся историческая хронология соответствия ROW_ID реальному моменту создания карточки полностью стирается.
  2. Специфика распределенных баз данных (УРБД). Если в информационной базе когда-либо использовался обмен, объекты, созданные в периферийном узле годами ранее, при загрузке в центральную базу получают новые системные значения ROW_ID.
  3. Пропуски и перескоки счетчика. При откатах транзакций, сбоях записи или программных ошибках инкремент поля ROW_ID увеличивается вхолостую, образуя разрывы.

Таким образом, колонка ROW_ID является исключительно внутренним физическим счетчиком таблицы СУБД и никак не гарантирует дату и время создания элемента в прикладном смысле.

Альтернатива: внутренний идентификатор ID в 1С 7.7

Проанализируем структуру первичного ключа справочников 1С 7.7. Внутренний идентификатор объекта хранится в поле ID (тип данных CHAR(9)):

  1. Первые 6 символов представляют собой порядковый номер объекта, закодированный платформой в 36-ричной системе счисления (символы 0–9 и A–Z).
  2. Последние 3 символа содержат код узла информационной базы (при использовании распределенных баз данных) или заполнены пробелами для локальной базы.

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

Как гарантированно определить дату заведения номенклатуры

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

  1. Анализ таблицы периодических реквизитов (_1SCONST). Если в конфигурации у справочника «Номенклатура» хотя бы один реквизит объявлен периодическим (например, базовая цена, ставка НДС, статус товара), то в момент первичной записи карточки платформа создает строку в таблице _1SCONST. Поле OBJID хранит идентификатор элемента, а поле DATE — дату фиксации значения. Выполнив группировку MIN(DATE) по идентификатору позиции, можно определить фактическую дату появления элемента в учете.
  2. Подчиненные справочники. При создании карточки товара конфигурации (например, «Торговля и склад 7.7») автоматически генерируют базовые единицы измерения или категории цен в подчиненных справочниках. Если там присутствуют периодические реквизиты, их минимальная дата также служит маркером времени заведения позиции.
  3. Журнал регистрации. События интерактивного добавления фиксируются в системном журнале. Однако при массовой программной загрузке записей в журнале может не оказаться.

Построение SQL-запроса для поиска неиспользуемой номенклатуры

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


SELECT 
    Спр.ID as [Номенклатура $Справочник.Номенклатура]
FROM 
    $Справочник.Номенклатура AS Спр
WHERE 
    Спр.IsFolder = 2
    AND Спр.IsMark = 0
    AND Спр.ID NOT IN (
        SELECT DISTINCT $Ост.Номенклатура 
        FROM $Регистр.ОстаткиТМЦ AS Ост
    )

Разберем логику условий:

  1. Спр.IsFolder = 2 — исключает из выборки группы справочника, отбирая только элементы.
  2. Спр.IsMark = 0 — отсекает элементы, которые уже помечены на удаление.
  3. Конструкция NOT IN (или NOT EXISTS) проверяет факт полного отсутствия идентификатора номенклатуры среди измерений таблицы движений регистра.

Контроль ссылочной целостности перед удалением

Проанализируем риски прямого удаления элементов из базы данных на уровне СУБД. Проверка только таблицы регистра накопления (например, ОстаткиТМЦ) является недостаточной:

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

Если принудительно удалить найденные позиции прямой SQL-командой DELETE, в табличных частях существующих документов останутся некорректные идентификаторы, что приведет к появлению строк с надписью «<Объект не найден>».

Безопасный порядок действий при очистке:

  1. Выполнить запрос на выборку неиспользуемых идентификаторов.
  2. В коде 1С выгрузить полученные ссылки и передать их в штатную функцию встроенного языка НайтиСсылки(). Метод проверит всю информационную базу (документы, константы, периодику, проводки) и зафиксирует, есть ли реальные ссылки на элемент.
  3. Позиции, на которые ссылки отсутствуют, можно безопасно пометить на удаление стандартным методом платформы Удалить(1) или перенести в специальную архивную группу справочника, исключив их из видимости пользователей при оперативном подборе.
← На главную