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