Что быстрее и правильнее в 1С: обращение к предопределенному элементу или поиск по коду?

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

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


// Вариант 1: Прямое обращение к предопределенному значению
Счет = ПланыСчетов.Хозрасчетный.ВспомогательныеПроизводства;

// Вариант 2: Поиск элемента по коду
Счет = ПланыСчетов.Хозрасчетный.НайтиПоКоду("23");

Разберем детально, как работают оба механизма на уровне платформы, что происходит с производительностью и какие стандарты разработки необходимо соблюдать.

Механизмы платформы: кэширование против запроса к СУБД

Проанализируем работу платформы при выполнении каждого из вариантов:

  1. Обращение к предопределенному элементу. При старте клиентского сеанса и инициализации менеджеров объектов платформа загружает таблицу соответствий имен предопределенных элементов и их внутренних идентификаторов (поле _PredefinedID) в оперативный кэш. Обращение вида ПланыСчетов.Хозрасчетный.ВспомогательныеПроизводства или вызов функции ПредопределенноеЗначение("ПланыСчетов.Хозрасчетный.ВспомогательныеПроизводства") извлекает ссылку мгновенно из памяти, не отправляя отдельный SQL-запрос к СУБД. На тонком клиенте функция ПредопределенноеЗначение() выполняется без серверного вызова, если метаданные уже находятся в клиентском кэше.
  2. Поиск по коду через НайтиПоКоду(). Вызов метода НайтиПоКоду() всегда инициирует выполнение SQL-запроса SELECT к базе данных. Несмотря на то, что поиск происходит по индексированному полю, платформе требуется совершить сетевой раундтрип между сервером 1С и СУБД, выполнить поиск по B-дереву индекса и передать результат обратно. Это создает гарантированные накладные расходы по времени и ресурсам.

Сравнение подходов в текстах запросов 1С

Посмотрим на аналогичную задачу при составлении условий в запросах. Сравним два варианта фильтрации данных:


// Вариант 1: Использование конструкции ЗНАЧЕНИЕ
ГДЕ
    Хозрасчетный.Счет = ЗНАЧЕНИЕ(ПланыСчетов.Хозрасчетный.ВспомогательныеПроизводства)

// Вариант 2: Сравнение по реквизиту через точку
ГДЕ
    Хозрасчетный.Счет.Код = "23"

Выясним, почему первый вариант в разы эффективнее:

  1. Конструкция ЗНАЧЕНИЕ(...) преобразуется платформой на этапе компиляции запроса в константный бинарный идентификатор (GUID). В итоговом SQL-запросе к СУБД происходит прямое сравнение ссылок без лишних операций.
  2. Обращение через точку к реквизиту Хозрасчетный.Счет.Код приводит к неявному соединению (LEFT JOIN) с таблицей плана счетов. Это усложняет план выполнения запроса в СУБД, увеличивает время обработки и может препятствовать использованию оптимальных индексов.

Риски надежности и бизнес-логики при поиске по коду

Помимо проигрыша в скорости, использование метода НайтиПоКоду() несет в себе критические риски для работоспособности конфигурации:

  1. Человеческий фактор и изменение данных. Пользователи с соответствующими правами могут отредактировать код или наименование счета в режиме «1С:Предприятие». Если в алгоритме зашит поиск по строке "23", логика программы полностью нарушится. Имя предопределенного элемента зафиксировано в конфигураторе и не зависит от пользовательских изменений кода или наименования.
  2. Неуникальность кодов. Если для объекта отключен контроль уникальности кодов либо используется периодическая/иерархическая нумерация, метод НайтиПоКоду() вернет первый попавшийся элемент, что приведет к труднодиагностируемым ошибкам в проводках и расчетах.
  3. Ограничения прав доступа (RLS). При включенных механизмах RLS поиск по коду может вернуть пустую ссылку из-за ограничений на чтение таблицы, тогда как обращение к предопределенному значению позволяет корректно передавать и сравнивать ссылку даже в контексте закрытых записей.

Методы для динамической работы с предопределенными данными

Если в коде необходимо динамически получать имя или ссылку предопределенного элемента, платформа предоставляет специальные встроенные методы менеджеров:


// Получение ссылки по строковому имени предопределенного элемента
СсылкаНаСчет = ПланыСчетов.Хозрасчетный.ПолучитьСсылкуПоИмениПредопределенного("ВспомогательныеПроизводства");

// Получение имени предопределенного элемента по ссылке
ИмяЭлемента = ПланыСчетов.Хозрасчетный.ПолучитьИмяПредопределенного(СсылкаНаСчет);

Итоги и стандарты разработки

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

← На главную