Как в запросе 1С получить числовой идентификатор типа документа-регистратора?

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С:Предприятие часто возникает задача классификации данных. Например, при построении сложных отчетов или выгрузок может потребоваться заменить ссылку на документ конкретным числовым кодом (ID), зависящим от его типа. Рассмотрим, как правильно реализовать такое условие в запросе, разберем типичные ошибки и выясним, как оптимизировать производительность при работе с составными типами данных.

Задача: присвоение условного номера типу документа

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

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

Использование оператора ССЫЛКА

Рассмотрим наиболее правильный и эффективный с точки зрения синтаксиса способ — использование оператора ССЫЛКА. Этот оператор проверяет, относится ли ссылка в поле к конкретной таблице метаданных.

Разберем пример кода запроса:


ВЫБРАТЬ
    ТоварыОрганизацийОстаткиИОбороты.Регистратор КАК Регистратор,
    ВЫБОР
        КОГДА ТоварыОрганизацийОстаткиИОбороты.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
            ТОГДА 1
        КОГДА ТоварыОрганизацийОстаткиИОбороты.Регистратор ССЫЛКА Документ.ВозвратТоваровПоставщику
            ТОГДА 2
        КОГДА ТоварыОрганизацийОстаткиИОбороты.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
            ТОГДА 3
        ИНАЧЕ 0
    КОНЕЦ КАК УсловноеИДРегистратора,
    ТоварыОрганизацийОстаткиИОбороты.КоличествоКонечныйОстаток КАК Остаток
ИЗ
    РегистрНакопления.ТоварыОрганизаций.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Регистратор, , ) КАК ТоварыОрганизацийОстаткиИОбороты

В данном примере мы используем конструкцию ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ. Обратите внимание на ветку ИНАЧЕ: ее крайне рекомендуется добавлять, чтобы исключить появление значений NULL или неопределенных состояний, если в выборку попадет документ, не описанный в ваших условиях.

Использование ТИПЗНАЧЕНИЯ и ТИП()

Альтернативный способ заключается в сравнении типа поля с конкретным типом объекта метаданных. Рассмотрим, как это выглядит в коде:


ВЫБОР 
    КОГДА ТИПЗНАЧЕНИЯ(ТоварыОрганизацийОстаткиИОбороты.Регистратор) = ТИП(Документ.ПоступлениеТоваровУслуг) 
        ТОГДА 1 
    ИНАЧЕ 0 
КОНЕЦ КАК УсловноеИДРегистратора

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

Разбор ошибки «Поле не найдено Регистратор»

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

Виртуальные таблицы, такие как ОстаткиИОбороты, Остатки или Обороты, оптимизированы для быстрого получения итогов. По умолчанию платформа 1С не включает поле Регистратор в выборку виртуальной таблицы, так как это значительно увеличивает нагрузку на СУБД. Если вы просто обратитесь к полю Регистратор, не настроив таблицу, вы получите ошибку.

Чтобы исправить ситуацию, проанализируем параметры виртуальной таблицы. В параметрах ОстаткиИОбороты третьим параметром идет Периодичность. Вам необходимо установить значение Регистратор (или Авто, если вы используете СКД и она сама определяет нужные поля).

Посмотрим на правильный вызов таблицы:

РегистрНакопления.ТоварыОрганизаций.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Регистратор, , )

Только после указания периодичности Регистратор поле станет доступным для использования в секциях ВЫБРАТЬ, ГДЕ и в конструкции ВЫБОР.

Разбор ошибки «Таблица не найдена»

Если система ругается на то, что таблица Документ.ИмяДокумента не найдена, проверьте следующие моменты:

  1. Имена метаданных: Убедитесь, что вы используете «Имя» объекта из конфигуратора, а не его «Синоним».
  2. Префиксы расширений и отраслевых решений: В специализированных конфигурациях или расширениях к именам документов часто добавляются префиксы (например, бит_ПоступлениеТоваров). Проверьте точное написание в дереве метаданных.
  3. Опечатки: Зачастую ошибка кроется в банальной опечатке в длинном названии документа.

Производительность и технические нюансы

Проанализируем, что происходит «под капотом» СУБД при выполнении такого запроса. Поле Регистратор имеет составной тип данных. Когда вы пишете Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг, платформа на уровне SQL формирует соединение (LEFT JOIN) с таблицей этого документа.

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

Рассмотрим рекомендации по оптимизации:

  1. Фильтрация по типам: Если вам нужны данные только по определенным типам документов, старайтесь ограничивать выборку в параметрах ГДЕ виртуальной таблицы, а не только в выходных полях.
  2. Использование временных таблиц: Если логика сложная, сначала выберите Регистратор и другие поля во временную таблицу без условий по типам. Затем, во втором запросе, уже работайте с этой временной таблицей. Это упростит план запроса для оптимизатора СУБД.
  3. Денормализация: Если отчет по типам регистраторов строится очень часто и на огромных объемах данных, рассмотрите возможность добавления в регистр дополнительного реквизита ТипРегистратораID (тип — Число или Перечисление). Заполняйте его при проведении документа. Это позволит делать выборку мгновенно, не используя тяжелые проверки типов в запросе.

Итоги

Для успешного получения ID регистратора в запросе необходимо:

Соблюдение этих правил позволит вам создавать надежные и быстрые запросы для любых учетных систем на платформе 1С.

← На главную