В процессе разработки на платформе 1С:Предприятие 8.3 в режиме управляемого приложения одной из самых частых задач является программная обработка данных, выбранных пользователем в динамическом списке. Несмотря на кажущуюся простоту, начинающие разработчики часто сталкиваются с ситуацией, когда попытка получить данные возвращает Неопределено или приводит к ошибкам контекста. В этой статье мы подробно разберем, как правильно извлекать информацию из списков, в чем разница между идентификатором строки и самими данными, и как избежать типичных ошибок.
Для начала проанализируем, какие инструменты предоставляет нам платформа для работы с элементами формы, отображающими динамические списки. У объекта типа ТаблицаФормы (которым является наш список на форме) есть два ключевых свойства, которые часто путают:
ДанныеФормыСтруктура), содержащая значения всех полей, которые в данный момент отображаются в строке списка на клиенте.Рассмотрим подробнее их использование на примере. Допустим, у нас есть список заказов покупателей с именем Список.
Если нам нужно получить только ссылку на выбранный документ, мы используем следующий код. Подобный механизм получения ссылки лежит в основе инструментов для выборочного удаления организаций и связанных с ними данных:
&НаКлиенте
Процедура ПолучитьСсылку()
ВыбраннаяСсылка = Элементы.Список.ТекущаяСтрока;
Если ВыбраннаяСсылка <> Неопределено Тогда
ПоказатьОповещениеПользователя("Выбрана ссылка: " + ВыбраннаяСсылка);
КонецЕсли;
КонецПроцедуры
Однако, если нам нужно получить значение какого-либо реквизита, отображаемого в списке (например, сумму или контрагента), без обращения к серверу, мы используем ТекущиеДанные:
&НаКлиенте
Процедура ПолучитьДанныеСтроки()
ДанныеСтроки = Элементы.Список.ТекущиеДанные;
Если ДанныеСтроки <> Неопределено Тогда
СуммаДокумента = ДанныеСтроки.СуммаДокумента;
Контрагент = ДанныеСтроки.Контрагент;
// Работаем с данными прямо на клиенте
КонецЕсли;
КонецПроцедуры
Выясним причины, по которым свойство ТекущиеДанные может не возвращать ожидаемую информацию. Проанализируем типичные ситуации:
ТекущиеДанные доступно только на клиенте. Если вы попытаетесь обратиться к Элементы.Список.ТекущиеДанные внутри процедуры с директивой &НаСервере, платформа вернет ошибку или пустой результат, так как визуальное состояние формы и выделение строк не передаются на сервер в таком виде.Неопределено.ТекущиеДанные попадают только те поля, которые включены в состав запроса динамического списка и (в некоторых случаях) доступны для отображения. Если поля нет в схеме запроса, вы не сможете получить его из текущих данных.Наиболее часто получение текущей строки требуется в обработчике события ПриАктивизацииСтроки. Это событие срабатывает каждый раз, когда пользователь перемещает курсор по списку. Посмотрим на правильную реализацию этого обработчика. Если же требуется автоматизировать сбор информации из интерфейса без написания кода, применяется платформа для создания программных роботов OneRPA:
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
// Элемент - это и есть наша таблица формы (Элементы.Список)
Данные = Элемент.ТекущиеДанные;
Если Данные = Неопределено Тогда
Возврат;
КонецЕсли;
// Пример: обновление связанной информации на форме
ТекущийНомерЗаказа = Данные.Номер;
КонецПроцедуры
Важный нюанс: Событие ПриАктивизацииСтроки может вызываться платформой несколько раз, в том числе при инициализации формы. Поэтому проверка на Неопределено обязательна, чтобы избежать аварийного завершения работы программы.
Часто задача звучит так: "Пользователь нажал кнопку, нам нужно взять текущую строку и выполнить с ней сложные вычисления на сервере". Посмотрим, как организовать передачу данных правильно. Нам нужно передать ТекущаяСтрока (ссылку) в серверную процедуру.
Рассмотрим пример реализации:
&НаКлиенте
Процедура КомандаОбработатьСтроку(Команда)
СсылкаНаОбъект = Элементы.Список.ТекущаяСтрока;
Если СсылкаНаОбъект <> Неопределено И ТипЗнч(СсылкаНаОбъект) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
ОбработатьНаСервере(СсылкаНаОбъект);
Иначе
Сообщить("Пожалуйста, выберите корректный документ в списке.");
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбработатьНаСервере(ПереданнаяСсылка)
// На сервере мы получаем объект по ссылке и выполняем действия
ОбъектДокумент = ПереданнаяСсылка.ПолучитьОбъект();
// ... логика обработки ...
КонецПроцедуры
Проанализируем ситуацию, когда в динамическом списке разрешено множественным выделением строк (свойство таблицы РежимВыделения = РежимВыделенияТаблицы.Множественный). В этом случае ТекущаяСтрока вернет только ту строку, на которой стоит фокус (пунктирная рамка), но пользователь мог выделить еще десять других строк.
Чтобы получить все выделенные строки, нужно использовать коллекцию ВыделенныеСтроки:
&НаКлиенте
Процедура ОбработатьВсеВыделенные()
МассивСтрок = Элементы.Список.ВыделенныеСтроки;
Для Каждого ИдентификаторСтроки Из МассивСтрок Цикл
// ИдентификаторСтроки в дин. списке - это Ссылка
Сообщить("Обрабатываем: " + ИдентификаторСтроки);
КонецЦикла;
КонецПроцедуры
1. Использование пути к данным: Если вам нужно просто отображать реквизит текущей строки в отдельном поле на форме (например, "Комментарий" текущего документа под списком), не обязательно писать код. Можно создать поле формы и в свойстве ПутьКДанным указать Элементы.Список.ТекущиеДанные.Комментарий. Платформа сама будет обновлять это поле при перемещении по списку.
2. Оптимизация: Не злоупотребляйте обращением к серверу в событии ПриАктивизацииСтроки. Если вам нужно просто показать данные, которые уже есть в списке, используйте ТекущиеДанные на клиенте. Каждый серверный вызов при перемещении курсора будет создавать "фризы" (задержки) в интерфейсе пользователя.
3. Проверка типа: В динамических списках, которые объединяют разные типы данных (например, список "Мои задачи", где могут быть и задачи, и документы), всегда проверяйте тип значения ТекущаяСтрока перед передачей в специфические функции.
Таким образом, мы проанализировали основные механизмы взаимодействия с динамическим списком. Правильный выбор между ТекущиеДанные и ТекущаяСтрока, а также понимание контекста выполнения кода (Клиент/Сервер) позволяют создавать быстрые и надежные интерфейсы в системе 1С:Предприятие.