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