При разработке на платформе «1С:Предприятие 8» мы часто сталкиваемся с тем, что система ведет себя не совсем так, как мы ожидаем от классического объектно-ориентированного языка. Одной из таких «подводных» особенностей является механизм разрешения имен в модуле менеджера. Давайте разберем ситуацию, когда привычный код начинает выдавать странные ошибки из-за простого добавления нового предопределенного элемента в справочник или план видов характеристик.
Проанализируем, как платформа видит данные внутри модуля менеджера. В отличие от модуля объекта, где мы работаем с контекстом конкретного экземпляра (через ЭтотОбъект), модуль менеджера предназначен для операций, относящихся ко всей таблице в целом. Однако разработчики платформы заложили в этот модуль интересную особенность: краткое обращение к предопределенным элементам.
Это означает, что если в справочнике Валюты есть предопределенный элемент с именем USD, то внутри модуля менеджера этого справочника мы можем написать просто USD вместо полного пути Справочники.Валюты.USD. Рассмотрим, к каким последствиям это приводит.
Чтобы понять причину возникновения ошибок, нам необходимо изучить иерархию поиска идентификаторов, которую использует платформа. Когда интерпретатор встречает слово в коде модуля менеджера, он ищет его значение в следующем порядке:
Обратим внимание на 4-й и 5-й пункты. Предопределенные элементы стоят выше глобального контекста. Это означает, что они «перекрывают» (маскируют) любые системные объекты, если их имена совпадают.
Представим ситуацию: разработчик решил создать в справочнике НастройкиПользователей предопределенный элемент и назвал его Массив. Казалось бы, обычное имя. Но теперь посмотрим, что произойдет в коде модуля менеджера этого справочника при попытке создать обычный массив:
Процедура ИнициализироватьНастройки() Экспорт
// Платформа попытается найти "Массив" в контексте
// И найдет Ссылку на предопределенный элемент, а не системный тип!
НовыйСписок = Новый Массив;
КонецПроцедуры
В данном случае выполнение кода прервется с ошибкой, так как платформа попытается вызвать конструктор Новый для ссылки на элемент справочника, а не для системного типа Массив. Выясним причину: из-за приоритета (пункт 4 против пункта 5) имя предопределенного элемента «захватило» идентификатор Массив.
Проанализируем, какие еще имена могут нанести вред стабильности системы. К наиболее коварным относятся те, что часто используются в коде как типы данных или объекты глобального контекста:
Метаданные — перекроет доступ к структуре метаданных всей конфигурации.Справочники, Документы, Перечисления — заблокируют доступ к менеджерам других объектов.Запрос — сделает невозможным создание новых запросов через Новый Запрос.Структура, Соответствие, СписокЗначений — сломают работу с коллекциями.ВнешниеОбработки, ВнешниеОтчеты — часто встречающаяся ошибка в типовых решениях.Выясним логику разработчиков платформы. Модуль менеджера программно расширяет возможности объекта метаданных. С точки зрения системы, менеджер «знает» свою таблицу досконально. Предопределенные данные являются неотъемлемой частью этой таблицы, поэтому краткий доступ к ним задумывался как удобный инструмент (синтаксический сахар), позволяющий не писать длинные конструкции типа Справочники.ИмяСправочника.ИмяЭлемента внутри «родного» модуля.
Однако отсутствие жесткой проверки имен в конфигураторе превращает эту «фичу» в потенциальную ловушку. В модуле объекта (через который мы работаем с конкретной ссылкой) такой магии нет, что вносит дополнительную путаницу в ожидания разработчиков.
Для предотвращения подобных ситуаций разберем стандарты разработки, которых рекомендует придерживаться фирма «1С»:
Массив лучше использовать ВидНастройки_Массив или Предопределенный_Массив.Строка назовите элемент ТипДанныхСтрока.Если вы столкнулись с кодом, где предопределенный элемент уже назван, например, Запрос, и изменить это имя нельзя (из-за завязок во внешних системах или обмена данными), у вас есть два пути решения проблемы:
Вариант 1: Использование полных путей. К сожалению, прямого обращения к «глобальному контексту» как к объекту (типа ГлобальныйКонтекст.Массив) в 1С не существует. Если имя перекрыто предопределенным элементом, вы не сможете создать объект этого типа напрямую в данном модуле.
Вариант 2: Вынос логики в общие модули. Рассмотрим этот способ как наиболее надежный. Поскольку в общем модуле контекст менеджера конкретного справочника отсутствует, там идентификатор Массив или Запрос будет по-прежнему указывать на системный тип. Вынесите создание и обработку объектов в функцию общего модуля и вызывайте её из модуля менеджера.
// В модуле менеджера справочника, где есть предопределенный элемент "Запрос"
Процедура ВыполнитьДействие() Экспорт
// Вместо Новый Запрос, который вызовет ошибку:
МойЗапрос = ОбщийМодульСервер.СоздатьОбъектЗапрос();
КонецПроцедуры
Мы проанализировали особенность работы платформы с контекстом модуля менеджера. Важно запомнить: всегда проверяйте имена предопределенных элементов на уникальность относительно системных типов. Это сэкономит часы отладки и защитит ваш код от труднообъяснимых падений в рантайме. Помните, что чистота именования — это не только эстетика, но и залог технической стабильности системы.