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

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

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

Использование функции ЕСТЬ для проверки типа

Самым универсальным и надежным способом проверки типа объекта в языке запросов является встроенная функция ЕСТЬ. Она позволяет определить, является ли значение в указанном поле ссылкой на объект конкретного типа, возвращая логическое значение ИСТИНА или ЛОЖЬ.

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

Обратите внимание, что функция ЕСТЬ работает эффективно даже на больших объемах данных, так как оптимизатор запросов 1С умеет преобразовывать такие условия в эффективные планы выполнения. Однако стоит помнить, что перечисление слишком большого количества типов может усложнить чтение кода.

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

ВЫБРАТЬ

РегистрНакопления.Продажи.Документ,

РегистрНакопления.Продажи.Сумма

ИЗ

РегистрНакопления.Продажи КАК Продажи

ГДЕ

ЕСТЬ(Продажи.Документ, ДокументСсылка.РеализацияТоваровУслуг)

ИЛИ ЕСТЬ(Продажи.Документ, ДокументСсылка.СчетФактураВыданный)

Использование функции ЕСТЬ гарантирует, что в выборку попадут только те записи, где тип ссылки строго соответствует указанному. Это защищает код от ошибок приведения типов, которые могут возникнуть при других методах сравнения.

⚠️ Внимание: Функция ЕСТЬ возвращает ИСТИНА только если тип совпадает точно. Она не учитывает наследование типов в контексте общих ссылок так, как это делает оператор ИСТИНА при явном приведении.
💡

Если вы проверяете тип в условии соединения таблиц (JOIN), использование функции ЕСТЬ может значительно ускорить выполнение запроса по сравнению с преобразованием типов.

Сравнение через псевдореквизит Вид ссылки

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

Сравнение типа документа через Ссылка.Вид позволяет писать более читаемый код, особенно когда нужно проверить принадлежность к целой группе документов или использовать предопределенные значения. Значение реквизита Вид представляет собой строковое представление типа или специальный объект описания типов.

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

Пример использования данного метода для фильтрации по виду документа:

ВЫБРАТЬ

Документ.Ссылка,

Документ.Дата

ИЗ

Документ.ПоступлениеТоваровУслуг КАК Поступление

ГДЕ

Поступление.Ссылка.Вид = ЗНАЧЕНИЕ(Тип("ДокументСсылка.ПоступлениеТоваровУслуг"))

В данном случае мы используем конструкцию ЗНАЧЕНИЕ(Тип(...)) для получения эталонного значения типа, что является более безопасным подходом, чем прямое сравнение со строкой. Это обеспечивает независимость кода от языковых настроек интерфейса.

  • 📌 Использование Ссылка.Вид удобно при динамическом формировании условий.
  • 📌 Метод чувствителен к изменениям метаданных конфигурации.
  • 📌 Требует явного указания полного имени типа для надежности.
📊 Какой метод проверки типа вы используете чаще?
Функция ЕСТЬ
Реквизит Вид
Преобразование в строку
Другой способ

Преобразование типов и оператор ИСТИНА

Третий распространенный подход заключается в явном приведении типа поля к требуемому типу документа с использованием оператора КАК и последующей проверкой на ИСТИНА. Этот метод часто применяется в старых версиях кода или в специфических сценариях работы с составными типами.

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

Код с использованием такого подхода может выглядеть следующим образом:

ВЫБРАТЬ

Регистр.Измерение1

ИЗ

РегистрСведений.ЦеныНоменклатуры КАК Регистр

ГДЕ

(Регистр.Измерение1 КАК ДокументСсылка.ЗаказКлиента) ИСТИНА

Здесь мы явно указываем, что рассматриваем поле Измерение1 в контексте типа ДокументСсылка.ЗаказКлиента. Если фактический тип значения соответствует указанному, выражение вернет истину. В противном случае будет возвращено ЛОЖЬ или NULL.

Важно отметить, что использование оператора КАК в условиях ГДЕ может влиять на производительность запроса, так как требует дополнительной обработки данных на уровне СУБД. Рекомендуется использовать этот метод только тогда, когда другие варианты неприменимы.

⚠️ Внимание: При использовании преобразования типов убедитесь, что поле действительно может содержать указанный тип. Попытка приведения несовместимых типов может привести к ошибкам выполнения запроса.
Особенности работы с NULL

Если в поле хранится значение NULL, то любое сравнение типа, включая функцию ЕСТЬ и оператор ИСТИНА, вернет ЛОЖЬ. Не забывайте обрабатывать пустые значения отдельно, если это критично для логики отчета.

Работа с составными типами в регистрах

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

Часто возникает задача отобрать документы определенного вида, исключив при этом справочники или другие документы. Для этого удобно комбинировать функцию ЕСТЬ с логическими операторами И и ИЛИ, строя сложные условия фильтрации.

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

