Выделение всех строк сразу: от Ctrl+A до массива ВыделенныеСтроки
Содержание
Чтобы выделить все строки в 1С, щёлкните по любой строке списка или табличной части и нажмите Ctrl+A. Программно то же самое делают через свойство ВыделенныеСтроки элемента формы: очищают его и добавляют идентификаторы всех строк в цикле.
Частое заблуждение — искать в языке метод вроде «ВыделитьВсе» или «НайтиВсе». Таких методов у таблиц и массивов нет. Выделение — это массив идентификаторов в элементе формы, а поиск группы строк делает НайтиСтроки. Ниже — оба уровня: что делает пользователь мышью и клавиатурой и как то же самое решает программист в управляемой форме платформы 8.3.
Как выделить все строки мышью и клавиатурой
Работает одинаково в списках справочников и документов, в табличных частях и в журналах. Интерфейс «Такси», платформа 8.3.
| Действие | Что выделяется |
|---|---|
Ctrl+A | все строки таблицы, где стоит курсор |
щелчок, затем Shift+щелчок | диапазон между двумя строками |
Ctrl+щелчок | добавить или убрать одну строку из выделения |
Shift+↓ / Shift+↑ | расширить выделение на строку вниз или вверх |
| щелчок без клавиш | сбросить выделение до одной строки |
Что можно сделать с выделенными строками в типовых конфигурациях (БП 3.0, ЗУП 3.1, УТ 11):
- ✅
Delв списке — пометить на удаление все выделенные объекты разом, программа спросит подтверждение. - ✅ кнопка
Провестив списке документов — провести все выделенные документы. - ✅
Ещё → Изменить выделенные— групповая смена реквизита, например вида номенклатуры или ставки НДС у сотни карточек. - ✅
Ещё → Вывести список— выгрузить строки в табличный документ, а оттуда сохранить в Excel.
В табличном документе отчёта Ctrl+A выделяет все ячейки. Если выделить ячейки с числами, типовые отчёты показывают их сумму в шапке формы — удобно для быстрой сверки без калькулятора.
Почему Ctrl+A не срабатывает
- 🔸 Курсор стоит внутри ячейки в режиме редактирования. Тогда
Ctrl+Aвыделит текст в поле, а не строки. НажмитеEscи повторите. - 🔸 У таблицы на форме включён режим одиночного выделения. Пользователь его не поменяет, это настройка разработчика (см. следующий раздел).
- 🔸 На таблице включён отбор. Выделяются только видимые строки, скрытые отбором в выделение не попадают.
Режим выделения и массив ВыделенныеСтроки в табличной части
Для программиста выделение в управляемой форме — это свойство элемента ТаблицаФормы. Ключевых свойств два:
- 🔹
РежимВыделения—РежимВыделенияТаблицы.МножественныйилиРежимВыделенияТаблицы.Одиночный. В одиночном режиме выделить несколько строк нельзя ни мышью, ни кодом. - 🔹
ВыделенныеСтроки— массив выделенных строк. Для табличной части и таблицы значений на форме в нём лежат идентификаторы строк (число), а не сами строки.
Режим проще задать в конфигураторе, в палитре свойств элемента таблицы. Если нужно переключать на лету:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Элементы.Товары.РежимВыделения = РежимВыделенияТаблицы.Множественный;
КонецПроцедуры
Кнопка «Выделить все строки» в табличной части
Добавьте команду формы и вынесите её на командную панель таблицы. Обработчик:
&НаКлиенте
Процедура ВыделитьВсеСтроки(Команда)
Выделенные = Элементы.Товары.ВыделенныеСтроки;
Выделенные.Очистить();
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Выделенные.Добавить(СтрокаТЧ.ПолучитьИдентификатор());
КонецЦикла;
КонецПроцедуры
Снять выделение — одна строка: Элементы.Товары.ВыделенныеСтроки.Очистить();. Текущая строка при этом останется, её задаёт отдельное свойство ТекущаяСтрока.
Как обработать выделенные строки
По идентификатору строку получают методом НайтиПоИдентификатору. Пример: поставить скидку 5% на все выделенные позиции.
&НаКлиенте
Процедура СкидкаНаВыделенные(Команда)
Для Каждого Ид Из Элементы.Товары.ВыделенныеСтроки Цикл
СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Ид);
Если СтрокаТЧ = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаТЧ.ПроцентСкидки = 5;
КонецЦикла;
КонецПроцедуры
Имена Товары и ПроцентСкидки замените на реквизиты своей формы. Пересчёт сумм после изменения процента — отдельная процедура, её вызывают так же, как при ручном вводе.
Выделение в динамическом списке формы
В форме списка справочника или документа таблица выводит динамический список. Здесь Элементы.Список.ВыделенныеСтроки содержит не идентификаторы, а ключи строк. Для списка с основной таблицей это ссылки: СправочникСсылка.Номенклатура, ДокументСсылка.РеализацияТоваровУслуг и т. п.
Отличия от табличной части:
- 🔸 Строк в памяти клиента нет: список подчитывает их порциями при прокрутке. Перебрать «все строки» циклом на клиенте нельзя.
- 🔸 Если пользователь включил группировку, в массиве могут оказаться строки группировок. Их тип —
СтрокаГруппировкиДинамическогоСписка, такие элементы пропускайте. - 🔸 Выделить конкретную запись кодом можно:
Элементы.Список.ВыделенныеСтроки.Добавить(Ссылка). Но «выделить всё» программно для списка на десятки тысяч записей бессмысленно — проще сразу обработать данные запросом.
Типовой обработчик команды формы списка: собрать ссылки на клиенте и одним вызовом отдать на сервер.
&НаКлиенте
Процедура ОбработатьВыделенные(Команда)
Ссылки = Новый Массив;
Для Каждого Ключ Из Элементы.Список.ВыделенныеСтроки Цикл
Если ТипЗнч(Ключ) = Тип("СтрокаГруппировкиДинамическогоСписка") Тогда
Продолжить;
КонецЕсли;
Ссылки.Добавить(Ключ);
КонецЦикла;
Если Ссылки.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Выделите строки в списке.");
Возврат;
КонецЕсли;
ОбработатьНаСервере(Ссылки);
Элементы.Список.Обновить();
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработатьНаСервере(Ссылки)
Для Каждого Ссылка Из Ссылки Цикл
Объект = Ссылка.ПолучитьОбъект();
// изменение реквизитов объекта
Объект.Записать();
КонецЦикла;
КонецПроцедуры
Команда с параметром — выделение без кода формы
Если команда живёт в общих командах или в командах объекта, код формы не нужен. В свойствах команды задайте тип параметра (ссылку на нужный объект) и РежимИспользованияПараметра = Множественный. Тогда в ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) придёт массив ссылок на все выделенные строки списка. Так устроены многие команды из меню Создать на основании и Печать в типовых.
Найти и выделить все подходящие строки: НайтиСтроки и ОтборСтрок
Задача «выделить все строки, где номенклатура такая-то» решается в два шага: найти строки, затем занести их идентификаторы в выделение.
НайтиСтроки принимает структуру отбора и возвращает массив строк, у которых все перечисленные поля совпадают. Метод есть у таблицы значений, у табличной части объекта и у коллекции данных формы, то есть у Объект.Товары на клиенте.
&НаКлиенте
Процедура ВыделитьПоТовару(Номенклатура)
Отбор = Новый Структура("Номенклатура", Номенклатура);
Найденные = Объект.Товары.НайтиСтроки(Отбор);
Выделенные = Элементы.Товары.ВыделенныеСтроки;
Выделенные.Очистить();
Для Каждого СтрокаТЧ Из Найденные Цикл
Выделенные.Добавить(СтрокаТЧ.ПолучитьИдентификатор());
КонецЦикла;
Если Найденные.Количество() > 0 Тогда
Элементы.Товары.ТекущаяСтрока = Найденные[0].ПолучитьИдентификатор();
КонецЕсли;
КонецПроцедуры
Ограничение НайтиСтроки: только точное равенство. Условия «больше», «содержит», «пусто или ноль» придётся проверять в цикле вручную.
Скрыть всё лишнее вместо выделения
Иногда пользователю удобнее видеть только нужные строки, а не искать подсвеченные среди сотни. Для этого у таблицы формы есть ОтборСтрок:
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", Номенклатура);
// вернуть все строки:
Элементы.Товары.ОтборСтрок = Неопределено;
Отбор меняет только отображение. Цикл Для Каждого СтрокаТЧ Из Объект.Товары по-прежнему пройдёт по всем строкам, включая скрытые. Если обработка должна касаться только видимых, перебирайте ВыделенныеСтроки или повторите условие отбора в цикле.
Все элементы массива, списка значений и таблицы значений
Вне формы понятия «выделение» нет. Есть задача получить все подходящие элементы коллекции. Инструменты разные:
| Коллекция | Чем найти все подходящие | Что вернёт |
|---|---|---|
Массив | цикл с условием; Найти() ищет только первое вхождение | индекс или Неопределено |
СписокЗначений | цикл; для отметки всех — ЗаполнитьПометки(Истина) | меняет пометки на месте |
ТаблицаЗначений | НайтиСтроки(Структура) | массив строк |
ТаблицаЗначений | Скопировать(Структура) | новая таблица только с подходящими строками |
| любая колонка | ВыгрузитьКолонку("Имя") | массив значений колонки |
Все вхождения значения в массив:
Индексы = Новый Массив;
Для Сч = 0 По Массив.ВГраница() Цикл
Если Массив[Сч] = Искомое Тогда
Индексы.Добавить(Сч);
КонецЕсли;
КонецЦикла;
Если у массива 0 элементов, ВГраница() вернёт -1, и цикл не выполнится ни разу — отдельная проверка не нужна.
Связка таблицы значений с запросом — частый приём: выгрузить колонку ссылок и передать её параметром.
Ссылки = ТаблицаТоваров.ВыгрузитьКолонку("Номенклатура");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В (&Ссылки)";
Запрос.УстановитьПараметр("Ссылки", Ссылки);
Результат = Запрос.Выполнить().Выгрузить();
Дубли в массиве ссылок запросу не мешают: условие В их схлопнет.
Колонка «Пометка» вместо выделения
Выделение хрупкое: один щелчок без Ctrl — и пользователь потерял полсотни отмеченных строк. Для обработок, где человек долго отбирает позиции, добавьте в таблицу булеву колонку Пометка с флажком и две команды: «Отметить все» и «Снять отметки».
&НаКлиенте
Процедура ОтметитьВсе(Команда)
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
СтрокаТЧ.Пометка = Истина;
КонецЦикла;
КонецПроцедуры
Флажки сохраняются в данных формы, их видно и после перерисовки, а отобрать отмеченные можно тем же НайтиСтроки(Новый Структура("Пометка", Истина)).
Массовые операции над выделенными строками: скорость и ловушки
Выделить тысячу строк просто. Обработать их так, чтобы форма не зависла, — отдельная задача.
Один вызов сервера вместо тысячи
Серверная процедура, вызванная внутри цикла на клиенте, — главная причина тормозов. Каждый вызов — это обмен с сервером, а в веб-клиенте и через интернет ещё и сетевая задержка. Соберите массив на клиенте и передайте его целиком одним вызовом, как в примере с динамическим списком. Используйте &НаСервереБезКонтекста, если данные формы серверу не нужны: тогда на сервер не уходит вся форма.
Удаление выделенных строк
Удалять строки прямо в цикле по ВыделенныеСтроки нельзя. При удалении строки платформа убирает её идентификатор из выделения, массив меняется на ходу, и часть строк пропускается. Сначала скопируйте идентификаторы, потом удаляйте:
&НаКлиенте
Процедура УдалитьВыделенные(Команда)
Иды = Новый Массив;
Для Каждого Ид Из Элементы.Товары.ВыделенныеСтроки Цикл
Иды.Добавить(Ид);
КонецЦикла;
Для Каждого Ид Из Иды Цикл
СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Ид);
Если СтрокаТЧ <> Неопределено Тогда
Объект.Товары.Удалить(СтрокаТЧ);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
С массивами та же история: удаляя элементы по индексу, идите с конца — Для Сч = 1 По Массив.Количество() Цикл, а индекс берите как Массив.Количество() - Сч. Тогда сдвиг оставшихся элементов не ломает перебор.
Запись сотен объектов
- ⚠️ Запись каждого объекта — отдельная транзакция с проверками, подписками и движениями. Тысяча документов — это минуты, а не секунды. Предупредите пользователя или запускайте обработку фоновым заданием.
- ⚠️ Оборачивать всю пачку в одну транзакцию рискованно: ошибка на 999-м объекте откатит все предыдущие, а таблицы будут заблокированы до конца. Обычно пишут по одному объекту с перехватом ошибки в
Попытка … Исключениеи собирают список неудачных. - ⚠️ Перепроведение выделенных документов в закрытом периоде меняет движения. Перед массовым перепроведением или изменением реквизитов сделайте резервную копию базы.
Чек: всё ли выделено
Пользователи часто уверены, что Ctrl+A в форме списка зацепил вообще все записи справочника. На деле в выделение попадает то, что проходит текущий отбор и поиск в списке. Покажите перед запуском обработки число строк:
Количество = Элементы.Список.ВыделенныеСтроки.Количество();
ТекстВопроса = СтрШаблон("Будет обработано строк: %1. Продолжить?", Формат(Количество, "ЧГ=0"));
Вопрос задают через ПоказатьВопрос с обработчиком оповещения — модальные окна в управляемых формах по умолчанию запрещены.
Частые вопросы
Сохраняется ли выделение после обновления списка?
Обновить() платформа старается сохранить выделение по ключам. Если запись исчезла из-за отбора, она выпадет из выделения. Для надёжности храните отмеченные ссылки в реквизите формы или используйте колонку с флажком.Можно ли узнать выделенные строки в серверной процедуре?
Чем текущая строка отличается от выделенных?
Элементы.Товары.ТекущиеДанные. Выделенных может быть много. Команда, рассчитанная на одну строку, обычно берёт текущую.Как выделить все строки, кроме нескольких?
Ctrl+A, затем Ctrl+щелчком снимите выделение с лишних строк. В коде — заполните ВыделенныеСтроки в цикле и пропустите строки по условию.