В процессе разработки на платформе «1С:Предприятие 8» программисты часто сталкиваются с ситуациями, когда необходимо обратиться к данным объекта динамически, не зная имени конкретного реквизита или колонки на этапе написания кода. Традиционный способ обращения через точку Объект.ИмяРеквизита в таких случаях не подходит. Рассмотрим подробно механизм использования квадратных скобок [], который часто вызывает вопросы: является ли это недокументированной особенностью или стандартным поведением платформы.
Для многих встроенных типов в 1С оператор получения значения по индексу [] является универсальным. Проанализируем ситуацию, описанную в теме: у нас есть объект типа СтрокаТаблицыЗначений. Платформа позволяет обращаться к его колонкам тремя способами:
НоваяСтрока.ИмяКолонки. Это самый быстрый и предпочтительный способ, если имя колонки известно заранее.НоваяСтрока[0]. Используется, когда мы обходим колонки в цикле по их числовому номеру.НоваяСтрока["ИмяКолонки"]. Именно этот способ часто кажется «скрытым», так как в кратких справках он упоминается реже остальных.Выясним причину, почему это работает. Объект СтрокаТаблицыЗначений реализует интерфейс коллекции. Платформа «прощает» разработчику использование строкового ключа внутри квадратных скобок, выполняя внутренний поиск индекса колонки по её имени в коллекции Колонки родительской таблицы значений.
Проанализируем поведение итератора при обходе строки. Если мы используем конструкцию Для каждого ... Из ... Цикл для объекта СтрокаТаблицыЗначений, мы получим последовательный перебор значений ячеек в этой строке. Рассмотрим пример кода:
Для каждого ЗначениеЯчейки Из СтрокаТаблицы Цикл
// В переменную ЗначениеЯчейки попадает содержимое колонки,
// но мы не знаем здесь Имя этой колонки.
Сообщить(ЗначениеЯчейки);
КонецЦикла;
Важно понимать разницу: в отличие от объекта Структура, где итератор возвращает объект КлючИЗначение, строка таблицы значений при обходе возвращает только сами данные. Поэтому обращение через Строка["ИмяКолонки"] является единственным способом получить значение по динамическому имени без прямого использования точки.
Как отмечают участники обсуждения, данный механизм работает не только для таблиц значений. Рассмотрим, где еще можно применить обращение через квадратные скобки:
СправочникОбъект, ДокументОбъект и т.д. можно написать Объект["Код"] или Объект["Дата"]. Это позволяет писать универсальные алгоритмы обработки данных.СправочникСсылка или ДокументСсылка такой синтаксис также допустим. Однако здесь кроется ловушка производительности. Если вы обращаетесь к реквизиту ссылки через [], и этого реквизита нет в кэше, платформа может считать весь объект из базы данных.Рассмотрим пример универсальной функции, которая может работать с любым объектом, имеющим реквизит «Сумма»:
Функция ПолучитьСуммуЛюбогоОбъекта(ЛюбойОбъект) Экспорт
// Если мы не уверены в типе, но знаем, что поле "Сумма" должно быть
Возврат ЛюбойОбъект["Сумма"];
КонецФункции
Выясним, стоит ли повсеместно использовать такой подход. Проанализируем технические аспекты выполнения кода:
1. Скорость выполнения: Обращение через точку Строка.Колонки компилируется на этапе подготовки модуля. Платформа точно знает адрес значения в памяти. При использовании Строка["ИмяКолонки"] системе требуется время на поиск строки в хеш-таблице имен колонок. В циклах на сотни тысяч итераций это может привести к замедлению работы на 10–15%.
2. Контроль ошибок (Runtime Error): Это критически важный момент. Если вы ошибетесь в написании имени в кавычках (например, Строка["Суммаа"]), программа выдаст исключение и аварийно завершится. В случае использования Структуры мы можем использовать метод Свойство(), чтобы проверить наличие ключа. У СтрокаТаблицыЗначений такого метода нет. Перед использованием [] рекомендуется убедиться, что такая колонка существует:
Если Строка.Владелец().Колонки.Найти("ИмяКолонки") <> Неопределено Тогда
Значение = Строка["ИмяКолонки"];
КонецЕсли;
3. Рефакторинг и поддержка кода: Инструменты 1С (и сторонние расширения типа SonarQube) плохо распознают имена в кавычках. Если вы решите переименовать колонку в метаданных или в коде создания таблицы, автоматический поиск ссылок (F12) не покажет вам строковые обращения в квадратных скобках. Это существенно усложняет поддержку крупных конфигураций.
Рассмотрим ситуацию с использованием функций-посредников, упомянутую в обсуждении (пример с модулями «Раруса» или БСП). Зачем создавать функцию ПолучитьРеквизит(Объект, ИмяРеквизита), если можно просто написать Объект[ИмяРеквизита]?
Во-первых, это инкапсуляция. В будущем в такую функцию можно добавить логику проверки прав доступа, логирование или обработку ошибок (например, возвращать Неопределено вместо падения системы).
Во-вторых, это вызов сервера. В типовых конфигурациях (БСП) часто используются функции типа ОбщегоНазначения.ЗначениеРеквизитаОбъекта(). Это необходимо, потому что на клиенте у нас есть только ссылка, а данные реквизитов лежат на сервере. Попытка обратиться к Ссылка["Реквизит"] на клиенте может привести к неявному серверному вызову, что крайне негативно сказывается на скорости интерфейса («проблема 1+N»).
Посмотрим на правильный пример получения данных через универсальный механизм:
// Вместо небезопасного прямого обращения
Значение = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "Наименование");
// Если работаем с таблицей значений на сервере
Для каждого Стр Из ТЗ Цикл
// Динамическое получение данных по массиву нужных колонок
Для каждого ИмяКолонки Из МассивИмен Цикл
ТекДанные = Стр[ИмяКолонки];
// Обработка данных
КонецЦикла;
КонецЦикла;
Использование квадратных скобок для доступа по строковому ключу — это мощный инструмент платформы «1С:Предприятие 8», который не является багом. Это штатная реализация доступа к свойствам объектов, поддерживающих интерфейс коллекции или динамический набор свойств.
Основные выводы:
Объект.Поле всегда, когда имя поля известно заранее — это быстрее и безопаснее для рефакторинга.Объект["Поле"] только для универсальных алгоритмов, где имя поля передается в переменной.СтрокаТаблицыЗначений нет метода Свойство(), поэтому всегда проверяйте состав колонок перед обращением, чтобы избежать падения программы.Таким образом, «недокументированность» этой фичи скорее связана с тем, что 1С продвигает более строгие стандарты разработки, минимизирующие ошибки из-за опечаток в строковых литералах. Тем не менее, знание этого механизма необходимо каждому профессиональному разработчику для написания гибкого и универсального кода.