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

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

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

Использование функции ТИПЗНАЧЕНИЯ в условиях отбора

Самый распространенный и интуитивно понятный способ — применение встроенной функции ТИПЗНАЧЕНИЯ() (или TYPE() в английской версии). Эта функция возвращает строковое представление типа объекта, что позволяет использовать её в секции ГДЕ или ИМЕЮЩИЕ. Синтаксис предельно прост: вы передаете поле ссылки в качестве аргумента и сравниваете результат с именем типа.

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

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

ВЫБРАТЬ

Движения.Период,

Движения.Ссылка,

Движения.Сумма

ИЗ

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

ГДЕ

ТИПЗНАЧЕНИЯ(Движения.Ссылка) = "ДокументСсылка.РеализацияТоваровУслуг"

Такой подход удобен своей наглядностью, однако имеет один существенный недостаток. Использование функции в условии ГДЕ может помешать оптимизатору запросов использовать индексы по полям типа таблицы ссылок. В небольших базах это незаметно, но при миллионах записей время выполнения может возрасти в разы. Всегда проверяйте план выполнения запроса при использовании подобных конструкций.

💡

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

Работа с таблицами значений типов ссылок

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

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

Пример реализации через соединение с таблицей типов:

ВЫБРАТЬ

Продажи.Период,

Продажи.Ссылка

ИЗ

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

ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТипыЗначенийСсылок КАК ТипыСсылок

ПО ТИПЗНАЧЕНИЯ(Продажи.Ссылка) = ТипыСсылок.Ссылка

ГДЕ

ТипыСсылок.Наименование = "ДокументСсылка.ЗаказКлиента"

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

📊 Какой метод определения типа вы используете чаще?
ТИПЗНАЧЕНИЯ() в условии ГДЕ
Соединение с ТипыЗначенийСсылок
Определение типа в коде 1С
Не определяю тип вообще

Функция ЕСТЬТИП для проверки существования типа

Функция ЕСТЬТИП() (или ISTYPE()) служит для проверки принадлежности значения к определенному типу и возвращает булево значение (ИСТИНА или ЛОЖЬ). В отличие от ТИПЗНАЧЕНИЯ, она не возвращает имя типа, а сразу дает ответ на вопрос "является ли этот объект данным типом?". Это делает код более читаемым в сложных логических условиях.

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

Пример использования в запросе:

ВЫБРАТЬ

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

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

ИЗ

Документ.ВсеДокументы КАК Документы

ГДЕ

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

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

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

⚠️ Внимание: Функция ЕСТЬТИП может возвращать ЛОЖЬ, если в поле ссылки хранится неопределенное значение (NULL). Всегда учитывайте возможность пустых ссылок при построении логики отбора.

Определение типа через таблицу ссылочных типов (СсылочныеТипы)

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

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

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

Поле Описание Тип данных
Ссылка Уникальный идентификатор типа ТипЗначенияСсылки
Наименование Полное имя типа (например, ДокументСсылка.Заказ) Строка
Родитель Ссылка на родительский тип (для иерархии) ТипЗначенияСсылки
ЭтоСоставнойТип Признак составного типа Булево

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

Нюансы работы с составными типами

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

Особенности работы с составными типами ссылок

В конфигурациях 1С часто встречаются поля, имеющие составной тип. Это означает, что в одном поле могут храниться ссылки на объекты совершенно разных видов, например, на документ и на справочник. Работа с такими полями требует особого внимания, так как стандартные сравнения могут вести себя непредсказуемо.

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

Список типичных проблем при работе с составными типами:

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

Для решения этих проблем рекомендуется заранее разделять потоки данных. Можно использовать оператор ВЫБРАТЬ ... ОБЪЕДИНИТЬ ВСЕ ..., где каждая часть запроса будет строго типизирована. Это позволит оптимизатору построить более эффективный план выполнения и избежать лишних проверок типов вruntime.

⚠️ Внимание: При работе с составными типами избегайте использования оператора ТОЧКА (.) для доступа к реквизитам прямо в запросе, если тип не гарантирован. Лучше выгрузить ссылку и получить реквизиты через дополнительное соединение или в коде.

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

Производительность запросов, использующих определение типа, напрямую зависит от объема обрабатываемых данных и способа фильтрации. Как упоминалось ранее, вызов функций в условии ГДЕ может отключать использование индексов. Чтобы минимизировать потери скорости, следует придерживаться ряда правил при написании кода.

