Как получить данные текущей строки таблицы на управляемой форме 1С 8.3?

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

При переводе конфигураций или внешних обработок с обычных форм на управляемые разработчики часто сталкиваются с ошибкой: «Ошибка при получении значения атрибута контекста (ТекущиеДанные): Текущие данные таблицы недоступны на сервере». Разберем причины возникновения этой ошибки, выясним принципы работы с табличными частями в тонком клиенте и рассмотрим несколько надежных способов передачи данных текущей строки на сервер.

Почему возникает ошибка при обращении к ТекущиеДанные на сервере?

В обычных формах (толстый клиент) весь контекст формы и элементы управления были доступны в любой процедуре без разделения. В управляемых формах действует четкая клиент-серверная архитектура:

  1. Элементы формы (коллекция Элементы) существуют и управляются в контексте клиента. Свойство ТекущиеДанные таблицы формы указывает на строку, на которой в данный момент установлен курсор пользователя. Сервер не имеет информации о фокусе ввода и выделенных визуальных элементах, поэтому обращение к свойству Элементы.ИмяТаблицы.ТекущиеДанные на сервере вызывает исключение.
  2. Данные формы (объект Объект или иной реквизит формы) доступны и на клиенте, и на сервере. Однако коллекция данных формы (например, Объект.ВходящиеПартии) содержит только строки таблицы, но не содержит понятия «текущий выделенный пользователем элемент».
  3. Несериализуемость типов данных: Значение, возвращаемое свойством ТекущиеДанные на клиенте, имеет тип ДанныеФормыЭлементКоллекции. Этот объект является мутабельным и не может быть напрямую передан в качестве параметра в серверную процедуру или функцию.

Рассмотрим рабочие способы правильной организации кода при работе с текущей строкой.

Способ 1. Передача идентификатора строки и поиск через НайтиПоИдентификатору

Каждая строка коллекции данных формы имеет уникальный числовой идентификатор, который сохраняется в течение жизни формы и не зависит от сортировок, фильтров или номера строки. Мы можем получить этот идентификатор на клиенте, передать его на сервер и найти соответствующую строку через метод НайтиПоИдентификатору().

Посмотрим на пример реализации:


&НаКлиенте
Процедура ОбработатьВыбраннуюСтроку(Команда)
    
    // Получаем текущие данные на клиенте
    ТекДанные = Элементы.ВходящиеПартии.ТекущиеДанные;
    
    // Проверяем, выбрана ли строка пользователем
    Если ТекДанные = Неопределено Тогда
        ПоказатьПредупреждение(, "Не выбрана строка для обработки!");
        Возврат;
    КонецЕсли;
    
    // Передаем идентификатор строки на сервер
    ИдентификаторСтроки = ТекДанные.ПолучитьИдентификатор();
    ОбработатьСтрокуНаСервере(ИдентификаторСтроки);
    
КонецПроцедуры

&НаСервере
Процедура ОбработатьСтрокуНаСервере(ИдентификаторСтроки)
    
    // Находим строку в данных формы по идентификатору
    СтрокаТЧ = Объект.ВходящиеПартии.НайтиПоИдентификатору(ИдентификаторСтроки);
    
    Если СтрокаТЧ <> Неопределено Тогда
        // Выполняем необходимые действия со строкой
        СтрокаТЧ.Площадка = "Основная площадка";
    КонецЕсли;
    
КонецПроцедуры

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


&НаКлиенте
Процедура ОбработатьСтрокуАльтернативно(Команда)
    
    ИдентификаторСтроки = Элементы.ВходящиеПартии.ТекущаяСтрока;
    
    Если ИдентификаторСтроки = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    ОбработатьСтрокуНаСервере(ИдентификаторСтроки);
    
КонецПроцедуры

Способ 2. Передача структуры параметров с клиента на сервер (рекомендуемый)

Если на сервере не требуется модифицировать саму табличную часть формы, а нужно лишь прочитать реквизиты выбранной строки (например, для формирования запроса к веб-сервису, генерации XDTO-пакета или проведения проверок), оптимальнее всего собрать структуру значений на клиенте и передать ее на сервер.

Такой подход избавляет сервер от необходимости повторно искать строку в коллекции формы и снижает объем передаваемых данных.

Разберем пример формирования параметров:


&НаКлиенте
Процедура ОтправитьВЕТИС(Команда)
    
    ТекДанные = Элементы.ВходящиеПартии.ТекущиеДанные;
    Если ТекДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Формируем структуру с необходимыми полями
    ПараметрыЗапроса = Новый Структура;
    ПараметрыЗапроса.Вставить("UUIDПлощадкиОтправителя", ТекДанные.UUIDПлощадкиОтправителя);
    ПараметрыЗапроса.Вставить("UUIDХСОтправителя",       ТекДанные.UUIDХСОтправителя);
    
    ОтправитьДанныеНаСервере(ПараметрыЗапроса);
    
КонецПроцедуры

&НаСервере
Процедура ОтправитьДанныеНаСервере(ПараметрыЗапроса)
    
    // Используем переданные параметры без обращения к элементам формы
    UUIDПлощадки = ПараметрыЗапроса.UUIDПлощадкиОтправителя;
    UUIDХС       = ПараметрыЗапроса.UUIDХСОтправителя;
    
    // Логика работы с фабрикой XDTO или внешними сервисами
    
КонецПроцедуры

Способ 3. Работа со множественным выбором строк

Если в таблице формы включено свойство МножественныйВыбор = Истина, пользователь может выделить сразу несколько строк (через клавиши Shift или Ctrl). Свойство ТекущиеДанные в таком случае вернет только одну активную строку. Чтобы обработать весь набор выделенных строк, используем свойство ВыделенныеСтроки.

Проанализируем пример групповой обработки:


&НаКлиенте
Процедура ОбработатьВыделенныеСтроки(Команда)
    
    МассивИдентификаторов = Элементы.ВходящиеПартии.ВыделенныеСтроки;
    
    Если МассивИдентификаторов.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    ОбработатьМассивСтрокНаСервере(МассивИдентификаторов);
    
КонецПроцедуры

&НаСервере
Процедура ОбработатьМассивСтрокНаСервере(МассивИдентификаторов)
    
    Для Каждого Идентификатор Из МассивИдентификаторов Цикл
        СтрокаТЧ = Объект.ВходящиеПартии.НайтиПоИдентификатору(Идентификатор);
        Если СтрокаТЧ <> Неопределено Тогда
            // Обработка каждой найденной строки
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Важные рекомендации и предотвращение ошибок

  1. Всегда проверяйте результат на Неопределено: Если в таблице нет строк или курсор не установлен, обращение к Элементы.ИмяТаблицы.ТекущиеДанные вернет Неопределено. Попытка прочитать свойство (например, ТекДанные.Площадка) без предварительной проверки вызовет ошибку «Поле не является значением объектного типа».
  2. Не используйте номер строки: Номер строки (НомерСтроки) или индекс в массиве коллекции могут измениться при установке пользовательских отборов или сортировок колонок. Поиск по идентификатору через НайтиПоИдентификатору() гарантирует нахождение именно той строки, которую выбрал пользователь.
  3. Общие модули без контекста формы: Если логика выносится в общий серверный модуль, передавайте туда только сериализуемые типы данных (структуры, массивы, примитивные типы), так как контекст формы в общих модулях недоступен.
← На главную