Зачем использовать переменные модуля для хранения менеджеров перечислений и объектов в 1С?

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

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

Суть рассматриваемого приема

Давайте проанализируем ситуацию на конкретном примере. В начале модуля объекта программист пишет следующее:


Перем мСтавкиНДС;
Перем мВидыНоменклатуры;

А в конце модуля, в области инициализации (основной части), выполняется присваивание:


мСтавкиНДС = Перечисления.СтавкиНДС;
мВидыНоменклатуры = Перечисления.ВидыНоменклатуры;

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

1. Повышение производительности на уровне байт-кода

Первая и самая техническая причина — это скорость работы платформы. Разберем по шагам, что происходит, когда мы пишем Перечисления.СтавкиНДС. В этот момент платформа 1С выполняет поиск объекта в глобальном контексте. Это операция поиска по ключу в хеш-таблице. Хотя она выполняется очень быстро, в высоконагруженных циклах (например, при обработке сотен тысяч строк в документе) суммарные затраты времени могут стать заметными.

Когда же мы используем переменную модуля мСтавкиНДС, ссылка на менеджер объекта уже закэширована в локальной таблице переменных модуля. Обращение к переменной происходит по индексу в этой таблице, что на уровне выполнения байт-кода быстрее, чем поиск в глобальном контексте. Посмотрим на пример гипотетического цикла:


// Вариант 1: Прямое обращение
Для Каждого Строка Из ТЧ Цикл
    Если Строка.СтавкаНДС = Перечисления.СтавкиНДС.НДС20 Тогда
        // Логика
    КонецЕсли;
КонецЦикла;

// Вариант 2: Использование переменной модуля
Для Каждого Строка Из ТЧ Цикл
    Если Строка.СтавкаНДС = мСтавкиНДС.НДС20 Тогда
        // Логика
    КонецЕсли;
КонецЦикла;

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

2. Абстрагирование и гибкость рефакторинга

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


// Было:
мСтавкиНДС = Перечисления.СтавкиНДС;
// Стало:
мСтавкиНДС = Справочники.СтавкиНДС;

Весь остальной код в процедурах (например, мСтавкиНДС.НДС20) останется работоспособным (при условии идентичности имен элементов). Это значительно упрощает поддержку сложных систем.

3. Универсальность кода и разработка тиражных решений

Рассмотрим пример разработки универсальных модулей, которые должны работать в разных конфигурациях (например, интеграционные модули Диадока или БСП). В одной конфигурации перечисление может называться СтавкиНДС, а в другой — НДС_Ставки. Чтобы не переписывать логику под каждую базу, разработчики используют переменные-посредники. При запуске модуля система определяет, какие объекты метаданных есть в наличии, и подставляет их в соответствующие переменные. Это позволяет писать «независимый» от конкретных имен метаданных код.

4. Предотвращение «затенения» имен и читаемость

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

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

  1. Визуальный контроль: Вы сразу видите, откуда взята переменная.
  2. Безопасность: Вы случайно не измените реквизит объекта, думая, что работаете с локальной переменной.
  3. Поддержка в IDE: Современные инструменты разработки, такие как 1C:EDT, лучше анализируют зависимости, когда они явно выделены.

5. Тестирование и Mock-объекты

В продвинутой разработке использование переменных модуля позволяет применять Unit-тестирование. Если ваша функция жестко завязана на Перечисления.СтавкиНДС.НДС20, ее сложно проверить без реальной базы данных. Однако, если функция использует мСтавкиНДС.НДС20, то в рамках теста вы можете «подменить» (замокать) значение этой переменной на тестовый объект. Это позволяет проверять сложные алгоритмы в изоляции от данных базы.

Когда этот подход НЕ оправдан?

Несмотря на все плюсы, рассмотрим и критику. Если модуль небольшой, а обращения к перечислениям единичны, создание лишних переменных может только запутать код. В простых обработках лучше придерживаться принципа KISS (Keep It Simple, Stupid) и использовать прямые обращения к метаданным — это делает код понятнее для тех, кто не привык искать инициализацию переменных в конце модуля.

Подведем итог: использование переменных модуля для кэширования менеджеров — это не просто «выпендреж» или «тяжелое наследие», а инструмент профессионального разработчика для создания быстрого, гибкого и универсального кода. Попробуем применить эти знания в своих проектах, соблюдая баланс между производительностью и читаемостью.

← На главную