При разработке отчетов или обработок на платформе 1С часто возникает необходимость передать в запрос ТаблицаЗначений, содержащую ссылки на справочники. Одной из типичных проблем является невозможность «дотянуться» через точку к реквизитам этой ссылки (например, Номенклатура.Родитель). Давайте разберемся, почему это происходит и как правильно организовать работу с такими данными.
Когда мы передаем ТаблицаЗначений в запрос в качестве параметра, платформа 1С не сохраняет полноценную структуру метаданных для колонок этой таблицы в самом языке запросов. Для системы это выглядит как набор данных с недостаточно определенным типом. Несмотря на то, что мы типизируем колонку при создании таблицы через ОписаниеТипов, внутри запроса транслятор не всегда «понимает», что в этой колонке лежит объект, обладающий конкретными реквизитами.
Попытка обратиться к полю тбОстатки.Номенклатура.Родитель напрямую приводит к ошибке, так как запрос не видит структуры справочника Номенклатура у переданного параметра.
Одним из самых быстрых способов заставить систему «увидеть» реквизиты объекта является явное приведение типа. Для этого используется ключевое слово ВЫРАЗИТЬ. Оно прямо указывает интерпретатору запроса, что поле должно рассматриваться как конкретный ссылочный тип.
Рассмотрим, как это выглядит в коде:
ВЫБРАТЬ
ВЫРАЗИТЬ(тбОстатки.Номенклатура КАК Справочник.Номенклатура).Родитель КАК Группа,
тбОстатки.Номенклатура,
тбОстатки.СреднийОстаток
ИЗ
&тбОстатки КАК тбОстатки
Использование ВЫРАЗИТЬ позволяет движку запроса «подтянуть» описание метаданных, после чего обращение через точку становится легальным и ошибка пропадает.
Более профессиональным и производительным подходом считается разделение операций. Вместо того чтобы пытаться вытащить данные «на лету», лучше сначала загрузить ТаблицаЗначений во временную таблицу, а затем соединить её с основной таблицей базы данных.
Давайте посмотрим, как это реализовать:
// Шаг 1: Помещаем данные во временную таблицу
Запрос.Текст =
"ВЫБРАТЬ
| тбОстатки.Номенклатура,
| тбОстатки.СреднийОстаток
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ
| &тбОстатки КАК тбОстатки
|;
|// Шаг 2: Выполняем выборку с соединением
|ВЫБРАТЬ
| Спр.Родитель КАК Группа,
| ВТ.Номенклатура,
| ВТ.СреднийОстаток
|ИЗ
| ВТ_Данные КАК ВТ
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Спр
| ПО ВТ.Номенклатура = Спр.Ссылка";
Почему это лучший вариант?
Такой подход считается наиболее стабильным. Первый этап — это простая передача данных в память сервера. Второй этап — это полноценная работа с таблицами БД, где система точно знает структуру каждого справочника. Это позволяет избежать проблем с потерей типов и делает код более читаемым и легким для отладки.
Если вы столкнулись с ошибкой доступа к реквизитам объекта в запросе при работе с ТаблицаЗначений, помните:
ВЫРАЗИТЬ.Теперь вы можете уверенно строить любые выборки, даже если исходные данные приходят из внешней таблицы, созданной программно.