Программирование в 1С

Как получить значение реквизита в 1С программно: все способы

Коротко

Для одной ссылки проще всего получить значение реквизита в 1С через точку: Ссылка.Реквизит. Каждое такое обращение — это отдельный запрос к базе, поэтому в цикле по многим ссылкам используйте методы БСП ОбщегоНазначения.ЗначениеРеквизита() и ОбщегоНазначения.ЗначенияРеквизитов() (пакетное чтение) или обычный запрос.

Ключевое различие: реквизит объекта (поле справочника или документа) читается через ссылку, а реквизит формы — это отдельная сущность, доступная только в модуле формы через Элементы/реквизиты формы. Их часто путают.

Получить значение реквизита через точку (Ссылка.Реквизит)

Самый короткий способ получить значение реквизита в 1С — обратиться к нему через точку от ссылки на объект. Платформа сама подгрузит значение из базы:

Ссылка = Справочники.Номенклатура.НайтиПоКоду("00-000123");
Артикул = Ссылка.Артикул;
Производитель = Ссылка.Производитель;
Сообщить("Артикул: " + Артикул + ", производитель: " + Производитель);

Так можно читать любой реквизит объекта, включая стандартные (Код, Наименование, Родитель, ПометкаУдаления). Обращение через точку удобно для одиночного чтения, но у него есть скрытая цена — каждое такое обращение к незакэшированному реквизиту порождает отдельный запрос к СУБД.

Реквизит через объект: ПолучитьОбъект

Если реквизит нужно не только прочитать, но и изменить, получают объект методом ПолучитьОбъект() и работают с его реквизитами напрямую:

Объект = Ссылка.ПолучитьОбъект();
ТекущийАртикул = Объект.Артикул;   // чтение реквизита
Объект.Комментарий = "Проверено";  // запись реквизита
Объект.Записать();
ПолучитьОбъект
без параметров
СправочникОбъект

Для простого чтения реквизита ПолучитьОбъект() не нужен и даже вреден: он считывает объект целиком и блокирует его. Читайте через ссылку (Ссылка.Реквизит), а объект получайте только когда собираетесь записывать.

Метод ЗначениеРеквизита для одного реквизита

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

// БСП: значение одного реквизита по ссылке
Артикул = ОбщегоНазначения.ЗначениеРеквизита(НоменклатураСсылка, "Артикул");

// поддерживается путь через точку к реквизитам связанных объектов
СтранаПоставщика = ОбщегоНазначения.ЗначениеРеквизита(ЗаказСсылка, "Поставщик.СтранаРегистрации");

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

Пакетное чтение: ЗначенияРеквизитов для одной ссылки

Когда от одной ссылки нужно сразу несколько реквизитов, вместо нескольких обращений через точку берут их одним запросом методом ОбщегоНазначения.ЗначенияРеквизитов():

// вернёт структуру: Артикул, Производитель, ЕдиницаИзмерения
Реквизиты = ОбщегоНазначения.ЗначенияРеквизитов(НоменклатураСсылка, "Артикул,Производитель,ЕдиницаИзмерения");
Сообщить(Реквизиты.Артикул);
Сообщить(Реквизиты.Производитель);

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

Получить реквизиты для множества ссылок сразу

Если реквизиты нужно прочитать для целого массива ссылок (например, для строк документа), БСП предлагает ОбщегоНазначения.ЗначенияРеквизитовОбъектов() — он читает всё одним запросом и возвращает соответствие «ссылка → структура реквизитов»:

МассивСсылок = Новый Массив;
МассивСсылок.Добавить(Номенклатура1);
МассивСсылок.Добавить(Номенклатура2);

Данные = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(МассивСсылок, "Артикул,Производитель");
Для Каждого Элемент Из Данные Цикл
    Ссылка = Элемент.Ключ;
    Реквизиты = Элемент.Значение;
    Сообщить(Ссылка + ": " + Реквизиты.Артикул);
