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

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

При разработке на управляемых формах 1С (УФ) программисты часто сталкиваются с необходимостью обработать данные текущей строки таблицы именно на стороне сервера. Основная сложность заключается в том, что привычное свойство ТекущиеДанные доступно только в клиентском контексте. В этой статье мы подробно разберем, как правильно передать управление на сервер и получить доступ к нужной строке, используя идентификаторы и особенности коллекций данных формы.

Понимание разницы между визуальным элементом и данными

Для начала проанализируем архитектуру управляемой формы. На форме всегда присутствуют два связанных объекта:

  1. Реквизит формы (например, с типом ДанныеФормыКоллекция) — это сами данные, которые хранятся на сервере и отображаются на клиенте.
  2. Элемент формы (тип ТаблицаФормы) — это визуальное представление данных, которое отвечает за отображение, выделение строк и взаимодействие с пользователем.

Разберем ситуацию: когда пользователь выбирает строку в таблице, визуальный элемент "знает", какая строка активна. Это значение хранится в свойстве Элементы.ИмяВашейТаблицы.ТекущаяСтрока. Важно понимать, что это свойство возвращает не саму строку, а её внутренний идентификатор (ID) — уникальное числовое значение.

Способ 1: Использование метода НайтиПоИдентификатору на сервере

Этот способ является наиболее правильным и эффективным. Мы используем идентификатор строки, который доступен на сервере через коллекцию элементов формы, и находим по нему данные в реквизите. Рассмотрим пример кода, где ТЗ — это имя реквизита формы (ваша таблица), а Элементы.ТЗ — визуальный элемент.


&НаСервере
Процедура ОбработатьТекущуюСтрокуНаСервере()
    
    // Получаем идентификатор текущей строки из элемента формы
    ИдентификаторСтроки = Элементы.ТЗ.ТекущаяСтрока;
    
    Если ИдентификаторСтроки <> Неопределено Тогда
        // Находим строку в коллекции данных формы по её ID
        ТекущаяСтрокаДанных = ТЗ.НайтиПоИдентификатору(ИдентификаторСтроки);
        
        Если ТекущаяСтрокаДанных <> Неопределено Тогда
            // Теперь нам доступны все колонки строки
            Сообщить("Выбрана строка с реквизитом: " + ТекущаяСтрокаДанных.ИмяКолонки);
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Проанализируем этот код: метод НайтиПоИдентификатору ищет строку именно по внутреннему ID, который не меняется при сортировке или фильтрации таблицы. Это принципиальное отличие от индекса строки, который может измениться, если пользователь нажмет на заголовок колонки для сортировки.

Способ 2: Передача идентификатора в качестве параметра

Хорошей практикой считается явная передача параметров при вызове серверных процедур с клиента. Это делает код более читаемым и позволяет избежать лишних обращений к объекту Элементы на сервере, что положительно сказывается на чистоте кода. Для реализации классических сценариев на управляемой форме, таких как обновление связанных списков при смене строки, можно использовать готовый механизм для связывания главной и подчиненной таблиц.


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

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

Выясним причину, почему это работает: объект Заказы на сервере имеет тип ДанныеФормыКоллекция. У этого типа есть встроенный метод НайтиПоИдентификатору(), который позволяет мгновенно получить доступ к нужной строке памяти сервера. При решении более сложных задач, когда требуется не просто найти строку, а динамически сформировать весь интерфейс, будет полезен инструмент для программного вывода произвольной таблицы значений на управляемую форму.

Ловушка при использовании РеквизитФормыВЗначение

Рассмотрим важный нюанс, который часто приводит к ошибкам. Если вы решите преобразовать данные формы в обычную таблицу значений с помощью метода РеквизитФормыВЗначение("Заказы"), вы потеряете внутренние идентификаторы строк.

В обычной ТаблицеЗначений нет метода НайтиПоИдентификатору. Если вы планируете сложную обработку данных через выгрузку в объект ТаблицаЗначений, вам придется заранее позаботиться о наличии уникальной колонки (например, НомерСтроки или собственный УникальныйИдентификатор), чтобы найти соответствие. Посмотрим на пример, как делать не рекомендуется, если можно обойтись работой с данными формы:


&НаСервере
Процедура ОпасныйМетод()
    
    // ТЗ_Объект - это уже не ДанныеФормыКоллекция, а обычная ТаблицаЗначений
    ТЗ_Объект = РеквизитФормыВЗначение("Заказы"); 
    
    // ОШИБКА: У ТЗ_Объект нет метода НайтиПоИдентификатору!
    // Строка = ТЗ_Объект.НайтиПоИдентификатору(Элементы.Заказы.ТекущаяСтрока); 
    
КонецПроцедуры

Совет: старайтесь изменять данные напрямую в реквизите формы (тип ДанныеФормыКоллекция), тогда платформа автоматически синхронизирует изменения с интерфейсом пользователя без полной перезагрузки таблицы.

Работа с множественным выделением строк

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

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


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

Резюме и рекомендации

Подведем итог нашему разбору. Для эффективной работы с текущей строкой на сервере придерживайтесь следующих правил:

Соблюдение этих правил позволит вам писать быстрый и стабильный код для управляемого интерфейса 1С, избегая лишних конвертаций данных и ошибок контекста.

← На главную