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

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

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

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

Способ 1. Простой запрос с использованием левого соединения

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

Рассмотрим пример запроса, который вернет нам все проведенные заказы, для которых в базе не найдено ни одной реализации:


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

Разберем, как это работает. При левом соединении система берет каждую запись из таблицы ЗаказПокупателя. Если для этого заказа находится хотя бы одна РеализацияТоваровУслуг, в колонках второй таблицы появляются данные этой реализации. Если же реализации нет, во всех колонках таблицы реализации будет стоять значение NULL. Условие ЕСТЬ NULL в секции ГДЕ позволяет нам отфильтровать именно те заказы, для которых «пара» не нашлась.

Способ 2. Оптимизация запроса с использованием временных таблиц

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

Рассмотрим оптимизированный вариант:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    РеализацияТоваровУслуг.Сделка КАК Сделка
ПОМЕСТИТЬ ВТ_ЕстьРеализации
ИЗ
    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ГДЕ
    РеализацияТоваровУслуг.Сделка ССЫЛКА Документ.ЗаказПокупателя;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЗаказПокупателя.Ссылка
ИЗ
    Документ.ЗаказПокупателя КАК ЗаказПокупателя
ЛЕВОЕ СОЕДИНЕНИЕ 
    ВТ_ЕстьРеализации КАК ВТ_ЕстьРеализации
ПО 
    ЗаказПокупателя.Ссылка = ВТ_ЕстьРеализации.Сделка
ГДЕ
    ЗаказПокупателя.Проведен = ИСТИНА
    И ВТ_ЕстьРеализации.Сделка ЕСТЬ NULL

Использование ВЫБРАТЬ РАЗЛИЧНЫЕ позволяет сократить объем временной таблицы, если на один заказ вводится несколько реализаций. Это существенно снижает нагрузку на дисковую подсистему и память сервера.

Способ 3. Работа с составными типами данных и типизация

Часто реквизит связи (например, Сделка или ДокументОснование) имеет составной тип данных. Это означает, что в поле может храниться ссылка на ЗаказПокупателя, Счет на оплату или даже на другой документ. В этом случае крайне важно использовать функцию ВЫРАЗИТЬ.

Если не типизировать поле в запросе, платформа 1С при обращении к базе данных SQL сформирует соединение со всеми таблицами, входящими в этот тип. Это может привести к значительному падению производительности. Проанализируем правильное использование типизации:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Реализация.Сделка КАК Документ.ЗаказПокупателя) КАК Заказ
ПОМЕСТИТЬ ВТ_ЗаказыСРеализацией
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
    Реализация.Сделка ССЫЛКА Документ.ЗаказПокупателя;

Важный момент: индексирование полей во временных таблицах также играет ключевую роль. Если вы планируете использовать временную таблицу для дальнейших соединений в большом пакете запросов, добавьте ИНДЕКСИРОВАТЬ ПО. Хотя для разовой выборки из 100 строк это не критично, профессиональный подход требует написания кода, готового к масштабированию.

Способ 4. Использование объекта «Критерии отбора»

В типовых конфигурациях (например, УТ 10.3, ERP, КА) существует стандартный механизм для отслеживания связей — Критерии отбора. Обычно такой объект называется СвязанныеДокументы.

Если мы заглянем в конфигуратор, то увидим, что критерий отбора — это фактически предопределенный индекс всех ссылок в системе на конкретный объект. Вы можете использовать критерий отбора в запросе к виртуальной таблице. Это может быть быстрее, чем сканирование отдельных таблиц документов, так как платформа уже «знает», какие документы на что ссылаются.

Способ 5. Программный поиск ссылок через НайтиПоСсылкам

Если задача стоит не в массовом получении списка, а в точечной проверке конкретных документов (например, перед удалением или закрытием периода), можно воспользоваться методом встроенного языка НайтиПоСсылкам().

Проанализируем пример кода:


МассивЗаказов = Новый Массив;
МассивЗаказов.Добавить(СсылкаНаЗаказ);

ТаблицаСсылок = НайтиПоСсылкам(МассивЗаказов);
Если ТаблицаСсылок.Количество() = 0 Тогда
    Сообщить("Связанных документов не найдено");
КонецЕсли;

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

Рекомендации и выводы

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

  1. Для разовых задач и небольших баз используйте ЛЕВОЕ СОЕДИНЕНИЕ с условием ЕСТЬ NULL. Это быстро и наглядно.
  2. Для высоконагруженных систем всегда используйте временные таблицы и типизацию через ВЫРАЗИТЬ, если поле связи составное.
  3. Не забывайте про индексы. Поля, по которым происходит соединение (например, Сделка), должны быть проиндексированы в метаданных документа.
  4. Учитывайте статус документа. Если вы ищете заказы без реализаций, обязательно добавляйте фильтры Проведен = ИСТИНА и ПометкаУдаления = ЛОЖЬ как для заказов, так и для реализаций, чтобы избежать учета «мусорных» данных.

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

← На главную