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