Зачем использовать ОбщегоНазначения.ЗначениеРеквизитаОбъекта вместо прямого обращения через точку к ссылке?

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

При разработке в типовых конфигурациях на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с конструкциями вида ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИмяРеквизита"). На первый взгляд может показаться, что это избыточное усложнение кода, ведь платформа позволяет обратиться к данным напрямую: Ссылка.ИмяРеквизита. Однако за этой внешней простотой скрываются серьезные механизмы работы с памятью и базой данных. В данной статье мы разберем, почему использование специализированных функций Библиотеки Стандартных Подсистем (БСП) является стандартом профессиональной разработки.

Механизм «Объектного кэша» и его подводные камни

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

Проанализируем последствия такого поведения:

  1. Избыточность данных: Если в документе 150 реквизитов, включая тяжелые текстовые поля (комментарии, описания), а вам нужна только сумма, сервер всё равно прочитает и передаст по сети все 150 полей.
  2. Расход памяти: Считанный объект занимает место в оперативной памяти сервера приложений. При массовой обработке ссылок в цикле это может привести к значительному потреблению ресурсов.
  3. Проблема «толстых» объектов: Как было отмечено в обсуждении, если у объекта множество реквизитов или он сам по себе очень сложный, неожиданная нагрузка («ж..а» в терминах участников форума) наступит очень быстро.

Как работает функция ЗначениеРеквизитаОбъекта

В отличие от прямого обращения, функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта подготавливает и выполняет точечный SQL-запрос. Рассмотрим пример её вызова:


СуммаЗаказа = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЗаказПокупателя, "СуммаДокумента");

При выполнении этого кода в СУБД будет отправлен запрос, выбирающий только поле СуммаДокумента. Это критически важно для высоконагруженных систем. Мы не засоряем кэш ненужными данными и экономим трафик между сервером 1С и сервером базы данных.

Преимущества использования методов БСП

Разберем дополнительные возможности, которые открываются при использовании функций общего назначения:

  1. Разыменование ссылок (Dot-walking): Мы можем получать данные через несколько уровней вложенности. Например:
    
    ВалютаЗаказа = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЗаказПокупателя, "ВалютаДокумента.Код");
    
    Такой подход выполнит оптимальное соединение (LEFT JOIN) на уровне SQL, что гораздо быстрее, чем последовательное обращение через точку, которое бы заставило платформу кэшировать сначала сам заказ, а потом и объект валюты.
  2. Безопасность при пустых ссылках: Если переменная ЗаказПокупателя окажется пустой, прямое обращение может вернуть неочевидный результат или привести к ошибке в определенных контекстах. Функции БСП корректно обрабатывают передачу Неопределено или пустых ссылок, возвращая пустое значение соответствующего типа.
  3. Групповое получение данных: Если нам нужно несколько полей одного объекта, крайне рекомендуется использовать ЗначенияРеквизитовОбъекта (во множественном числе), которая возвращает структуру:
    
    Данные = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ЗаказПокупателя, "Дата, Номер, СуммаДокумента");
    Если Данные.СуммаДокумента > 1000 Тогда
        // логика
    КонецЕсли;
    

Работа в транзакции и актуальность данных

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

На самом деле, благодаря уровню изоляции транзакций, запрос SELECT внутри той же самой транзакции успешно видит все изменения, внесенные ранее. Поэтому использование ЗначениеРеквизитаОбъекта остается безопасным и эффективным методом даже внутри транзакционных блоков.

Когда НЕ нужно использовать функции БСП?

Проанализируем ситуации, когда прямое обращение или другие методы будут предпочтительнее:

Итоги: правила хорошего тона

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

Привыкание к строковым литералам (именам реквизитов в кавычках) окупается скоростью работы программы и отсутствием «загадочных» просадок производительности на ровном месте.

← На главную