Чтение реквизитов в 1С 8.3: от точки через ссылку до компоновщика отчёта

· 9 мин

Содержание

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

Ниже примеры для платформы 8.3 и управляемых форм. Код работает в типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) и в собственных разработках — различаются только имена объектов.

Какой способ выбрать: сравнение по задачам

Сначала определите контекст. Одна и та же строка Ссылка.ИНН на сервере работает, а в клиентском обработчике формы падает с ошибкой.

СпособГде работаетКогда братьМинусы
Через точку Объект.РеквизитСервер, форма (данные формы)Объект уже в памятиОт ссылки читает объект целиком
ЗначениеРеквизитаОбъекта (БСП)СерверОдин-два реквизита по ссылкеТолько в конфигурациях с БСП
ЗапросСерверМного записей, отборы, соединенияБольше кода
СКДСервер, отчётыЗначение для отчёта, группировки, итогиТяжеловата для одного поля
МетаданныеКлиент и серверИмя, синоним, тип поля, а не данныеДанных не возвращает

💡 Правило практика: если значений больше десятка — пишите запрос. Чтение через точку в цикле по тысяче документов превращается в тысячу обращений к базе.

Выборка значений полей языком запросов

Запрос — основной способ получить данные из базы на сервере. Он читает только перечисленные поля и позволяет отобрать нужные записи условием.

Одно значение по ссылке

&НаСервереБезКонтекста
Функция ИННКонтрагента(Контрагент)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Контрагенты.ИНН КАК ИНН
    |ИЗ
    |    Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |    Контрагенты.Ссылка = &Ссылка";
    Запрос.УстановитьПараметр("Ссылка", Контрагент);

    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Выборка.ИНН;
    КонецЕсли;

    Возврат "";

КонецФункции

Обращение Выборка.ИНН работает по псевдониму после КАК. Если псевдоним не задан, платформа назовёт колонку по последнему имени в пути, но лучше задавать его явно.

Значения из связанных объектов

Разыменование через точку в запросе тоже работает: Реализация.Контрагент.ИНН. Платформа сама добавит соединение с таблицей контрагентов.

