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