Определение типа регистратора в запросах 1С:Предприятие 8

Узнайте секреты работы со составным типом Регистратор в 1С 8.3. Простые примеры запросов для быстрой идентификации документов в регистрах накопления.

Бесплатная консультация юриста

+7 (800) 302-87-29

Реклама jurik.ru

Работа с регистрами накопления и бухгалтерии в 1С:Предприятие 8 часто требует анализа поля Регистратор․ Поскольку это поле имеет составной тип (может ссылаться на различные документы), программисту необходимо уметь определять конкретный тип документа-регистратора прямо в тексте запроса․ В этой статье подробно разбираются все актуальные способы решения этой задачи․

Теоретические основы

Поле Регистратор в регистрах накопления представляет собой ссылку на объект метаданных типа Документ․ В отличие от измерений, которые могут ссылаться на справочники, регистратор всегда документ․ Однако в одном регистре регистраторами могут выступать несколько разных видов документов (например, РеализацияТоваровУслуг, ПоступлениеТоваровУслуг, СписаниеТоваров и т․д․)․

Язык запросов 1С предоставляет специальные операторы для работы с составными типами данных:

  • ТИПЗНАЧЕНИЯ(Поле) — возвращает строковое представление типа значения (например, ДокументСсылка․РеализацияТоваровУслуг)․
  • ТИП(Метаданные) — получает описание типа по объекту метаданных (например, ТИП(Документ․РеализацияТоваровУслуг))․
  • ВЫБОР КОГДА ․․․ ТОГДА ․․․ ИНАЧЕ ․․․ КОНЕЦ — конструкция для условной логики (аналог CASE/IF)․
  • ВЫРАЗИТЬ(Поле КАК Тип) — приведение поля составного типа к конкретному типу для доступа к реквизитам конкретного документа․
  • ССЫЛКА, оператор проверки типа в условии ГДЕ (доступен в новых версиях платформы)․

Основные способы определения типа регистратора

Использование функции ТИПЗНАЧЕНИЯ в секции ВЫБРАТЬ

Самый прямой способ — вывести тип регистратора в результат запроса для анализа или группировки․

ВЫБРАТЬ
 Взаиморасчеты․Регистратор КАК Регистратор,
 ТИПЗНАЧЕНИЯ(Взаиморасчеты․Регистратор) КАК ТипРегистратора,
 Взаиморасчеты․СуммаОборот
ИЗ
 РегистрНакопления․ВзаиморасчетыСКонтрагентами КАК Взаиморасчеты

Результат: В поле ТипРегистратора вернется строка вида ДокументСсылка․РеализацияТоваровУслуг․

Фильтрация по типу в секции ГДЕ (Оператор В)

Для отбора записей только определенных типов документов удобно использовать оператор В со списком типов, полученных через функцию ТИП․

ВЫБРАТЬ
 ТоварныеЗапасы․Регистратор,
 ТоварныеЗапасы․Номенклатура,
 ТоварныеЗапасы․КоличествоОборот
ИЗ
 РегистрНакопления․ТоварныеЗапасы КАК ТоварныеЗапасы
ГДЕ
 ТИПЗНАЧЕНИЯ(ТоварныеЗапасы․Регистратор) В 
 (ТИП(Документ․ПоступлениеТоваровУслуг), 
 ТИП(Документ․ПеремещениеТоваров))

Важно: В параметрах запроса можно передать массив типов (Массив), заполненный через Метаданные․Документы․ИмяДокумента․

Оператор ССЫЛКА (Современный синтаксис)

Начиная с платформы 8․3․18+ (проверяйте актуальность для своей версии), в секции ГДЕ можно использовать более читаемую конструкцию ССЫЛКА․

ГДЕ
 ТоварныеЗапасы․Регистратор ССЫЛКА Документ․РасходТовара
 // Или для списка:
 // ТоварныеЗапасы․Регистратор ССЫЛКА Документ․РасходТовара, Документ․СписаниеТоваров

Конструкция ВЫБОР для получения читаемого имени типа

