Как правильно получить текущую строку и данные из динамического списка в 1С 8.3?

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

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

Разбираем основные понятия: ТекущаяСтрока и ТекущиеДанные

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

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

Рассмотрим подробнее их использование на примере. Допустим, у нас есть список заказов покупателей с именем Список.

Если нам нужно получить только ссылку на выбранный документ, мы используем следующий код:


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

Однако, если нам нужно получить значение какого-либо реквизита, отображаемого в списке (например, сумму или контрагента), без обращения к серверу, мы используем ТекущиеДанные:


&НаКлиенте
Процедура ПолучитьДанныеСтроки()
    ДанныеСтроки = Элементы.Список.ТекущиеДанные;
    Если ДанныеСтроки <> Неопределено Тогда
        СуммаДокумента = ДанныеСтроки.СуммаДокумента;
        Контрагент = ДанныеСтроки.Контрагент;
        // Работаем с данными прямо на клиенте
    КонецЕсли;
КонецПроцедуры

Почему возникает ошибка или возвращается Неопределено?

Выясним причины, по которым свойство ТекущиеДанные может не возвращать ожидаемую информацию. Проанализируем типичные ситуации:

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

Разберем по шагам работу в событии ПриАктивизацииСтроки

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


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    // Элемент - это и есть наша таблица формы (Элементы.Список)
    Данные = Элемент.ТекущиеДанные;
    
    Если Данные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Пример: обновление связанной информации на форме
    ТекущийНомерЗаказа = Данные.Номер;
КонецПроцедуры

Важный нюанс: Событие ПриАктивизацииСтроки может вызываться платформой несколько раз, в том числе при инициализации формы. Поэтому проверка на Неопределено обязательна, чтобы избежать аварийного завершения работы программы.

Как получить данные на сервере, зная текущую строку?

Часто задача звучит так: "Пользователь нажал кнопку, нам нужно взять текущую строку и выполнить с ней сложные вычисления на сервере". Посмотрим, как организовать передачу данных правильно. Нам нужно передать ТекущаяСтрока (ссылку) в серверную процедуру.

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


&НаКлиенте
Процедура КомандаОбработатьСтроку(Команда)
    
    СсылкаНаОбъект = Элементы.Список.ТекущаяСтрока;
    
    Если СсылкаНаОбъект <> Неопределено И ТипЗнч(СсылкаНаОбъект) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        ОбработатьНаСервере(СсылкаНаОбъект);
    Иначе
        Сообщить("Пожалуйста, выберите корректный документ в списке.");
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура ОбработатьНаСервере(ПереданнаяСсылка)
    // На сервере мы получаем объект по ссылке и выполняем действия
    ОбъектДокумент = ПереданнаяСсылка.ПолучитьОбъект();
    // ... логика обработки ...
КонецПроцедуры

Сценарий с множественным выделением

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

Чтобы получить все выделенные строки, нужно использовать коллекцию ВыделенныеСтроки:


&НаКлиенте
Процедура ОбработатьВсеВыделенные()
    МассивСтрок = Элементы.Список.ВыделенныеСтроки;
    
    Для Каждого ИдентификаторСтроки Из МассивСтрок Цикл
        // ИдентификаторСтроки в дин. списке - это Ссылка
        Сообщить("Обрабатываем: " + ИдентификаторСтроки);
    КонецЦикла;
КонецПроцедуры

Практические советы и рекомендации

1. Использование пути к данным: Если вам нужно просто отображать реквизит текущей строки в отдельном поле на форме (например, "Комментарий" текущего документа под списком), не обязательно писать код. Можно создать поле формы и в свойстве ПутьКДанным указать Элементы.Список.ТекущиеДанные.Комментарий. Платформа сама будет обновлять это поле при перемещении по списку.

2. Оптимизация: Не злоупотребляйте обращением к серверу в событии ПриАктивизацииСтроки. Если вам нужно просто показать данные, которые уже есть в списке, используйте ТекущиеДанные на клиенте. Каждый серверный вызов при перемещении курсора будет создавать "фризы" (задержки) в интерфейсе пользователя.

3. Проверка типа: В динамических списках, которые объединяют разные типы данных (например, список "Мои задачи", где могут быть и задачи, и документы), всегда проверяйте тип значения ТекущаяСтрока перед передачей в специфические функции.

Таким образом, мы проанализировали основные механизмы взаимодействия с динамическим списком. Правильный выбор между ТекущиеДанные и ТекущаяСтрока, а также понимание контекста выполнения кода (Клиент/Сервер) позволяют создавать быстрые и надежные интерфейсы в системе 1С:Предприятие.

← На главную