Как отобрать документы с незаполненными дополнительными реквизитами в запросе 1С и СКД?

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

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

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

---

Почему не работает простой запрос к табличной части?

Дополнительные реквизиты в 1С хранятся в подчиненных табличных частях объектов (обычно табличная часть называется ДополнительныеРеквизиты). Каждая строка этой таблицы содержит ссылку на свойство (план видов характеристик ДополнительныеРеквизитыИСведения) и его значение.

Если пользователь заполнил дополнительный реквизит в документе, в табличной части появляется соответствующая строка. Но если реквизит не заполнен, то в базе данных строки с этим свойством для данного документа просто не существует. Именно поэтому простая попытка написать запрос с условием вида ГДЕ ДополнительныеРеквизиты.Значение = Неопределено или ГДЕ ДополнительныеРеквизиты.Значение ЕСТЬ NULL без предварительного соединения таблиц вернет пустой результат или отбросит документы, у которых табличная часть пуста.

Рассмотрим правильные подходы к решению этой задачи.

---

Решение №1: Левое соединение с правильным условием связи

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

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

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


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

Разберем по шагам, как работает этот запрос:

  1. Мы выбираем все документы из таблицы Документ.РеализацияТоваровУслуг.
  2. Присоединяем к ним табличную часть ДополнительныеРеквизиты только для того свойства, которое передано в параметре &СвойствоОплата (например, наш дополнительный реквизит «Оплачена»).
  3. Если у документа данное свойство не заполнено, то в колонках присоединенной таблицы ДопРеквизиты (включая поля Свойство и Значение) вернется системное значение NULL.
  4. В секции ГДЕ мы накладываем условие ДопРеквизиты.Значение ЕСТЬ NULL. Это позволяет нам отсечь все документы, для которых строка с нужным свойством была найдена (то есть реквизит заполнен), и оставить только те, где этой строки нет.

---

Решение №2: Использование механизма исключения (ВТ и условие НЕ В)

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

Рассмотрим этот пример реализации:


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Реализация.Ссылка КАК Ссылка,
    Реализация.Номер КАК Номер,
    Реализация.Дата КАК Дата
ИЗ
    Документ.RealizaciaТоваровУслуг КАК Реализация
ГДЕ
    НЕ Реализация.Ссылка В (ВЫБРАТЬ ВТ.Ссылка ИЗ ВТ_ЗаполненныеДокументы КАК ВТ)

Этот способ интуитивно понятен и отлично подходит для простых выборок в обработках или при переносе данных.

---

Решение №3: Использование механизма «Характеристики» в СКД

Если задача решается в рамках отчета на Системе компоновки данных (СКД), то ручное прописывание левых соединений в тексте запроса — не самый лучший вариант. Платформа 1С предлагает встроенный инструмент под названием Характеристики.

Рассмотрим, как настроить характеристики в СКД, чтобы они определялись автоматически:

  1. Откроем конструктор схемы компоновки данных и перейдем на вкладку Характеристики (в верхней части окна настройки набора данных).
  2. Добавим новую строку и укажем правила получения характеристик:
    • Путь к данным: выбираем поле, для которого настраиваются характеристики (например, Ссылка нашего документа).
    • Источник видов характеристик: таблица, откуда система будет брать список доступных реквизитов (например, справочник НаборыДополнительныхРеквизитовИСведений или запрос к ПВХ ДополнительныеРеквизитыИСведения).
    • Источник значений характеристик: табличная часть дополнительных реквизитов документа (Документ.РеализацияТоваровУслуг.ДополнительныеРеквизиты).
  3. После такой настройки все дополнительные реквизиты документа автоматически появятся в дереве доступных полей СКД в виде подчиненных полей (например, Ссылка.Оплачена [Дополнительный реквизит]).

В чем преимущество такого подхода? Вам больше не нужно писать сложные запросы с проверками на NULL. Пользователь отчета сможет в пользовательских настройках просто перетащить поле реквизита в отбор и выбрать условие "Не заполнено". СКД самостоятельно сгенерирует наиболее оптимальный SQL-запрос под капотом СУБД, учитывая пустые значения и системные неопределенности.

Если нужно построить сложный отбор (например, выбрать незаполненные значения или значения со статусом «Частично»), СКД сформирует условие по следующему шаблону:


ГДЕ
    (ДопРеквизиты.Значение В (НЕОПРЕДЕЛЕНО, &ПустоеЗначение, &ПустаяДата, 0)
    ИЛИ ДопРеквизиты.Значение ЕСТЬ NULL)

---

Почему в СКД пропадает поле «Контрагент»?

В процессе разработки отчетов в СКД программисты иногда сталкиваются со странным поведением системы: поле Контрагент присутствует в запросе, успешно выводится в консоли запросов, но при формировании отчета на СКД в режиме предприятия колонка с контрагентом просто исчезает или отображается пустой.

Выясним причину этой проблемы. Все дело в механизме Функциональных опций (ФО) платформы «1С:Предприятие».

В типовых конфигурациях (например, в УТ 11 или ERP) ведение учета в разрезе партнеров и контрагентов регулируется соответствующими константами и функциональными опциями (например, функциональная опция «ИспользоватьПартнеровИКонтрагентов»). Если эта опция отключена в настройках системы, то платформа на уровне ядра автоматически скрывает связанные поля из интерфейса и отчетов СКД, даже если они жестко прописаны в вашем запросе.

Для решения этой проблемы есть два пути:

  1. Включить функциональную опцию в режиме предприятия: Перейдите в настройки системы (НСИ и администрирование -> Настройка разделов) и установите флаг ведения учета по партнерам/контрагентам. После этого поля сразу станут доступны в отчете.
  2. Отключить проверку функциональной опции для поля в СКД (если это необходимо): В схеме компоновки данных на вкладке «Наборы данных» найдите нужное поле и проверьте свойства функциональных опций. Однако помните, что обход бизнес-логики типовой конфигурации может привести к некорректному заполнению данных пользователями.

---

Может ли проведенный документ быть помечен на удаление?

В запросах начинающих разработчиков часто можно встретить конструкцию вида:


И Реализация.Проведен = ИСТИНА
И Реализация.ПометкаУдаления = ЛОЖЬ

На первый взгляд, проверка ПометкаУдаления = ЛОЖЬ является избыточной, так как в обычном режиме работы платформы невозможно пометить документ на удаление без отмены его проведения. Сама система при попытке удаления предложит сначала распровести документ.

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


ДокументОбъект.ОбменДанными.Загрузка = Истина;
ДокументОбъект.ПометкаУдаления = Истина;
ДокументОбъект.Записать();

В этом случае платформа запишет документ в базу данных «как есть» — с установленной пометкой удаления, но с сохраненным признаком Проведен = ИСТИНА (и даже с существующими движениями по регистрам). Поэтому совместное использование этих условий в критически важных аналитических отчетах оправданно и защищает от ошибок "грязного" чтения данных из СУБД.

---

Подведем итоги

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

← На главную