Чтобы получить не техническое имя типа (ДокументСсылка․․․․), а понятное название (например, «Реализация», «Поступление»), используют ВЫБОР․

ВЫБРАТЬ
 Продажи․Регистратор КАК Регистратор,
 ВЫБОР
 КОГДА ТИПЗНАЧЕНИЯ(Продажи․Регистратор) = ТИП(Документ․ОтгрузкаТоваров)
 ТОГДА "Накладная (Отгрузка)"
 КОГДА ТИПЗНАЧЕНИЯ(Продажи․Регистратор) = ТИП(Документ․РеализацияТоваровУслуг)
 ТОГДА "Реализация (Услуги)"
 ИНАЧЕ "Прочий документ"
 КОНЕЦ КАК ВидДокумента
ИЗ
 РегистрНакопления․Продажи КАК Продажи

Работа с реквизитами конкретного документа-регистратора

Часто требуется не просто узнать тип, а получить доступ к реквизитам или табличным частям конкретного документа (например, Номер, Дата, Контрагент или строки ТЧ)․

Разыменование через точку (неявное приведение)

Если в запросе обратиться к реквизиту, который есть не во всех документах-регистраторах, платформа вернет NULL для несоответствующих типов․

ВЫБРАТЬ
 Взаиморасчеты․Регистратор․Номер КАК НомерДок,
 Взаиморасчеты․Регистратор․Контрагент КАК Контрагент
 // Если у документа нет поля Контрагент, вернется NULL
ИЗ
 РегистрНакопления․ВзаиморасчетыСКонтрагентами КАК Взаиморасчеты

Явное приведение типа: ВЫРАЗИТЬ(․․․ КАК ․․․)

Это профессиональный подход, гарантирующий доступ к реквизитам конкретного вида документа и корректную работу оптимизатора запросов․

ВЫБРАТЬ
 ВЫРАЗИТЬ(Продажи․Регистратор КАК Документ․РеализацияТоваровУслуг)․Номер КАК НомерРеал,
 ВЫРАЗИТЬ(Продажи․Регистратор КАК Документ․РеализацияТоваровУслуг)․Контрагент КАК КонтрагентРеал
ИЗ
 РегистрНакопления․Продажи КАК Продажи
ГДЕ
 ТИПЗНАЧЕНИЯ(Продажи․Регистратор) = ТИП(Документ․РеализацияТоваровУслуг)

Получение реквизитов табличной части регистратора

Для доступа к табличной части нужно использовать соединение (СОЕДИНЕНИЕ) с табличной частью документа, предварительно приведя регистратор к нужному типу․

ВЫБРАТЬ
 Реал․Номенклатура,
 Реал․Количество,
 Продажи․Регистратор․Номер КАК НомерДок
ИЗ
 РегистрНакопления․Продажи КАК Продажи
 ЛЕВОЕ СОЕДИНЕНИЕ Документ․РеализацияТоваровУслуг․Товары КАК Реал
 ПО ВЫРАЗИТЬ(Продажи․Регистратор КАК Документ․РеализацияТоваровУслуг) = Реал․Ссылка
ГДЕ
 ТИПЗНАЧЕНИЯ(Продажи․Регистратор) = ТИП(Документ․РеализацияТоваровУслуг)

Передача типов через параметры запроса

Жесткое кодирование типов в тексте запроса (ТИП(Документ․Имя)) удобно, но негибко․ Лучше передавать список типов параметром․

Пример кода на встроенном языке:

Запрос = Новый Запрос;
Запрос․Текст = 
"ВЫБРАТЬ
 | Остатки․Регистратор,
 | Остатки․Номенклатура,
 | Остатки․КоличествоОстаток
 |ИЗ
 | РегистрНакопления․ТоварыНаСкладах․Остатки КАК Остатки
 |ГДЕ
 | ТИПЗНАЧЕНИЯ(Остатки․Регистратор) В (&МассивТиповРегистраторов)";
