При работе с регистрами накопления‚ бухгалтерии или при объединении данных из разных таблиц‚ часто возникает необходимость отфильтровать или обработать записи‚ относящиеся к конкретному виду документа (типу метаданных). В языке запросов 1С:Предприятие 8 для этого используются две ключевые функции: ТИПЗНАЧЕНИЯ и ТИП.
В этой статье подробно разберем синтаксис‚ нюансы использования‚ типичные ошибки и приведем практические примеры для решения реальных задач.
Теоретические основы Функция ТИПЗНАЧЕНИЯ(<Поле>)
Возвращает описание типа значения‚ содержащегося в поле запроса. Аналог встроенного языка — функция ТипЗнч.
- Арменту может быть любое поле выборки: ссылка на документ‚ регистратор‚ реквизит составного типа.
- Результат — значение системного перечисления
Тип(например‚ДокументСсылка.РеализацияТоваровУслуг).
Функция ТИП(<ИмяТипа>)
Возвращает описание типа по его строковому имени в формате метаданных. Используется для сравнения с результатом ТИПЗНАЧЕНИЯ.
- Синтаксис:
ТИП(Документ.ИмяДокумента)‚ТИП(Справочник.ИмяСправочника)‚ТИП(Перечисление.ИмяПеречисления)и т.д. - Важно: Имя типа указывается без кавычек и с точным соответствием регистру и имени метаданных в конфигурации.
Базовый синтаксис проверки
Классическая конструкция для отбора по типу документа в секции ГДЕ или внутри ВЫБОР:
ГДЕ ТИПЗНАЧЕНИЯ(Регистратор) = ТИП(Документ.РеализацияТоваровУслуг)
Или с использованием оператора В для проверки на вхождение в список типов:
ГДЕ ТИПЗНАЧЕНИЯ(Регистратор) В (ТИП(Документ.ПоступлениеТоваровУслуг)‚ ТИП(Документ.ПоступлениеДопРасходов))
Практические примеры Пример 1. Отбор движений регистра по конкретному документу
Задача: Получить остатки или обороты только по документам «Реализация товаров и услуг».
ВЫБРАТЬ
ХозрасчетныйОборотыДтКт.СчетДт‚
ХозрасчетныйОборотыДтКт.СчетКт‚
ХозрасчетныйОборотыДтКт.СуммаОборот‚
ХозрасчетныйОборотыДтКт.Регистратор
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(&НачалоПериода‚ &КонецПериода‚ Регистратор‚ ‚ ‚ ‚ ‚ ) КАК ХозрасчетныйОборотыДтКт
ГДЕ
ТИПЗНАЧЕНИЯ(ХозрасчетныйОборотыДтКт.Регистратор) = ТИП(Документ.РеализацияТоваровУслуг)
Пример 2. Условная логика в полях выборки (ВЫБОР КОГДА)
Задача: В отчете по взаиморасчетам применить скидку 10%‚ если контрагентом является сотрудник (документ основания — «Возврат товаров от покупателя» с типом контрагента «Сотрудники»)‚ иначе — полная сумма.
ВЫБРАТЬ
Реализация.Ссылка КАК Ссылка‚
Реализация.Контрагент КАК Контрагент‚
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(Реализация.Контрагент) = ТИП(Справочник.Сотрудники)
ТОГДА Реализация.СуммаДокумента * 0.9
ИНАЧЕ Реализация.СуммаДокумента
КОНЕЦ КАК СуммаСоСкидкой
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
Пример 3. Проверка типа регистратора в регистре накопления
Частая задача при анализе «левых» записей или при настройке обмена данными — отсечь документы неверного типа.
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Номенклатура‚
ТоварыНаСкладахОстатки.Склад‚
ТоварыНаСкладахОстатки.КоличествоОстаток‚
ТоварыНаСкладахОстатки.Регистратор
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&МоментВремени‚ ) КАК ТоварыНаСкладахОстатки
ГДЕ
ТИПЗНАЧЕНИЯ(ТоварыНаСкладахОстатки.Регистратор) = ТИП(Документ.ПеремещениеТоваров)
Программная проверка на сервере (Встроенный язык)
Иногда проверку типа удобнее или необходимо выполнить в модуле объекта/менеджера‚ а не в тексте запроса. Для этого используется пара функций: ТипЗнч и Тип.
&НаСервере
Процедура ПроверитьТипДокументаПрограммно(СсылкаНаДокумент)
// Проверка‚ что переданная ссылка указывает на документ "СадкаВПечь" (пример имени)
Если ТипЗнч(СсылкаНаДокумент) = Тип("ДокументСсылка.СадкаВПечь") Тогда
Сообщить("Это документ 'Садка в печь'");
ИначеЕсли ТипЗнч(СсылкаНаДокумент) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
Сообщить("Это реализация");
Иначе
Сообщить("Это другой тип документа: " + Строка(ТипЗнч(СсылкаНаДокумент)));
КонецЕсли;
КонецПроцедуры
Важное отличие: В запросах используется ТИП(Документ.Имя)‚ а во встроенном языке — Тип("ДокументСсылка.Имя") (строка с полным именем типа значения).
Работа с ССЫЛКА и ВЫРАЗИТЬ КАК
Иногда для корректного определения типа или сравнения ссылок требуется привести поле к явному типу с помощью ВЫРАЗИТЬ(... КАК ...) или использовать функцию ССЫЛКА.
Функция ССЫЛКА(Документ.Имя‚ ПолеИД)
Позволяет создать ссылку на конкретный документ по его ID (UUID) для сравнения в запросе.
ВЫБРАТЬ
Товары.Номенклатура
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка = ССЫЛКА(Документ.РеализацияТоваровУслуг‚ &IDДокумента)
Приведение составного типа (ВЫРАЗИТЬ КАК)
Если поле имеет составной тип (например‚ Регистратор может быть Документом или Справочником)‚ для доступа к реквизитам конкретного типа используется приведение:
ВЫБРАТЬ
ВЫРАЗИТЬ(Регистратор КАК Документ.РеализацияТоваровУслуг).Номер КАК НомерРеал
ИЗ
РегистрНакопления.Продажи.Остатки КАК Остатки
ГДЕ
ТИПЗНАЧЕНИЯ(Регистратор) = ТИП(Документ.РеализацияТоваровУслуг)
Типичные ошибки и лучшие практики - Ошибка в имени типа. В функции
ТИП имя метаданных должно совпадать точно (регистр‚ отсутствие пробелов в техническом имени). Проверяйте в дереве конфигурации (Свойства -> Имя). - Сравнение со строкой. Нельзя писать:
ТИПЗНАЧЕНИЯ(Поле) = "Документ.Реализация". Только ТИП(Документ.Реализация). - Производительность. Использование
ТИПЗНАЧЕНИЯ в секции ГДЕ на больших таблицах может замедлить запрос‚ так как СУБД не может использовать индексы эффективно. - Совет: Если возможно‚ используйте виртуальные таблицы с параметром отбора по регистратору (например‚
Остатки(Момент‚ Регистратор = &Ссылка)) или предварительно отфильтруйте нужные документы во временной таблице.
- Проверка на NULL. Если поле может быть не заполнено‚
ТИПЗНАЧЕНИЯ(NULL) вернет NULL. Учитывайте это в условиях: ГДЕ ТИПЗНАЧЕНИЯ(Поле) = ТИП(Документ.Тип) ИЛИ Поле ЕСТЬ NULL. - Использование ВЫБОР вместо ГДЕ. Если нужно не отобрать‚ а разделить логику (например‚ разные формулы для разных типов)‚ используйте
ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(...) = ТИП(...) ТОГДА ... в секции ВЫБРАТЬ.
Сводная таблица функций
ТИП имя метаданных должно совпадать точно (регистр‚ отсутствие пробелов в техническом имени). Проверяйте в дереве конфигурации (Свойства -> Имя).ТИПЗНАЧЕНИЯ(Поле) = "Документ.Реализация". Только ТИП(Документ.Реализация).ТИПЗНАЧЕНИЯ в секции ГДЕ на больших таблицах может замедлить запрос‚ так как СУБД не может использовать индексы эффективно. - Совет: Если возможно‚ используйте виртуальные таблицы с параметром отбора по регистратору (например‚
Остатки(Момент‚ Регистратор = &Ссылка)) или предварительно отфильтруйте нужные документы во временной таблице.
ТИПЗНАЧЕНИЯ(NULL) вернет NULL. Учитывайте это в условиях: ГДЕ ТИПЗНАЧЕНИЯ(Поле) = ТИП(Документ.Тип) ИЛИ Поле ЕСТЬ NULL.ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(...) = ТИП(...) ТОГДА ... в секции ВЫБРАТЬ.| Среда выполнения | Функция определения типа значения | Функция получения типа по имени | Пример типа для сравнения |
|---|---|---|---|
| Язык запросов (SQL-подобный) | ТИПЗНАЧЕНИЯ(Поле) | ТИП(Документ.Имя) | ТИП(Документ.РеализацияТоваровУслуг) |
| Встроенный язык (1С:Script) | ТипЗнч(Переменная) | Тип("ДокументСсылка.Имя") | Тип("ДокументСсылка.РеализацияТоваровУслуг") |
Проверка типа документа в запросе 1С — базовый навык для разработки отчетов‚ обработок данных и механизмов обмена. Главное правило: используйте пару ТИПЗНАЧЕНИЯ и ТИП в запросах‚ и пару ТипЗнч и Тип во встроенном языке. Следите за точностью имен метаданных и помните о производительности при работе с большими объемами данных — при необходимости выносите отбор по типу на уровень виртуальных таблиц или временных таблиц.
Надеемся‚ приведенные примеры помогут вам быстро решить вашу задачу по типизации данных в запросах 1С:Предприятие 8.3.