Текущая строка, выделение и подсветка в таблице управляемой формы 1С 8.3
Содержание
Чтобы программно выделить строку в 1С 8.3 на управляемой форме, присвойте свойству ТекущаяСтрока элемента таблицы идентификатор строки: Элементы.Товары.ТекущаяСтрока = Строка.ПолучитьИдентификатор(). Для динамического списка вместо идентификатора передают ключ — обычно ссылку: Элементы.Список.ТекущаяСтрока = Ссылка. Если нужно отметить несколько строк, их добавляют в коллекцию ВыделенныеСтроки, предварительно включив множественный режим выделения.
Главная ловушка — путать три вещи: текущую строку (где стоит курсор), выделенные строки (подсвеченные системным цветом) и визуальную подсветку цветом по условию. Это разные механизмы с разным кодом. Примеры рассчитаны на платформу 8.3 и управляемые формы; про обычные формы — отдельный раздел.
Что значит «выделить строку» в таблице управляемой формы
На форме таблица — это элемент ТаблицаФормы. Данные лежат в реквизите формы: табличной части объекта (Объект.Товары), таблице значений, дереве или динамическом списке. Код работает с элементом, а не с данными.
У элемента таблицы есть свойства, которые отвечают за выделение:
| Свойство | Что хранит | Доступ из кода |
|---|---|---|
ТекущаяСтрока | Идентификатор (коллекции) или ключ (динамический список) строки под курсором | Чтение и запись |
ТекущиеДанные | Данные текущей строки, можно читать поля | Только на клиенте |
ВыделенныеСтроки | Массив идентификаторов или ключей всех выделенных строк | Свойство не переприсваивается, но в массив можно добавлять и очищать его |
РежимВыделения | РежимВыделенияТаблицы.Одиночный или .Множественный | Чтение и запись |
РежимВыделенияСтроки | РежимВыделенияСтрокиТаблицы.Строка или .Ячейка | Чтение и запись |
Что важно запомнить:
- 🔹 Текущая строка всегда одна. Это строка с фокусом, её подсвечивает рамка или цвет курсора.
- 🔹 Выделенных может быть много, но только при множественном режиме. В одиночном режиме выделенная строка совпадает с текущей.
- 🔹 Цветная подсветка по условию (например, красным — строки с нулевым количеством) к выделению не относится. Это оформление, и делается оно через условное оформление.
Свойство РежимВыделенияСтроки = Ячейка даёт «табличный» курсор по ячейкам, как в Excel. Для выделения целой строки при клике ставьте Строка.
Идентификатор строки и коллекция ВыделенныеСтроки
В управляемой форме строки коллекций (табличная часть, таблица значений, дерево) адресуются не индексом и не самим объектом строки, а идентификатором. Это число, которое платформа выдаёт каждой строке данных формы. Получают его методом ПолучитьИдентификатор(), обратный поиск — НайтиПоИдентификатору().
Сделать строку текущей
Пример: после подбора номенклатуры поставить курсор на строку с нужным товаром.
&НаКлиенте
Процедура ПерейтиКТовару(Номенклатура)
НайденныеСтроки = Объект.Товары.НайтиСтроки(Новый Структура("Номенклатура", Номенклатура));
Если НайденныеСтроки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Элементы.Товары.ТекущаяСтрока = НайденныеСтроки[0].ПолучитьИдентификатор();
ТекущийЭлемент = Элементы.Товары;
КонецПроцедуры
Строка ТекущийЭлемент = Элементы.Товары переводит фокус на таблицу. Без неё курсор встанет на нужную строку, но фокус останется на том поле, где был, и пользователь может не заметить перехода.
Выделить несколько строк
Сначала включают множественный режим (в свойствах таблицы в конфигураторе или кодом), затем наполняют ВыделенныеСтроки. Пример — выделить все строки с нулевой ценой:
&НаКлиенте
Процедура ВыделитьСтрокиБезЦены(Команда)
Элементы.Товары.РежимВыделения = РежимВыделенияТаблицы.Множественный;
Элементы.Товары.ВыделенныеСтроки.Очистить();
ПерваяНайденная = Неопределено;
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Если СтрокаТЧ.Цена = 0 Тогда
Идентификатор = СтрокаТЧ.ПолучитьИдентификатор();
Элементы.Товары.ВыделенныеСтроки.Добавить(Идентификатор);
Если ПерваяНайденная = Неопределено Тогда
ПерваяНайденная = Идентификатор;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ПерваяНайденная <> Неопределено Тогда
Элементы.Товары.ТекущаяСтрока = ПерваяНайденная;
КонецЕсли;
КонецПроцедуры
Добавление в ВыделенныеСтроки не двигает курсор. Поэтому в примере текущей делается первая найденная строка — иначе выделение может оказаться за пределами видимой области, и таблица не прокрутится к нему.
Прочитать выделенные строки и отправить на сервер
Обработка выделенного — самый частый сценарий: «удалить отмеченные», «проставить скидку выбранным». Идентификаторы — простые числа, их можно передать на сервер массивом.
&НаКлиенте
Процедура УстановитьСкидку(Команда)
Выделенные = Элементы.Товары.ВыделенныеСтроки;
Если Выделенные.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Выделите строки для установки скидки.");
Возврат;
КонецЕсли;
МассивИдентификаторов = Новый Массив;
Для Каждого Идентификатор Из Выделенные Цикл
МассивИдентификаторов.Добавить(Идентификатор);
КонецЦикла;
УстановитьСкидкуНаСервере(МассивИдентификаторов, 5);
КонецПроцедуры
&НаСервере
Процедура УстановитьСкидкуНаСервере(МассивИдентификаторов, ПроцентСкидки)
Для Каждого Идентификатор Из МассивИдентификаторов Цикл
СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Идентификатор);
Если СтрокаТЧ = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаТЧ.ПроцентСкидки = ПроцентСкидки;
КонецЦикла;
КонецПроцедуры
Копия в отдельный массив нужна, чтобы на сервер ушли обычные значения, а не служебная коллекция элемента формы.
При удалении выделенных строк сначала соберите сами строки в массив, а потом удаляйте. Если удалять внутри цикла по ВыделенныеСтроки, коллекция меняется на ходу, и часть строк пропускается.
Как подсветить строку цветом: условное оформление вместо RowAppearance
Тот, кто переходит с обычных форм, ищет ОформлениеСтроки и обработчик ПриВыводеСтроки. В управляемых формах их нет: оформление строк считается на сервере заранее, по правилам. Инструмент — условное оформление формы.
Пример: подсветить розовым строки табличной части, где количество равно нулю. Код ставят в ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных(Элементы.Товары.Имя);
Отбор = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.Количество");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = 0;
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(255, 225, 225));
КонецПроцедуры
Что здесь происходит:
Поля— к каким элементам формы применить оформление. Указано имя всей таблицы, поэтому подсвечивается строка целиком. Чтобы подсветить одну колонку, укажите имя её поля, напримерТоварыКоличество.Отбор— условие. Левое значение — путь к данным формы, а не имя элемента.Оформление— что поменять. КромеЦветФоначасто используютЦветТекста,Шрифт,Видимость,Текст.
Для динамического списка правило добавляют в собственное условное оформление списка, а путь в отборе указывают как поле запроса:
ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
Отбор = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПометкаУдаления");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = Истина;
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветТекста", Новый Цвет(150, 150, 150));
Условное оформление можно настроить и без кода: в конфигураторе откройте форму, вызовите палитру свойств самой формы и найдите свойство «Условное оформление». Код удобнее, когда правила зависят от настроек или правятся в расширении.
Если нужно подсветить именно ту строку, на которой стоит пользователь, отдельный цвет не нужен: платформа сама рисует текущую и выделенные строки. Подсветка «последней изменённой строки» делается через служебную колонку-флаг в данных и правило оформления по этой колонке.
Переход к нужной строке: курсор, фокус, прокрутка
Установка ТекущаяСтрока сразу прокручивает таблицу к строке. Несколько сценариев навигации, которые встречаются постоянно.
Перейти к последней добавленной строке
&НаКлиенте
Процедура ДобавитьИПерейти(Команда)
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Количество = 1;
Элементы.Товары.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
ТекущийЭлемент = Элементы.Товары;
Элементы.Товары.ИзменитьСтроку();
КонецПроцедуры
Метод ИзменитьСтроку() открывает текущую строку на редактирование — курсор окажется в ячейке, и пользователь сразу печатает.
Встать на строку при открытии формы списка
У стандартных форм списка и выбора есть параметр ТекущаяСтрока. Передайте его при открытии — и список откроется уже на нужном элементе:
ПараметрыФормы = Новый Структура("ТекущаяСтрока", Контрагент);
ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", ПараметрыФормы, Элементы.Контрагент);
Для собственной формы этот параметр нужно обработать самим: в ПриСозданииНаСервере прочитать Параметры.ТекущаяСтрока и присвоить его Элементы.Список.ТекущаяСтрока.
Таблица-дерево: раскрыть ветку до строки
В дереве строка может лежать в свёрнутой группе. Тогда текущей её сделать мало — надо раскрыть родителя:
СтрокаДерева = ДеревоДанных.НайтиПоИдентификатору(Идентификатор);
Родитель = СтрокаДерева.ПолучитьРодителя();
Если Родитель <> Неопределено Тогда
Элементы.ДеревоДанных.Развернуть(Родитель.ПолучитьИдентификатор(), Ложь);
КонецЕсли;
Элементы.ДеревоДанных.ТекущаяСтрока = Идентификатор;
Второй параметр Развернуть отвечает за раскрытие подчинённых веток: Ложь — раскрыть только этот уровень.
Динамический список: ключи вместо идентификаторов и события строки
В динамическом списке нет данных формы с идентификаторами. Строки адресуются ключом:
| Что выводит список | Тип ключа строки |
|---|---|
| Справочник, документ, план видов характеристик | Ссылка на объект |
| Регистр сведений | Ключ записи регистра |
| Произвольный запрос без основной таблицы | Служебный ключ, ссылкой не является |
Поэтому выделение в списке документов выглядит так:
Элементы.Список.РежимВыделения = РежимВыделенияТаблицы.Множественный;
Элементы.Список.ВыделенныеСтроки.Очистить();
Для Каждого Документ Из МассивДокументов Цикл
Элементы.Список.ВыделенныеСтроки.Добавить(Документ);
КонецЦикла;
Элементы.Список.ТекущаяСтрока = МассивДокументов[0];
Перед обращением к МассивДокументов[0] проверьте, что массив не пуст.
Две особенности, о которые спотыкаются:
- 🔸 Строка должна попадать в отбор. Если документ отфильтрован по периоду или организации, установка ключа ничего не сделает: строки в выборке нет.
- 🔸 В выделенных бывают группировки. Если в списке включена группировка или иерархия, в
ВыделенныеСтрокипопадают и строки групп. Их отсекают проверкой типа:
Для Каждого Ключ Из Элементы.Список.ВыделенныеСтроки Цикл
Если ТипЗнч(Ключ) = Тип("СтрокаГруппировкиДинамическогоСписка") Тогда
Продолжить;
КонецЕсли;
ОбработатьДокумент(Ключ);
КонецЦикла;
Событие ПриАктивизацииСтроки
Обработчик таблицы ПриАктивизацииСтроки срабатывает при смене текущей строки — и от клика пользователя, и при смене ТекущаяСтрока из кода. В нём обычно обновляют подчинённую таблицу или панель с деталями.
Если в обработчике есть вызов сервера, делайте его через обработчик ожидания. Иначе пролистывание списка стрелками даст по серверному вызову на каждую строку:
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
ОтключитьОбработчикОжидания("ОбновитьДетали");
ПодключитьОбработчикОжидания("ОбновитьДетали", 0.2, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьДетали()
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ОбновитьДеталиНаСервере(ТекущиеДанные.Ссылка);
КонецПроцедуры
Для динамического списка ТекущиеДанные содержит только колонки, которые попали в запрос списка. Поле, которого нет в запросе, вызовет ошибку «Поле объекта не обнаружено». Нужное поле добавьте в запрос или включите его использование в настройках колонок.
Другие полезные события таблицы:
- 🔹
Выбор— двойной щелчок или Enter. ПараметрВыбраннаяСтрокасодержит идентификатор или ключ строки. - 🔹
ПередНачаломИзменения,ПередУдалением— можно запретить действие черезОтказ = Истина, например для строк, выделенных цветом как «закрытые».
Обычные формы: ТабличноеПоле и ПриВыводеСтроки
В обычных формах (толстый клиент, старые конфигурации) таблица — это элемент ТабличноеПоле. Здесь всё проще: строки адресуются самим объектом строки, без идентификаторов.
// Сделать строку текущей
ЭлементыФормы.ТабличноеПоле1.ТекущаяСтрока = СтрокаТЗ;
// Добавить к выделенным
ЭлементыФормы.ТабличноеПоле1.ВыделенныеСтроки.Добавить(СтрокаТЗ);
Цвет строки задаётся в обработчике ПриВыводеСтроки. Его параметр ОформлениеСтроки — это и есть тот самый RowAppearance:
Процедура ТабличноеПоле1ПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
Если ДанныеСтроки.Количество = 0 Тогда
ОформлениеСтроки.ЦветФона = Новый Цвет(255, 225, 225);
КонецЕсли;
КонецПроцедуры
Отличие от управляемых форм принципиальное:
| Обычная форма | Управляемая форма | |
|---|---|---|
| Адрес строки | Объект строки | Идентификатор или ключ |
| Цвет строки | ПриВыводеСтроки, ОформлениеСтроки | Условное оформление |
| Где работает код оформления | На клиенте, на каждую строку | Правила задаются на сервере заранее |
Перенести код из обычной формы построчно нельзя. Логику из ПриВыводеСтроки переводят в правила условного оформления, а если условие сложное — в служебную колонку с готовым признаком.
Почему выделение не срабатывает: ошибки и решения
Строка.ПолучитьИдентификатор(), для динамического списка — ссылка или ключ записи.РежимВыделения = РежимВыделенияТаблицы.Множественный до заполнения коллекции.ЗначениеВРеквизитФормы), строки получают новые идентификаторы. Запоминайте не идентификатор, а значение ключевого поля, и после сервера ищите строку заново.Ещё одна частая путаница — индекс и идентификатор. Объект.Товары[0] — это строка по индексу, позиция в коллекции. Идентификатор — другое число, и совпадение с индексом случайно. Код вида Элементы.Товары.ТекущаяСтрока = 0 в лучшем случае ничего не сделает, в худшем — поставит курсор не туда.
Можно ли выделить строку программно, не перемещая курсор?
ВыделенныеСтроки при множественном режиме и не трогайте ТекущаяСтрока. Строка подсветится, курсор останется на месте.Как снять выделение со всех строк?
Элементы.Товары.ВыделенныеСтроки.Очистить(). Текущая строка при этом остаётся, просто без дополнительного выделения.Как узнать номер текущей строки табличной части?
Элементы.Товары.ТекущиеДанные и прочитайте поле НомерСтроки. Для таблицы значений в реквизите формы такого поля нет — индекс даёт Объект.Таблица.Индекс(Строка).Можно ли выделить строку в форме, которую открыл другой код?
Форма.Элементы.Список.ТекущаяСтрока = Ссылка. Для стандартных форм проще передать параметр ТекущаяСтрока при открытии.