КонецЦикла;

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

Для больших выборок и отбора самый быстрый способ получить значения реквизитов в 1С — запрос. СУБД возвращает все нужные поля за одно обращение, без чтения объектов в память:

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   Номенклатура.Ссылка КАК Ссылка,
    |   Номенклатура.Артикул КАК Артикул,
    |   Номенклатура.Производитель КАК Производитель
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |   Номенклатура.ЭтоГруппа = ЛОЖЬ";

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Артикул + " / " + Выборка.Производитель);
КонецЦикла;

В запросе можно сразу «провалиться» через точку к реквизитам ссылочных полей (Номенклатура.Производитель.Наименование) — платформа построит нужные соединения сама. Это остаётся одним запросом, а не запросом в цикле.

Реквизиты табличной части

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

Объект = ДокументСсылка.ПолучитьОбъект();
Для Каждого Строка Из Объект.Товары Цикл
    Сообщить(Строка.Номенклатура.Наименование + " x " + Строка.Количество);
КонецЦикла;

Если нужны только данные (без изменения документа), те же реквизиты табличной части быстрее получить запросом к таблице Документ.РеализацияТоваров.Товары — тогда объект целиком в память не поднимается.

Частые ошибки при получении значения реквизита в 1С

  • Чтение через точку в цикле. Ссылка.Реквизит внутри цикла по многим объектам — это N запросов к базе. Используйте ЗначенияРеквизитовОбъектов() или запрос — одно обращение вместо тысяч.
  • Неверное имя реквизита. Имя должно точно совпадать с конфигуратором. Ошибка в регистре или букве даёт «Поле объекта не обнаружено» — имена берите из метаданных именно вашей базы.
  • Путаница реквизита объекта и реквизита формы. Ссылка.Реквизит читает реквизит объекта. Реквизит формы живёт только в модуле формы и доступен по своему имени, а не через ссылку.
  • ПолучитьОбъект() ради чтения. Для простого чтения объект получать не нужно — это лишняя нагрузка и блокировка. Читайте через ссылку, объект берите только для записи.
  • Обращение через точку у пустой ссылки. У пустой ссылки реквизиты вернут пустые значения, а путь через точку может дать ошибку. Метод ОбщегоНазначения.ЗначениеРеквизита() безопасно вернёт Неопределено.

Какой способ получения реквизита в 1С выбрать

  • Через точку — одно значение у одной ссылки, простое чтение.
  • ЗначениеРеквизита — один реквизит с безопасной проверкой и путём через точку (БСП).
  • ЗначенияРеквизитов — несколько реквизитов одной ссылки за один запрос (БСП).
  • ЗначенияРеквизитовОбъектов — реквизиты для множества ссылок сразу (БСП).
  • Запросом — большие выборки, отбор, реквизиты табличных частей.

Частые вопросы о получении значения реквизита в 1С

Как получить значение реквизита формы в 1С?

Реквизит формы — это не реквизит объекта. Он доступен только в модуле формы по своему имени (например, ЭтотОбъект.МойРеквизитФормы или напрямую по имени реквизита формы), а не через Ссылка.Реквизит. Читать реквизит формы через ссылку на объект нельзя.

Как получить значение дополнительного реквизита 1С?

Дополнительные реквизиты (механизм свойств БСП) не являются полями объекта, поэтому через точку не читаются. Их получают через таблицу ДополнительныеРеквизиты объекта или методами подсистемы «Свойства» (УправлениеСвойствами.ЗначенияДополнительныхРеквизитов).

Почему чтение реквизитов тормозит в цикле?

Каждое обращение Ссылка.Реквизит к незакэшированному полю — отдельный запрос к СУБД. В цикле по тысячам объектов это тысячи запросов. Решение — прочитать всё одним запросом или методом ОбщегоНазначения.ЗначенияРеквизитовОбъектов().