Как правильно и быстро получить наименование элемента справочника без лишней нагрузки на сервер в 1С?

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

Каждый разработчик на платформе 1С:Предприятие рано или поздно сталкивается с задачей получения текстового представления или наименования объекта по его ссылке. Казалось бы, простая операция, но именно она часто становится причиной снижения производительности всей системы. В этой статье мы подробно разберем, как платформа 1С работает «под капотом» при получении наименований, развенчаем популярные мифы о работе функций преобразования типов и выработаем лучшие практики оптимизации вашего кода.

Разбор мифа: Можно ли получить наименование без участия сервера?

В среде разработчиков долгое время циркулировал миф о том, что использование конструкции СокрЛП(Ссылка) или простого приведения к строке Строка(Ссылка) позволяет мгновенно получить текстовое представление объекта прямо на клиенте, полностью избегая обращений к серверу приложений и СУБД. Проанализируем, почему это утверждение ошибочно.

Для оптимизации работы платформа 1С использует кэширование, разделенное на два независимых контура:

  1. Объектный кэш — хранит считанные объекты базы данных со всеми их реквизитами, табличными частями и метаданными.
  2. Кэш представлений — специализированный легкий кэш, который хранит исключительно строковые представления объектов (связку «Ссылка — Текстовое представление»).

Если для конкретной ссылки представление уже было получено ранее в текущем сеансе, то повторный вызов функции Строка(Ссылка) действительно мгновенно вернет значение из оперативной памяти клиента. Однако, если ссылка получена впервые или кэш представлений был очищен, платформа будет вынуждена отправить запрос на сервер и обратиться к СУБД для формирования строки. Таким образом, полностью избежать серверных вызовов при первом обращении физически невозможно.

Как преобразование ссылки к строке работает под капотом

Выясним причину, почему вызов Строка(Ссылка) работает быстрее, чем прямое обращение к свойству через точку вида Ссылка.Наименование, хотя оба метода в случае отсутствия данных в кэше отправляют запрос к СУБД.

Рассмотрим разницу в поведении платформы при выполнении этих операций:

Вариант 1. Прямое обращение через точку (Ссылка.Наименование)

Когда мы пишем такой код, платформа проверяет наличие объекта в объектном кэше. Если его там нет, выполняется тяжелый SQL-запрос к базе данных. Платформа считывает весь объект целиком — все его реквизиты (включая многострочные текстовые поля, реквизиты неограниченной длины) и даже табличные части. Весь этот массив данных передается по сети на сервер приложений, десериализуется и помещается в кэш. Это создает колоссальную избыточную нагрузку на сеть и оперативную память, особенно если вам нужно было всего лишь узнать краткое название контрагента.

Вариант 2. Преобразование ссылки к строке (Строка(Ссылка))

При использовании этой конструкции платформа ведет себя гораздо экономичнее. Если представления нет в кэше, выполняется легкий, точечный SQL-запрос. СУБД считывает только те поля, которые участвуют в формировании представления. По умолчанию для большинства справочников это поле Наименование (или Код, если наименование не задано в свойствах метаданных). Никакие лишние реквизиты и табличные части из базы данных не запрашиваются.

Посмотрим на пример кода, демонстрирующий разницу в подходах:


// Неоптимальный вариант: считывает весь объект из базы данных
ИмяКонтрагента = СсылкаНаКонтрагента.Наименование;

// Более легкий вариант: считывает только поле представления
ИмяКонтрагента = СокрЛП(Строка(СсылкаНаКонтрагента));

Произвольные представления в модуле менеджера

Начиная с версии платформы 8.3, у разработчиков появилась возможность гибко настраивать правила формирования строкового представления объектов через модуль менеджера. Для этого используются два стандартных события:

  1. ОбработкаПолученияПолейПредставления — указывает платформе, какие именно поля (например, Наименование, ИНН, Код) требуются для сборки строки.
  2. ОбработкаПолученияПредставления — содержит алгоритм сборки итоговой строки из полученных полей.

Разберем по шагам, как это работает на практике. Предположим, для справочника «Контрагенты» нам необходимо выводить представление в формате «Наименование (ИНН: ХХХХХХХХХХ)». Для этого в модуле менеджера справочника пишется следующий код:


Процедура ОбработкаПолученияПолейПредставления(Поля, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Поля.Добавить("Наименование");
    Поля.Добавить("ИНН");
КонецПроцедуры

Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Представление = Данные.Наименование + " (ИНН: " + Данные.ИНН + ")";
КонецПроцедуры

Внимание! При переопределении этих процедур крайне важно писать максимально простой и быстрый код. Если внутри процедуры ОбработкаПолученияПредставления вы напишете обращение через точку к связанным объектам или выполните тяжелый запрос, то любой вызов Строка(Ссылка) превратится в критическую точку отказа и моментально снизит производительность всей системы.

Опасность неявного преобразования в отчетах и списках

Одной из наиболее распространенных ошибок оптимизации является неявное приведение ссылочных типов к строке при формировании больших массивов данных. Классический пример — вывод ссылок напрямую в ячейки табличного документа при программном формировании отчетов без использования СКД.

Если вы выводите в ячейку таблицы значение с типом СправочникСсылка.Контрагенты, система при отрисовке каждой строки на экране будет вынуждена неявно вызывать функцию Строка(Ссылка). Если ваш отчет содержит 10 000 строк, платформа выполнит 10 000 отдельных последовательных микрозапросов к СУБД для получения представлений. Этот эффект называется проблемой «N+1 запроса».

Для предотвращения этой проблемы всегда получайте текстовые представления пакетом еще на этапе выполнения SQL-запроса, используя встроенную функцию ПРЕДСТАВЛЕНИЕ. Рассмотрим пример правильного построения запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Контрагенты.Ссылка КАК Ссылка,
    |	ПРЕДСТАВЛЕНИЕ(Контрагенты.Ссылка) КАК КонтрагентПредставление
    |ИЗ
    |	Справочник.Контрагенты КАК Контрагенты";

РезультатЗапроса = Запрос.Выполнить();
// Теперь при выводе в отчет мы используем уже готовую строку "КонтрагентПредставление"

Использование Библиотеки Стандартных Подсистем (БСП)

В современных типовых конфигурациях 1С лучшим стандартом разработки для точечного получения реквизитов объектов является использование функций БСП. Если вам нужно гарантированно получить чистое наименование объекта из базы данных без применения логики кастомных представлений из модуля менеджера, используйте функцию общего назначения.

Рассмотрим пример вызова этой функции:


НаименованиеКонтрагента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаКонтрагента, "Наименование");

Под капотом БСП формирует динамический параметризованный SQL-запрос, который запрашивает из базы данных исключительно одно конкретное поле — Наименование. Этот подход сочетает в себе абсолютную надежность, быстродействие и независимость от настроек отображения объектов в интерфейсе.

← На главную