При работе с управляемыми формами начинающие разработчики часто сталкиваются с ситуацией: форма выбора справочника возвращает массив элементов типа СправочникСсылка, но в отладчике или на форме видно только текстовое наименование объекта. При попытке обратиться к реквизитам выбранных объектов на клиенте возникают сложности или ошибки.
Рассмотрим подробно, почему платформенные ссылки ведут себя подобным образом на клиенте, и проанализируем основные способы получения данных из СправочникСсылка.
Выясним причину такого поведения платформы 1С:Предприятие. В тонком и веб-клиенте объект типа СправочникСсылка является «облегченным». Он содержит только Уникальный Идентификатор (GUID) и текстовое представление (как правило, наименование элемента). Реквизиты справочника не загружаются в память клиентского приложения ради экономии трафика и повышения производительности.
По этой причине прямое обращение к полям объекта «через точку» (например, Ссылка.Артикул) на клиенте невозможно. Для получения данных необходимо передать ссылку на сервер и прочитать реквизиты в серверном контексте.
Если из формы выбора вернулся массив ссылок, обращаться к серверу отдельно за каждым реквизитом каждого элемента крайне неэффективно. Лучше всего передать весь массив в один серверный метод и выполнить запрос к базе данных.
Разберем пример серверной процедуры, принимающей массив ссылок:
&НаСервереБезКонтекста
Функция ПолучитьДанныеЭлементовНаСервере(МассивСсылок)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Артикул КАК Артикул,
| Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В (&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Возвратить Запрос.Выполнить().Выгрузить();
КонецФункции
Этот подход гарантирует минимальное количество обращений к СУБД и оптимальную скорость работы приложения.
Если в конфигурации используется Библиотека Стандартных Подсистем, для получения одного или нескольких реквизитов объекта по ссылке не обязательно писать собственный запрос. Можно применить готовые функции БСП.
Для вызова с клиента прямо в клиентском коде разберем пример вызова:
// Получение одного реквизита на клиенте
ЗначениеАртикула = ОбщегоНазначенияВызовСервера.ЗначениеРеквизитаОбъекта(ВыбраннаяСсылка, "Артикул");
// Получение нескольких реквизитов в виде структуры
СтруктураРеквизитов = ОбщегоНазначенияВызовСервера.ЗначенияРеквизитовОбъекта(ВыбраннаяСсылка, "Артикул, ВидНоменклатуры");
Если вы уже находитесь в серверном контексте, используйте аналогичный модуль ОбщегоНазначения:
Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ВыбраннаяСсылка, "Артикул, Код");
На сервере обращение к реквизитам через ссылку (например, ТекСсылка.Наименование) синтаксически разрешено. Однако проанализируем нюанс производительности: при первом обращении «через точку» платформа считывает из базы данных весь объект целиком, включая все его табличные части и реквизиты.
Поэтому обращение «через точку» допустимо только для единичных вызовов. Если вы работаете с массивом ссылок или с большим объемом данных, всегда следует отдавать предпочтение языку запросов или функциям БСП.
Для создания собственных серверных методов в модуле формы всегда используйте директиву &НаСервереБезКонтекста. Это исключает передачу всей формы по сети и передает только сам массив ссылок:
&НаКлиенте
Процедура ОбработкаВыбора(РезультатВыбора, ИсточникВыбора)
Если ТипЗнч(РезультатВыбора) = Тип("Массив") Тогда
ДанныеОбъектов = ПрочитатьДанныеНаСервере(РезультатВыбора);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПрочитатьДанныеНаСервере(Знач МассивСсылок)
// Обработка массива ссылок на сервере
// ...
КонецФункции
Чтобы избежать повторного серверного вызова после закрытия формы выбора, проанализируем альтернативное решение: переопределение логики самой формы выбора.
В форме выбора справочника в обработчике выбора элемента можно считывать необходимые реквизиты заранее и возвращать не просто СправочникСсылка, а структуру с готовыми данными. Это избавляет вызывающую форму от необходимости делать дополнительный вызов сервера для чтения реквизитов.