Запрос.Текст =
"ВЫБРАТЬ
|    Реализация.Номер КАК Номер,
|    Реализация.Контрагент.ИНН КАК ИНН,
|    ЕСТЬNULL(Реализация.Договор.Наименование, """") КАК Договор
|ИЗ
|    Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
|    Реализация.Дата МЕЖДУ &Начало И &Конец";

Значение в таблицу или массив

Когда нужно много значений сразу, не перебирайте выборку вручную:

  • 📋 Запрос.Выполнить().Выгрузить() — таблица значений со всеми колонками;
  • 📌 Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ИНН") — массив значений одного поля;
  • 🔍 Запрос.Выполнить().Пустой() — проверка, что запрос вообще что-то вернул, без чтения строк.

Предопределённые значения и перечисления

Значение перечисления или предопределённого элемента в тексте запроса пишут через ЗНАЧЕНИЕ(): ГДЕ Документ.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийРеализацияТоваров.Товары). В коде модуля то же самое даёт ПредопределенноеЗначение("Перечисление.ВидыОперацийРеализацияТоваров.Товары") — функция доступна и на клиенте.

Имена перечислений в примере условные: точные возьмите из дерева конфигурации или через конструктор запроса.

Получение значений через СКД

В отчётах на системе компоновки данных значение поля получают тремя способами: полем набора данных, вычисляемым полем и программным выполнением схемы.

Поле набора и вычисляемое поле

В наборе данных «Запрос» поле приходит из текста запроса. Реквизит связанного объекта можно не выбирать в запросе: в настройках отчёта пользователь раскроет поле Контрагент и выберет Контрагент.ИНН — СКД сама сделает разыменование.

Вычисляемое поле задают на закладке «Вычисляемые поля» схемы. В колонке «Выражение» пишут выражение на языке выражений СКД:

  • 🧮 Количество * Цена — арифметика по полям набора;
  • 🔗 Контрагент.ИНН — реквизит связанного объекта;
  • 🛡️ ЕСТЬNULL(Сумма, 0) — защита от пустых значений;
  • 🧩 ВЫБОР КОГДА Сумма > 0 ТОГДА "Приход" ИНАЧЕ "Расход" КОНЕЦ — условие.

В выражениях ресурсов на закладке «Ресурсы» работают агрегатные функции СУММА, МАКСИМУМ, КОЛИЧЕСТВО, а также ВычислитьВыражение для расчёта по группировке.

Результат СКД в таблицу значений

Иногда схема уже написана, и её результат нужен в коде, а не на экране. Тогда выводят результат в коллекцию значений:

&НаСервере
Функция ДанныеОтчета(Период)

    Схема = Отчеты.ПродажиПоКонтрагентам.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = Схема.НастройкиПоУмолчанию;
    Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Период);

    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , ,
        Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

    Процессор = Новый ПроцессорКомпоновкиДанных;
    Процессор.Инициализировать(МакетКомпоновки);

    Результат = Новый ТаблицаЗначений;
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
    ПроцессорВывода.УстановитьОбъект(Результат);
    ПроцессорВывода.Вывести(Процессор);

    Возврат Результат;

КонецФункции

Отчёт ПродажиПоКонтрагентам и параметр Период здесь — пример: подставьте свои. Генератор для коллекции значений важен: без него макет строится для табличного документа, и вывод в таблицу не сработает.

Значение ячейки готового отчёта

Чтобы узнать, какое значение стоит за ячейкой, по которой щёлкнул пользователь, используют данные расшифровки. В обработчике ОбработкаРасшифровки формы отчёта приходит параметр Расшифровка — индекс элемента. На сервере по нему получают поля:

&НаСервере
Функция ЗначениеПоляРасшифровки(АдресДанныхРасшифровки, Расшифровка, ИмяПоля)

    ДанныеРасшифровки = ПолучитьИзВременногоХранилища(АдресДанныхРасшифровки);
    Для Каждого Поле Из ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля() Цикл
        Если Поле.Поле = ИмяПоля Тогда
            Возврат Поле.Значение;
        КонецЕсли;
    КонецЦикла;

    Возврат Неопределено;

КонецФункции

Адрес данных расшифровки сохраняют во временное хранилище при формировании отчёта. В типовых отчётах на БСП он уже лежит в реквизите формы — найдите его в модуле формы отчёта по слову «Расшифровк».

Метаданные поля: имя, синоним, тип

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

МетаРеквизит = Метаданные.Справочники.Контрагенты.Реквизиты.Найти("ИНН");
Если МетаРеквизит <> Неопределено Тогда
    Синоним = МетаРеквизит.Синоним;          // «ИНН»
    ТипПоля = МетаРеквизит.Тип;              // ОписаниеТипов
    ДлинаСтроки = ТипПоля.КвалификаторыСтроки.Длина;
КонецЕсли;

Что ещё полезно знать о метаданных:

  • 📁 Стандартные реквизиты (Код, Наименование, Ссылка, ПометкаУдаления) не входят в коллекцию Реквизиты. Они лежат в СтандартныеРеквизиты.
  • 🧾 Реквизиты табличной части ищут глубже: Метаданные.Документы.РеализацияТоваровУслуг.ТабличныеЧасти.Товары.Реквизиты.
  • 🔄 Метаданные объекта по ссылке даёт Ссылка.Метаданные(), а полное имя — Ссылка.Метаданные().ПолноеИмя(), например Справочник.Контрагенты.
  • ✅ Проверка типа значения: ТипЗнч(Значение) = Тип("СправочникСсылка.Контрагенты").

Связка метаданных и динамического обращения позволяет обойти все реквизиты объекта, не зная их заранее:

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

Квадратные скобки Объект["ИНН"] — то же самое, что Объект.ИНН, только имя поля передаётся строкой.

Обращение к реквизитам в коде формы и объекта

Здесь больше всего путаницы, потому что на форме поле, реквизит формы и реквизит объекта — три разные вещи.

Реквизит объекта на форме

На форме документа или справочника данные объекта лежат в основном реквизите Объект. Значение поля читают так:

&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
    ТекущийКонтрагент = Объект.Контрагент;   // ссылка на элемент справочника
    ДатаДокумента = Объект.Дата;
КонецПроцедуры

Собственный реквизит формы, добавленный на закладке «Реквизиты» редактора формы, читается просто по имени: СуммаИтого или ЭтаФорма.СуммаИтого.

Текущая строка табличной части

&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    Количество = ТекущиеДанные.Количество;
КонецПроцедуры

Проверка на Неопределено обязательна: в пустой таблице текущей строки нет.

Реквизит связанного объекта на клиенте

Объект.Контрагент.ИНН в клиентской процедуре не сработает: на клиенте ссылка не даёт доступа к реквизитам объекта. Нужен серверный вызов:

&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
    ИНН = ИННКонтрагентаНаСервере(Объект.Контрагент);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ИННКонтрагентаНаСервере(Контрагент)
    Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Контрагент, "ИНН");
КонецФункции

&НаСервереБезКонтекста не передаёт на сервер данные формы, поэтому вызов быстрее, чем &НаСервере.

Функции БСП для чтения по ссылке

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

ФункцияЧто возвращает
ЗначениеРеквизитаОбъекта(Ссылка, "ИНН")Значение одного реквизита
ЗначенияРеквизитовОбъекта(Ссылка, "ИНН, КПП")Структуру с ключами ИНН и КПП
ЗначениеРеквизитаОбъектов(МассивСсылок, "ИНН")Соответствие «ссылка → значение»

Внутри них обычный запрос, так что читается только нужное поле, а не объект целиком.

Объект в серверном коде

В модуле объекта и в серверных процедурах после Ссылка.ПолучитьОбъект() значения читаются напрямую: ДокОбъект.Контрагент, ДокОбъект.Товары[0].Количество. Индекс строки табличной части начинается с нуля. Найти строки по значению поля помогает ДокОбъект.Товары.НайтиСтроки(Новый Структура("Номенклатура", Номенклатура)) — метод возвращает массив строк.

Скорость чтения и обработка ошибок

Что замедляет чтение

  • 🐢 Обращение Ссылка.Реквизит на сервере читает данные объекта, а не одно поле. В цикле по тысячам ссылок это заметно тормозит.
  • 🔁 Запрос внутри цикла. Соберите ссылки в массив и передайте одним параметром: ГДЕ Контрагенты.Ссылка В (&Ссылки).
  • 🧩 Разыменование поля составного типа в запросе. Если Регистратор может быть десятью видами документов, Регистратор.Дата даст десять соединений. Уточните тип: ВЫРАЗИТЬ(Регистратор КАК Документ.РеализацияТоваровУслуг).Дата.
  • 📦 Много серверных вызовов из одной клиентской процедуры. Объедините их в одну серверную функцию, которая вернёт структуру.

Типовые ошибки при чтении

Диагностика: выберите симптом

Защищённая обёртка для обращения к полю, тип которого заранее неизвестен:

Если ЗначениеЗаполнено(Значение)
    И ТипЗнч(Значение) = Тип("СправочникСсылка.Контрагенты") Тогда
    ИНН = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Значение, "ИНН");
Иначе
    ИНН = "";
КонецЕсли;

Типы данных и форматы полученных значений

Значение приходит в своём типе, а показать или выгрузить его часто нужно строкой.

Тип значенияКак превратить в строкуПример результата
ДатаФормат(Дата, "ДФ=dd.MM.yyyy")07.10.2026
ЧислоФормат(Сумма, "ЧДЦ=2; ЧГ=0")15400.50
БулевоФормат(Флаг, "БЛ=Нет; БИ=Да")Да
СсылкаСтрока(Ссылка) или поле ПРЕДСТАВЛЕНИЕ() в запросеООО «Ромашка»
ПеречислениеСтрока(Значение)Синоним значения

Особенности, на которых чаще всего ошибаются:

  • 🔢 Число со строкой без формата склеивается с пробелом-разделителем разрядов: «15 400,5». Для выгрузки в файл используйте Формат(Сумма, "ЧГ=0").
  • 📅 Пустая дата — это '00010101', а не Неопределено. Проверяйте её через ЗначениеЗаполнено(Дата).
  • 🔤 Строка неограниченной длины в запросе не участвует в сравнении и группировке. Приведите её: ВЫРАЗИТЬ(Комментарий КАК СТРОКА(100)).
  • 🧷 Пустая ссылка не равна Неопределено. Сравнивайте с Справочники.Контрагенты.ПустаяСсылка() или используйте ЗначениеЗаполнено.
  • 📎 Поле типа ХранилищеЗначения отдаёт данные только через метод Получить(): Картинка = Объект.Файл.Получить().

Представление ссылки в запросе лучше брать через ПРЕДСТАВЛЕНИЕ(Контрагент): так в выборку сразу попадёт строка, и на клиенте не понадобится лишний вызов сервера.

Частые вопросы

Как получить значение поля в 1С, если имя поля хранится в переменной?
Используйте квадратные скобки: Объект[ИмяПоля]. Для структуры и строки таблицы значений синтаксис такой же. Если поля нет, будет ошибка, поэтому заранее проверьте его через метаданные.
Чем ЗначениеРеквизитаОбъекта лучше обращения через точку?
Функция БСП выполняет запрос и читает только указанное поле. Обращение через точку на сервере читает данные объекта. На одном объекте разницы почти нет, на тысячах — заметная.
Можно ли получить значение поля из формы другого открытого окна?
Можно, если у вас есть ссылка на эту форму, например переданная при открытии или полученная через параметр ВладелецФормы. Тогда читайте Форма.Объект.Реквизит. Чужую форму без ссылки на неё не найти.
Как прочитать значение реквизита в запросе для нескольких документов разных видов?
Если поле составного типа, приведите его через ВЫРАЗИТЬ к нужному виду или соберите данные объединением запросов ОБЪЕДИНИТЬ ВСЕ по каждому виду документа.
Почему значение поля пустое, хотя в форме оно заполнено?
Скорее всего, объект не записан: запрос и функции по ссылке читают базу, а не форму. Запишите объект или читайте значение из реквизита формы Объект.