Как в 1С найти документы, которых нет в регистре сведений через запрос

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

В процессе разработки и сопровождения систем на базе 1С часто возникает задача контроля данных. Одной из типичных ситуаций является поиск объектов (например, документов), для которых еще не созданы записи в определенных регистрах сведений — будь то регистр пломбировки, статусов или дополнительных реквизитов. В данной статье мы подробно разберем, как правильно составить такой запрос, проанализируем типичные ошибки и рассмотрим способы оптимизации производительности при работе с большими объемами данных.

Разбор базового решения через левое соединение

Рассмотрим ситуацию, когда нам необходимо найти все документы ПриходнаяНакладная, информация о которых отсутствует в регистре сведений ПломбировкаДокументов. Основным механизмом для решения подобных задач в языке запросов 1С является ЛЕВОЕ СОЕДИНЕНИЕ в сочетании с проверкой на пустое значение (NULL).

Проанализируем структуру правильного запроса. Мы берем за основу таблицу документов и пытаемся "подклеить" к ней таблицу регистра по ссылке на документ. Если записи в регистре нет, поле из таблицы регистра примет значение NULL.

Рассмотрим пример кода:


ВЫБРАТЬ
    ПриходнаяНакладная.Ссылка КАК Ссылка
ИЗ
    Документ.ПриходнаяНакладная КАК ПриходнаяНакладная
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПломбировкаДокументов КАК ПломбировкаДокументов
        ПО ПриходнаяНакладная.Ссылка = ПломбировкаДокументов.Документ
ГДЕ
    ПломбировкаДокументов.Документ ЕСТЬ NULL

Важный нюанс: Обратите внимание на условие связи в секции ПО. Типичной ошибкой начинающих разработчиков является обращение к реквизиту через точку, например: ПриходнаяНакладная.Ссылка = ПломбировкаДокументов.Документ.Ссылка. Это приводит к лишнему соединению с таблицей документа через поле регистра, что замедляет запрос и может привести к некорректной работе условия ЕСТЬ NULL. Всегда сравнивайте ссылку документа напрямую с измерением регистра ПломбировкаДокументов.Документ.

Оптимизация выборки и фильтрация данных

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

  1. Состояние проведения: Как правило, отсутствие записи в регистре критично только для проведенных документов. Поэтому добавим условие ПриходнаяНакладная.Проведен = ИСТИНА.
  2. Пометка удаления: Документы, помеченные на удаление, обычно не требуют пломбировки или иных действий. Исключим их с помощью ПриходнаяНакладная.ПометкаУдаления = ЛОЖЬ.
  3. Период: Ограничение выборки по дате (например, за текущий месяц) существенно снизит нагрузку на СУБД.

Обновленный запрос будет выглядеть так:


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

Альтернативный подход через оператор «НЕ В»

Существует еще один способ решения задачи — использование конструкции ГДЕ Ссылка НЕ В (...) с вложенным запросом. Рассмотрим его реализацию:


ВЫБРАТЬ
    ПриходнаяНакладная.Ссылка
ИЗ
    Документ.ПриходнаяНакладная КАК ПриходнаяНакладная
ГДЕ
    ПриходнаяНакладная.Ссылка НЕ В (
        ВЫБРАТЬ
            Рег.Документ
        ИЗ
            РегистрСведений.ПломбировкаДокументов КАК Рег
    )

Проанализируем ситуацию: Данный вариант кода часто кажется более читаемым. Однако стоит помнить, что на больших таблицах (сотни тысяч и миллионы записей) классическое ЛЕВОЕ СОЕДИНЕНИЕ обычно работает эффективнее. Платформа 1С и СУБД (MS SQL, PostgreSQL) лучше оптимизируют планы запросов с соединениями, чем с вложенными подзапросами в условии ИН.

Работа с периодическими регистрами сведений

Если наш регистр ПломбировкаДокументов является периодическим, то простая связь с физической таблицей регистра может вернуть неверный результат. Например, если документ был когда-то опломбирован, затем распломбирован (создана новая запись), в физической таблице все равно останется старая запись, и LEFT JOIN не определит, что на текущий момент документ "свободен".

В этом случае нам необходимо соединяться с виртуальной таблицей СрезПоследних:


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

Повышение производительности: индексирование и временные таблицы

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

  1. Индексация полей: Поле Документ в регистре сведений обязательно должно быть индексируемым. Если это Измерение, оно индексируется автоматически. Если же это Реквизит, убедитесь, что в конфигураторе для него включено свойство «Индексировать». Без индекса СУБД будет вынуждена сканировать весь регистр при каждом запросе (Full Scan).
  2. Использование временных таблиц: Если нам нужно сопоставить данные по сложным условиям, хорошей практикой считается сначала отобрать нужные ссылки на документы во временную таблицу (например, ВТ_ДокументыДляПроверки), а затем соединять её с регистром. Это позволяет оптимизатору запросов СУБД построить более точный и быстрый план выполнения.

Проблема «битых» ссылок

Иногда в базе данных возникают ситуации, когда в регистре сведений ссылка на документ есть, но самого документа уже не существует (так называемые "битые ссылки" или "Объект не найден"). В этом случае условие ЕСТЬ NULL может сработать неожиданно. Для обеспечения чистоты данных мы рекомендуем периодически выполнять проверку на наличие пустых ссылок и корректность типов данных, используя конструкцию ЗНАЧЕНИЕ(Документ.ИмяДокумента.ПустаяСсылка).

Подведем итог: использование ЛЕВОГО СОЕДИНЕНИЯ с проверкой на NULL — это стандарт индустрии 1С для поиска отсутствующих данных. Применяя к этому методу фильтрацию по состоянию документа, индексирование и временные таблицы, вы получите надежный и производительный инструмент для контроля данных в вашей системе.

← На главную