Во-первых, старайтесь сужать выборку до применения функций типа. Сначала отфильтруйте данные по периоду, организации или другим индексным полям, и только потом применяйте ТИПЗНАЧЕНИЯ или ЕСТЬТИП. Это уменьшит количество строк, для которых потребуется вычисление типа, что существенно ускорит работу.

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

☑️ Чек-лист оптимизации запроса

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

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

💡

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

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

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

Например, указание просто "ЗаказКлиента" вместо "ДокументСсылка.ЗаказКлиента" приведет к тому, что условие всегда будет ложным. Также важно помнить о регистре символов: имена типов чувствительны к регистру в некоторых контекстах, хотя платформа часто пытается привести их автоматически, полагаться на это не стоит.

Еще одна ошибка — попытка определить тип для значения NULL. Функции типа обычно возвращают НЕОПРЕДЕЛЕНО или ЛОЖЬ в таких случаях, что может нарушить логику отбора, если это не обработано явно. Всегда добавляйте проверку на заполненность ссылки перед проверкой её типа, если это критично для бизнес-логики.

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

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

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

Откройте метаданные в конфигураторе, найдите нужный объект и посмотрите его полное имя. Либо выполните простой запрос "ВЫБРАТЬ ТИПЗНАЧЕНИЯ(Ссылка) ИЗ ...", чтобы увидеть реальные значения в базе.

Практические примеры использования в отчетах

Рассмотрим реальную задачу: необходимо построить отчет по всем документам, влияющим на взаиморасчеты, независимо от их вида. В базе могут быть "Поступления", "Реализации", "Корректировки" и "Оплаты". Использование жесткого перечисления типов в коде сделает отчет негибким.

Решением будет использование таблицы ТипыЗначенийСсылок в сочетании с регистром взаиморасчетов. Мы соединяем движения регистра с таблицей типов и отбираем только те, которые относятся к группе документов. Это позволяет отчету автоматически подхватывать новые виды документов, если они добавлены в конфигурацию и имеют аналогичную структуру.

Пример кода для такого универсального отчета:

ВЫБРАТЬ

Взаиморасчеты.Период,

Взаиморасчеты.Ссылка КАК Документ,

ТипыСсылок.Наименование КАК ТипДокумента,

Взаиморасчеты.СуммаВзаиморасчетов

ИЗ

РегистрНакопления.Взаиморасчеты.Движения КАК Взаиморасчеты

ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТипыЗначенийСсылок КАК ТипыСсылок

ПО ТИПЗНАЧЕНИЯ(Взаиморасчеты.Ссылка) = ТипыСсылок.Ссылка

ГДЕ

ТипыСсылок.Наименование ПОДОБНО "ДокументСсылка.%"

Такой подход обеспечивает масштабируемость решения. Если завтра бухгалтерия решит ввести новый документ "Акт сверки", отчет сразу начнет его отображать без вмешательства программиста. Это пример того, как правильное использование инструментов платформы упрощает сопровождение системы.

Можно ли использовать ТИПЗНАЧЕНИЯ в условии ИМЕЮЩИЕ?

Да, функцию ТИПЗНАЧЕНИЯ() можно использовать в секции ИМЕЮЩИЕ для фильтрации результатов группировки. Это полезно, когда нужно отобрать группы, содержащие документы определенного типа. Однако помните, что фильтрация в ИМЕЮЩИЕ происходит после группировки, что может быть менее производительно, чем отбор в ГДЕ.

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

В коде 1С на стороне клиента или сервера используйте метод ТипЗначения() объекта ссылки или функцию ТипЗначенияСтрока(). Также можно использовать конструкцию Тип(...) для создания типа и оператор ... для проверки. В запросе же эти методы недоступны, только встроенные функции языка запросов.

Влияет ли использование ЕСТЬТИП на использование индексов?

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

Что вернет ТИПЗНАЧЕНИЯ для пустой ссылки?

Для пустой ссылки (NULL) функция ТИПЗНАЧЕНИЯ() вернет специальное значение НЕОПРЕДЕЛЕНО (Undefined). При сравнении со строкой это условие не выполнится. Чтобы корректно обрабатывать пустые ссылки, добавьте явную проверку И НЕ ЕСТЬПУСТО(Ссылка) в условие отбора.

Есть ли разница между ДокументСсылка и ДокументОбъект в типах?

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