В процессе разработки на платформе 1С:Предприятие 8.3, особенно при работе с расширениями конфигурации в типовых решениях вроде УТ 11, ERP или КА, программисты часто сталкиваются с необъяснимым поведением элементов формы. Одна из таких проблем — ситуация, когда при попытке получить выделенные пользователем строки динамического списка через свойство ВыделенныеСтроки, система возвращает пустой массив (количество элементов равно 0), хотя визуально в интерфейсе строки выбраны.
В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем механизмы работы динамических списков и рассмотрим несколько способов решения проблемы, начиная от простых настроек интерфейса и заканчивая программными методами исправления ошибок расширений.
Проанализируем наиболее частую причину, которая встречается именно при использовании расширений. Когда мы заимствуем форму из основной конфигурации в расширение, платформа создает копию метаданных этой формы. Если в основной конфигурации форма была существенно изменена (например, в результате обновления конфигурации), или если при самом процессе заимствования произошел внутренний сбой платформы, связь между программным объектом Элементы.Список и его визуальным представлением может нарушиться.
Рассмотрим решение: как показывает практика многих разработчиков, самым быстрым способом исправить это является полное удаление формы из расширения и ее повторное добавление. Рассмотрим этот процесс по шагам:
Этот метод кажется радикальным, но он «оживляет» внутренние индексы платформы и восстанавливает корректную работу коллекции ВыделенныеСтроки.
Выясним техническую сторону работы элемента «Таблица». Чтобы платформа вообще позволяла собирать идентификаторы строк в массив, у элемента формы типа Таблица (который отображает динамический список) должно быть активно свойство Множественный выбор.
Если это свойство отключено, свойство ВыделенныеСтроки может вести себя непредсказуемо. В некоторых версиях платформы оно может возвращать пустую коллекцию, подразумевая, что для работы с единственной строкой нужно использовать ТекущаяСтрока.
Проанализируем ситуацию: в расширении свойства элементов иногда сбрасываются в значения по умолчанию. Проверьте в палитре свойств динамического списка, установлена ли галочка «Множественный выбор». Без нее пользователь не сможет выделить несколько строк через Shift или Ctrl, и массив будет пустым.
Важно помнить критическое правило разработки на управляемых формах: свойство ВыделенныеСтроки доступно только на клиенте. Посмотрим на типичную ошибку начинающих разработчиков, когда обращение к элементам формы происходит в серверной процедуре:
&НаСервере
Процедура ОбработатьВыборНаСервере()
// ТАК ДЕЛАТЬ НЕЛЬЗЯ:
МассивСтрок = Элементы.Список.ВыделенныеСтроки;
// На сервере эта коллекция будет пустой или недоступной
КонецПроцедуры
Разберем, как правильно организовать передачу данных. Мы должны собрать идентификаторы строк на клиенте, а затем передать их параметром в серверный метод. Рассмотрим пример правильного кода:
&НаКлиенте
Процедура МояКоманда(Команда)
МассивВыделенныхСтрок = Элементы.Список.ВыделенныеСтроки;
Если МассивВыделенныхСтрок.Количество() = 0 Тогда
Сообщить("Ничего не выбрано!");
Возврат;
КонецЕсли;
ОбработатьДанныеНаСервере(МассивВыделенныхСтрок);
КонецПроцедуры
&НаСервере
Процедура ОбработатьДанныеНаСервере(МассивИдентификаторов)
Для Каждого Идентификатор Из МассивИдентификаторов Цикл
// Здесь мы уже работаем с данными
ДанныеСтроки = Элементы.Список.ДанныеСтроки(Идентификатор);
// ... логика обработки ...
КонецЦикла;
КонецПроцедуры
Форма подбора в типовых решениях (например, ПодборТоваровВДокументЗакупки) является крайне сложной. В ней часто используется не один, а несколько динамических списков, которые переключаются программно в зависимости от режима (поиск, иерархия, остатки).
Выясним причину возможной путаницы: в коде вы можете обращаться к Элементы.СписокРасширенныйПоискНоменклатура, в то время как в данный момент на форме активен другой список, например, Элементы.СписокНоменклатура. Если фокус внимания пользователя (и данные) находятся в одном списке, а команда пытается прочитать данные из другого, массив закономерно будет пустым.
Проанализируем ситуацию через отладчик. Вместо конкретного имени списка попробуйте использовать свойство формы ТекущийЭлемент:
&НаКлиенте
Процедура ПроверитьАктивныйСписок()
Элемент = ЭтаФорма.ТекущийЭлемент;
Если ТипЗнч(Элемент) = Тип("ТаблицаФормы") Тогда
Массив = Элемент.ВыделенныеСтроки;
Сообщить("Выбрано строк: " + Массив.Количество());
КонецЕсли;
КонецПроцедуры
Если вы создаете свою команду и размещаете кнопку в командной панели списка, 1С предоставляет встроенный механизм передачи выделенных строк. Рассмотрим использование параметра ПараметрКоманды.
Когда кнопка привязана к таблице, в обработчик команды автоматически передается массив идентификаторов выделенных строк. Проанализируем пример:
&НаКлиенте
Процедура ВыполнитьДействие(Команда)
// ПараметрКоманды содержит массив ссылок/идентификаторов выделенных строк,
// если кнопка находится в командной панели списка.
Если ТипЗнч(Команда.ПараметрКоманды) = Тип("Массив") Тогда
// Работаем напрямую с этим массивом
КонецЕсли;
КонецПроцедуры
Использование этого параметра часто помогает обойти баги, связанные с прямым обращением к Элементы.ИмяСписка.ВыделенныеСтроки в расширениях.
Подводя итог, если вы столкнулись с пустым массивом ВыделенныеСтроки, рекомендуем придерживаться следующего алгоритма проверки:
&НаКлиенте)./ClearCache.Помните, что в динамических списках массив выделенных строк содержит идентификаторы. Если у списка задана основная таблица, это будут ссылки (например, СправочникСсылка.Номенклатура). Если основной таблицы нет, это будут внутренние ключи строк, и для получения данных из них нужно использовать метод Элементы.ВашСписок.ДанныеСтроки(Идентификатор).