// Формируем массив типов
МассивТипов = Новый Массив;
МассивТипов․Добавить(Метаданные․Документы․ПоступлениеТоваровУслуг);
МассивТипов․Добавить(Метаданные․Документы․ПеремещениеТоваров);
// Можно добавить любой другой документ

Запрос․УстановитьПараметр("МассивТиповРегистраторов", МассивТипов);
Результат = Запрос․Выполнить;

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

  1. Индексы: Поле Регистратор индексируется автоматически․ Условия ТИПЗНАЧЕНИЯ(․․․) В (․․․) и ССЫЛКА эффективно используют индексы․
  2. Избегайте ВЫБОР в ГДЕ: Конструкция ГДЕ ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(․․․) = ТИП(․․․) ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ работает медленнее, чем нативный В или ССЫЛКА․
  3. Временные таблицы: Если запрос сложный и многократно фильтруется по типу регистратора, выгодно сначала отобрать нужные типы во временную таблицу (ПОМЕСТИТЬ ВТ_Отбор), а затем соединять с ней․
  4. Полнотекстовый поиск по типам: Не используйте СТРОКА(ТИПЗНАЧЕНИЯ(․․․)) ПОДОБНО "%Реализация%" — это полное сканирование таблицы․

Типичные ошибки и подводные камни

  • Сравнение со строкой: Нельзя писать ТИПЗНАЧЕНИЯ(Регистратор) = "ДокументСсылка․РеализацияТоваровУслуг"․ Сравнивать нужно только с результатом функции ТИП․
  • NULL в регистраторе: В регистрах накопления регистратор не может быть NULL (это обязательное системное поле)․ Проверка Регистратор ЕСТЬ NULL всегда вернет Ложь․
  • Доступ к реквизитам без приведения: Обращение Регистратор․СпецифичныйРеквизит для документа, у которого его нет, вернет NULL, но может сбить с толку при анализе данных․ Всегда используйте ВЫРАЗИТЬ внутри ВЫБОР или после проверки типа․
  • Регистратор vs Записатель: Поле Записатель (в регистрах бухгалтерии) может иметь тип ДокументСсылка или БизнесПроцессСсылка и т․д․ Логика определения типа идентична․

Сводная таблица конструкций

Задача Рекомендуемая конструкция Примечание
Вывести тип в результат ТИПЗНАЧЕНИЯ(Регистратор) Возвращает строку метаданных
Отбор по одному типу в ГДЕ ТИПЗНАЧЕНИЯ(Рег) = ТИП(Док․Имя) или Рег ССЫЛКА Док․Имя ССЫЛКА более читаем (платформа 8․3․18+)
Отбор по списку типов ТИПЗНАЧЕНИЯ(Рег) В (&МассивТипов) Параметр — Массив из Метаданные․Документы․Имя
Получить имя вида документа (строка) ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(Рег)=ТИП(Док․Имя) ТОГДА "Имя" КОНЕЦ Для отчетов пользователю
Доступ к реквизиту конкретного док․ ВЫРАЗИТЬ(Рег КАК Док․Имя)․Реквизит Обязательно после проверки типа в ГДЕ
Соединение с ТЧ документа ЛЕВОЕ СОЕДИНЕНИЕ Док․Имя․ТЧ КАК ТЧ ПО ВЫРАЗИТЬ(Рег КАК Док․Имя) = ТЧ․Ссылка Только для документов нужного типа

Умение корректно определять и использовать тип регистратора — базовый навык 1С-разработчика․ Главные правила:

  • Используйте ТИПЗНАЧЕНИЯ для анализа и ТИП для эталона сравнения․
  • Для фильтрации применяйте оператор В с массивом типов, переданным параметром․
  • Для доступа к уникальным реквизитам документа обязательно используйте ВЫРАЗИТЬ(․․․ КАК ․․․)․
  • Следите за версиями платформы: оператор ССЫЛКА делает код чище и понятнее․

Правильное применение этих техник позволяет писать быстрые, надежные и читаемые запросы для любых отчетов и обработок данных․