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

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

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

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

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

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

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

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


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

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


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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

← На главную