Зачем использовать ВЫРАЗИТЬ при обращении к реквизитам через точку в запросах 1С

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

В практике разработки на платформе 1С:Предприятие часто возникает ситуация, когда необходимо получить данные из реквизитов поля, имеющего составной тип данных. Типичный пример — поле Регистратор в регистрах накопления или бухгалтерии. Рассмотрим ситуацию: внешне два запроса выдают идентичный результат, но один из них считается «правильным» и быстрым, а другой — потенциальной причиной критических тормозов системы. Разберем детально, в чем заключается эта разница и почему использование оператора ВЫРАЗИТЬ является обязательным стандартом разработки.

Проблема обращения через точку от составного типа

Представим стандартную задачу: нам нужно выгрузить данные из регистра и определить контрагента. В зависимости от типа документа-регистратора контрагент может называться по-разному (например, Поставщик в приходной накладной и Покупатель в расходной). Проанализируем типичный код, который кажется логичным на первый взгляд:


ВЫБОР
    КОГДА ОстаткиТоваров.Регистратор ССЫЛКА Документ.ПриходнаяНакладная
        ТОГДА ОстаткиТоваров.Регистратор.Поставщик
    КОГДА ОстаткиТоваров.Регистратор ССЫЛКА Документ.РасходнаяНакладная
        ТОГДА ОстаткиТоваров.Регистратор.Покупатель
КОНЕЦ КАК Контрагент

Несмотря на то, что этот запрос вернет верные данные, он таит в себе серьезную архитектурную проблему. Дело в том, как платформа 1С транслирует этот код в язык SQL, понятный серверу баз данных (MS SQL Server, PostgreSQL и др.).

Механизм работы СУБД без оператора ВЫРАЗИТЬ

Разберем, что происходит «под капотом». Поле Регистратор является составным. Оно может содержать ссылки на десятки различных типов документов. Когда мы пишем Регистратор.Поставщик, платформа не знает заранее, какой именно документ лежит в конкретной записи. Поэтому в формируемом SQL-запросе создается левое соединение (LEFT OUTER JOIN) со всеми таблицами документов, которые входят в состав типа Регистратор и имеют реквизит с таким именем.

Проанализируем последствия такого подхода:

  1. Избыточные соединения: Если в регистраторы включено 50 видов документов, SQL-сервер может попытаться выполнить десятки лишних соединений.
  2. Нагрузка на оптимизатор: Планировщик запросов СУБД тратит значительное время на обработку гигантского текста запроса.
  3. Риск ошибки: Существует предел количества таблиц в одном запросе. При очень сложном составе поля запрос может просто не выполниться с ошибкой «Query is too complex».

Оптимизация с помощью оператора ВЫРАЗИТЬ

Теперь рассмотрим правильный вариант написания того же условия. Мы будем использовать конструкцию ВЫРАЗИТЬ(... КАК ...). Это дает платформе явное указание: «В этой ветке условия мы точно знаем, что тип регистратора — Приходная накладная, поэтому обращайся только к этой конкретной таблице».


ВЫБОР
    КОГДА ОстаткиТоваров.Регистратор ССЫЛКА Документ.ПриходнаяНакладная
        ТОГДА ВЫРАЗИТЬ(ОстаткиТоваров.Регистратор КАК Документ.ПриходнаяНакладная).Поставщик
    КОГДА ОстаткиТоваров.Регистратор ССЫЛКА Документ.РасходнаяНакладная
        ТОГДА ВЫРАЗИТЬ(ОстаткиТоваров.Регистратор КАК Документ.РасходнаяНакладная).Покупатель
КОНЕЦ КАК Контрагент

В этом случае в SQL-запросе вместо «ковровой бомбардировки» соединениями будет создано строго одно соединение с таблицей Документ.ПриходнаяНакладная для первой ветки и с Документ.РасходнаяНакладная для второй. Это кардинально снижает нагрузку на сервер БД.

Сравнение работы в файловом и серверном вариантах

Выясним интересную особенность, упомянутую опытными разработчиками. В файловой версии базы данных запрос без ВЫРАЗИТЬ иногда может работать даже быстрее. Это связано с тем, что встроенный движок 1С (собственный формат файлов .1CD) обрабатывает типизацию иначе, чем SQL-сервер. Однако ориентироваться на файловую версию при разработке — плохая практика.

В серверном варианте (особенно на высоконагруженных системах) использование ВЫРАЗИТЬ является критически обязательным. Без него время выполнения отчета может вырасти с нескольких секунд до нескольких минут или привести к полной блокировке таблиц.

Особый случай: тип «ЛюбаяСсылка»

Рассмотрим ситуацию, когда поле имеет тип ЛюбаяСсылка (например, реквизит Владелец в некоторых справочниках или Объект в задачах бизнес-процессов). Если попытаться обратиться через точку к реквизиту такого поля без ВЫРАЗИТЬ, система теоретически может попытаться соединиться со всеми таблицами базы данных, где есть такой реквизит (например, Наименование). Это гарантированный способ «уронить» производительность системы.

Резюме и рекомендации

Подведем итог нашего анализа. Использование оператора ВЫРАЗИТЬ при работе с составными типами — это не просто «стиль кодирования», а фундаментальное требование производительности.

Основные правила для разработчика:

  1. Всегда используйте ВЫРАЗИТЬ, если обращаетесь к реквизиту поля составного типа через точку.
  2. Помните, что если тип значения в поле не совпадет с типом в ВЫРАЗИТЬ, результатом будет NULL. Это позволяет писать безопасный и отказоустойчивый код.
  3. При использовании Системы компоновки данных (СКД) правила остаются теми же: несмотря на внутренние механизмы оптимизации СКД, явное приведение типов в тексте запроса гарантирует предсказуемость результата.

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

← На главную