Значение в поле ЕСТЬ(..., Документ) Ссылка.Вид = Документ (Поле КАК Документ) ИСТИНА
Ссылка на "Заказ" ИСТИНА ИСТИНА ИСТИНА
Ссылка на "Номенклатура" ЛОЖЬ ЛОЖЬ ЛОЖЬ
NULL (Пустая ссылка) ЛОЖЬ ЛОЖЬ ЛОЖЬ
Число или Строка ЛОЖЬ Ошибка/ЛОЖЬ ЛОЖЬ

Как видно из таблицы, все три метода дают схожий результат для корректных ссылок, но могут по-разному вести себя при наличии некорректных данных или пустых значений. Выбор конкретного метода зависит от требований к надежности и производительности.

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

💡

Для полей составного типа функция ЕСТЬ является наиболее производительным и безопасным способом фильтрации, так как она не требует неявного приведения типов.

Оптимизация производительности запросов

Вопрос производительности при фильтрации по типу документа стоит особенно остро в высоконагруженных системах. Неправильно написанное условие может привести к полному сканированию таблицы (Full Table Scan), что критически замедляет работу программы.

Использование индексов играет ключевую роль. Платформа автоматически создает индексы для полей, используемых в условиях соединения и фильтрации, но только если условие записано в "понятном" для оптимизатора виде. Функция ЕСТЬ обычно хорошо индексируется.

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

  • 🚀 Используйте ЕСТЬ для максимальной скорости выборки.
  • 🚀 Избегайте обертывания полей в функции преобразования типов.
  • 🚀 Проверяйте план выполнения запроса через консоль запросов.

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

⚠️ Внимание: В распределенных информационных базах (РИБ) условия сравнения типов должны быть совместимы с обеими узлами. Убедитесь, что конфигурации синхронизированы и типы документов имеют одинаковые идентификаторы.

☑️ Оптимизация запроса по типу

Выполнено: 0 / 4

Частые ошибки и способы их устранения

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

Например, запись вида ГДЕ ТипЗнч(Поле) = "ДокументСсылка.Заказ" является ошибочной в языке запросов, так как функция ТипЗнч недоступна непосредственно в тексте запроса. Для таких случаев необходимо использовать встроенные средства языка запросов, описанные выше.

Еще одна ошибка — игнорирование регистронезависимости строковых сравнений при использовании реквизита Вид. Если вы сравниваете вид документа со строковой константой, убедитесь, что регистр символов совпадает с ожидаемым в базе данных, или используйте операторы нечувствительные к регистру.

Для отладки таких ситуаций полезно выводить тип значения в отдельное поле выборки, чтобы визуально оценить, что именно приходит из базы. Это можно сделать, добавив в список выборки выражение ТИП(Поле), если версия платформы поддерживает данную функцию в контексте SELECT.

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

⚠️ Внимание: Интерфейс и возможности языка запросов могут обновляться. Рекомендуется сверять синтаксис функций в официальной документации к вашей версии платформы перед внедрением в промышленную эксплуатацию.
Секрет быстрой отладки

Используйте консоль запросов в режиме отладки. Она позволяет пошагово выполнять части запроса и видеть промежуточные наборы данных, что помогает выявить, на каком этапе отсеиваются нужные документы.

Можно ли сравнить тип документа в условии соединения (JOIN)?

Да, это возможно и часто необходимо. Вы можете использовать функцию ЕСТЬ непосредственно в условии соединения таблиц. Например: ЛЕВОЕ СОЕДИНИЕ ... НА ЕСТЬ(Таблица2.Поле, ДокументСсылка.Тип) И .... Это позволяет соединять таблицы только по записям определенного типа.

Что вернет запрос, если в поле составного типа хранится не документ?

Если вы используете функцию ЕСТЬ с указанием типа документа, а в поле находится справочник или число, функция вернет ЛОЖЬ, и запись не попадет в выборку (при условии, что это фильтр). Ошибки выполнения не возникнет.

Как проверить, что поле содержит ЛЮБОЙ документ, а не конкретный вид?

Для этого можно использовать функцию ЕСТЬ без уточнения конкретного вида, если синтаксис позволяет, либо перечислить все возможные виды документов через оператор ИЛИ. Альтернативно, можно проверить, что Ссылка.Вид начинается с префикса "ДокументСсылка".

Влияет ли смена синонима документа на работу запроса с ЕСТЬ?

Нет, функция ЕСТЬ использует внутреннее имя типа метаданных, а не синоним. Поэтому переименование документа в конфигураторе не сломает запрос, использующий полное имя типа ДокументСсылка.ИмяОбъекта.

Есть ли разница в скорости между ЕСТЬ и сравнением Вида?

В большинстве случаев функция ЕСТЬ работает быстрее, так как она оптимизирована на уровне движка запросов для проверки типов. Сравнение реквизита Вид может требовать дополнительного обращения к системным таблицам метаданных в зависимости от реализации.