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