Использование квадратных скобок [] при работе со справочниками в 1С: поиск или обращение к свойствам?

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

В среде разработчиков 1С периодически возникают дискуссии о скрытых или малодокументированных возможностях платформы. Одной из таких тем является использование оператора квадратные скобки [] применительно к менеджерам справочников. На первый взгляд может показаться, что это альтернативный синтаксис для поиска элементов по наименованию, аналогичный работе с объектом Соответствие. Однако, чтобы не допустить критических ошибок в логике работы программы, нам необходимо детально разобраться, как именно платформа обрабатывает такие конструкции.

Механизм позднего связывания и оператор доступа по строке

Для начала проанализируем фундаментальный принцип работы встроенного языка 1С:Предприятие 8. Оператор [] представляет собой механизм позднего связывания. Он позволяет обратиться к свойству объекта, имя которого становится известным только в момент выполнения программного кода. Рассмотрим стандартную ситуацию: когда мы пишем Справочники.Номенклатура, мы обращаемся к объекту через точку. Но платформа также позволяет нам написать Справочники["Номенклатура"]. Эти записи абсолютно идентичны по результату.

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

Сценарий 1: Обращение к менеджеру справочника (Предопределенные элементы)

Многие разработчики ошибочно полагают, что конструкция Справочники.ИмяСправочника["Значение"] выполняет поиск в базе данных по полю «Наименование». Это заблуждение. На самом деле, когда мы используем квадратные скобки у Менеджера Справочника, платформа ищет в метаданных предопределенный элемент с указанным именем (именем, заданным в конфигураторе, а не в пользовательском режиме).

Давайте посмотрим на пример кода, который демонстрирует это поведение:


// Предположим, в конфигураторе создан предопределенный элемент с именем "ОсновнойСклад"
// Мы можем обратиться к нему тремя способами:

// 1. Стандартное обращение через точку
Ссылка1 = Справочники.Склады.ОсновнойСклад;

// 2. Обращение через квадратные скобки по строковому литералу
Ссылка2 = Справочники.Склады["ОсновнойСклад"];

// 3. Динамическое обращение через переменную
ИмяЭлемента = "ОсновнойСклад";
Ссылка3 = Справочники.Склады[ИмяЭлемента];

Если Ссылка1 = Ссылка2 И Ссылка2 = Ссылка3 Тогда
    Сообщить("Все три способа вернули одну и ту же ссылку на предопределенный элемент.");
КонецЕсли;

Важный нюанс: если вы попытаетесь передать в скобки строку, которой нет в списке имен предопределенных элементов этого справочника, система выдаст ошибку времени выполнения (Property not found). Это еще раз доказывает, что это не поиск по данным, а обращение к программным идентификаторам метаданных.

Сценарий 2: Обращение к ссылке справочника (Доступ к реквизитам)

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

Проанализируем ситуацию: нам нужно получить значение произвольного реквизита у элемента справочника «Контрагенты», не зная заранее имени этого реквизита.


Процедура ВывестиЗначениеРеквизита(СсылкаНаОбъект, ИмяРеквизита)
    // Вместо использования функции Вычислить() или громоздких условий, 
    // используем оператор []
    
    Попытка
        Значение = СсылкаНаОбъект[ИмяРеквизита];
        Сообщить("Реквизит " + ИмяРеквизита + " имеет значение: " + Значение);
    Исключение
        Сообщить("У объекта нет реквизита с именем " + ИмяРеквизита);
    КонецПопытки;
КонецПроцедуры

// Пример вызова:
ВывестиЗначениеРеквизита(ВыбраннаяСсылка, "ИНН");
ВывестиЗначениеРеквизита(ВыбраннаяСсылка, "ПолноеНаименование");

Этот метод работает идентично обращению через точку СсылкаНаОбъект.ИмяРеквизита, но дает гибкость при работе с динамическими именами свойств.

Почему это не аналогично методу НайтиПоНаименованию()?

Рассмотрим принципиальные отличия механизма [] от полноценного поиска. Поиск по наименованию (метод НайтиПоНаименованию()) инициирует SQL-запрос к таблице базы данных и ищет совпадение в колонке Description (Наименование). Оператор [] у менеджера работает только в оперативной памяти с коллекцией метаданных.

Проанализируем таблицу различий:

  1. Область поиска: НайтиПоНаименованию() ищет по всем записям в БД. Квадратные скобки ищут только среди предопределенных элементов.
  2. Тип аргумента: В поиске вы указываете строку, которая может содержать любые символы. В скобках вы указываете имя (идентификатор), который должен соответствовать правилам именования объектов в 1С (без пробелов, не начинаться с цифры и т.д.).
  3. Результат при отсутствии: Метод поиска вернет ПустаяСсылка. Оператор доступа к свойству [] вызовет исключение и аварийное завершение скрипта, если свойство не найдено.

Практические советы по использованию

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

  1. Разработка универсальных механизмов загрузки данных: когда соответствие полей файла и реквизитов справочника задается настройками в базе.
  2. Работа с перечислениями: Конструкция Перечисления[ИмяПеречисления][ИмяЗначения] позволяет получать значения перечислений полностью динамически.
  3. Оптимизация кода: использование [] работает значительно быстрее, чем функция Вычислить(), так как не требует парсинга и компиляции всей строки выражения, а лишь ищет имя в таблице символов объекта.

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

← На главную