Как программно выделить все строки в табличной части документа на управляемой форме?

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

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

Постановка задачи и анализ механизмов платформы

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

Разберем три ключевых понятия, которые часто путают:

  1. НомерСтроки — это реквизит табличной части (начинается с 1). Он может меняться при сортировке.
  2. Индекс — позиция строки в коллекции данных (начинается с 0).
  3. Идентификатор строки — это уникальный внутренний ключ строки в контексте текущей формы. Именно его использует платформа для связи визуального элемента с данными.

Реализация базового алгоритма выделения

Проанализируем самый простой и надежный способ выделения всех строк. Весь код должен исполняться в контексте &НаКлиенте (удобно использовать встраиваемую консоль кода), так как работа с элементами формы и визуальным выделением недоступна на сервере. Рассмотрим следующий пример кода:


&НаКлиенте
Процедура ВыделитьВсеСтроки(Команда)
    
    // Сначала очищаем текущее выделение, чтобы избежать дублей
    Элементы.ТабличнаяЧастьИмя.ВыделенныеСтроки.Очистить();
    
    // Обходим коллекцию данных (объектную часть)
    Для Каждого ТекущаяСтрока Из Объект.ТабличнаяЧастьИмя Цикл
        
        // Получаем уникальный идентификатор строки и добавляем его в массив выделения
        Идентификатор = ТекущаяСтрока.ПолучитьИдентификатор();
        Элементы.ТабличнаяЧастьИмя.ВыделенныеСтроки.Добавить(Идентификатор);
        
    КонецЦикла;
    
КонецПроцедуры

В данном примере мы используем метод ПолучитьИдентификатор(). Это критически важный момент. Если попытаться добавить просто ТекущаяСтрока.НомерСтроки, код может сработать некорректно, если строки в таблице были отсортированы или удалены, так как идентификаторы в форме перестанут совпадать с физическими номерами строк в базе данных.

Важность очистки коллекции перед заполнением

Выясним причину, по которой в коде выше используется метод Очистить(). Коллекция ВыделенныеСтроки ведет себя как массив. Если пользователь уже выделил какие-то строки вручную, а мы запустим цикл добавления без предварительной очистки, то в коллекции могут появиться дублирующиеся идентификаторы. Хотя платформа 1С зачастую обрабатывает это корректно, с точки зрения чистоты кода и производительности интерфейса, предварительная очистка является обязательным этапом.

Проблема пользовательских фильтров (отборов)

Рассмотрим ситуацию, когда пользователь применил фильтр к таблице (например, через поиск или стандартный отбор). Если мы используем цикл Для Каждого Строка Из Объект.ТабличнаяЧастьИмя, программа выделит все строки, которые есть в объекте, включая те, которые в данный момент скрыты фильтром. Это может запутать пользователя: он видит 5 строк, нажимает кнопку, а система обрабатывает 100 скрытых строк.

К сожалению, программного способа «в лоб» получить список только видимых строк для обычной табличной части (не динамического списка) в 1С практически нет. В таких случаях рекомендуется либо предупреждать пользователя, либо анализировать свойство Элементы.ИмяТаблицы.ОтборСтрок, если он установлен программно.

Особенности работы с большими таблицами

Проанализируем ситуацию с производительностью. Если в вашей табличной части тысячи строк, выполнение цикла Для Каждого с добавлением в ВыделенныеСтроки на клиенте может вызвать кратковременное «замирание» интерфейса. Это связано с тем, что каждое изменение коллекции выделения заставляет форму пересчитывать свои визуальные параметры.

Если ваша задача — просто обработать все строки на сервере, лучше не заниматься программным выделением на клиенте. Передайте на сервер весь объект целиком и обработайте его в цикле там. Программное выделение нужно только тогда, когда дальнейшая логика завязана именно на визуально выбранные пользователем элементы.

Типичные ошибки: почему НомерСтроки - 1 не работает?

Разберем популярное заблуждение, упомянутое в обсуждениях: использование конструкции стр.НомерСтроки - 1. Рассмотрим, почему это плохой совет:

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

Правильный подход всегда базируется на методе ПолучитьИдентификатор() для строк табличной части или значении ключа для динамических списков.

Альтернативный метод: вызов стандартной команды

Посмотрим на ситуацию с другой стороны. В платформе уже реализована команда «Выделить все» (горячие клавиши Ctrl + A). Если на командной панели вашей таблицы включены стандартные команды, вы можете попробовать использовать метод ВыполнитьКоманду(). Однако, прямое программное заполнение коллекции ВыделенныеСтроки через Добавить() считается более надежным и контролируемым способом для разработчика 1С.

Итоговый алгоритм действий

Подводя итог, для реализации качественного выделения всех строк на форме выполним следующие шаги:

  1. Убедимся, что процедура выполняется &НаКлиенте.
  2. Определим имя элемента формы, отображающего таблицу (оно может отличаться от имени самой табличной части в метаданных).
  3. Вызовем метод Элементы.ВашаТаблица.ВыделенныеСтроки.Очистить().
  4. Запустим цикл по данным (например, Объект.Товары).
  5. Внутри цикла используем ПолучитьИдентификатор() текущей строки.
  6. Добавим полученное значение в Элементы.ВашаТаблица.ВыделенныеСтроки.

Соблюдение этих простых правил позволит вашему коду работать стабильно вне зависимости от сортировок, фильтров и действий пользователя с данными в таблице.

← На главную