Как создать и переиспользовать общую табличную часть с условным оформлением для нескольких обработок в мобильном приложении 1С?

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

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

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

1. Программное управление условным оформлением для табличной части-реквизита

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

Принцип работы

  1. Мы создаем в каждой обработке реквизит формы типа ТаблицаЗначений, который будет служить нашей табличной частью. На форме размещаем элемент типа ТабличноеПоле, связанный с этим реквизитом.
  2. Мы разрабатываем одну общую процедуру в общем модуле. Эта процедура будет отвечать за программное добавление всех правил условного оформления.
  3. Из каждой обработки, в событии, например, ПриСозданииНаСервере или ПриОткрытии, мы вызываем эту общую процедуру, передавая ей текущую форму и имя нашей табличной части.

Реализация условного оформления программно

Для программного применения условного оформления мы будем использовать свойство УсловноеОформление объекта Форма. Это свойство представляет собой коллекцию элементов условного оформления, которые мы можем добавлять, удалять и изменять в коде. Важно помнить, что для нединамических списков (коим является наша табличная часть-реквизит обработки) условное оформление задается для самой формы и должно выполняться на сервере, чтобы платформа могла корректно пересчитать расположение и внешний вид элементов.

Давайте посмотрим, как можно реализовать такую общую процедуру в серверном общем модуле:


// Пример общего модуля (например, 'ОбщийМодульОформленияСервер')
Процедура ПрименитьУсловноеОформлениеКТабличнойЧасти(Форма, ИмяТабличнойЧасти) Экспорт
    
    // Получаем коллекцию условного оформления формы
    УсловноеОформлениеФормы = Форма.УсловноеОформление;
    
    // Очищаем существующее оформление для данной табличной части (опционально, если хотим полностью заменить)
    // УсловноеОформлениеФормы.Элементы.Очистить(); 
    
    // Создаем первый элемент условного оформления: например, выделение строк с определенным статусом
    ЭлементОформления1 = УсловноеОформлениеФормы.Элементы.Добавить();
    
    // 1. Условие отбора: например, если значение в колонке 'Статус' равно 'Ошибка'
    Отбор1 = ЭлементОформления1.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    Отбор1.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяТабличнойЧасти + ".Статус"); // Предполагаем, что есть колонка 'Статус'
    Отбор1.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    Отбор1.ПравоеЗначение = "Ошибка";
    Отбор1.Использование = Истина;
    
    // 2. Поля, к которым применяется оформление: вся строка
    ПолеОформления1 = ЭлементОформления1.Поля.Элементы.Добавить();
    ПолеОформления1.Поле = Новый ПолеКомпоновкиДанных(ИмяТабличнойЧасти);
    ПолеОформления1.Использование = Истина;
    
    // 3. Оформление: цвет текста и фона
    ЭлементОформления1.Оформление.УстановитьЗначениеПараметра("ЦветТекста", Новый Цвет(255, 0, 0)); // Красный
    ЭлементОформления1.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(255, 230, 230)); // Светло-красный
    
    // Создаем второй элемент условного оформления: например, выделение строк с 'Успешно'
    ЭлементОформления2 = УсловноеОформлениеФормы.Элементы.Добавить();
    Отбор2 = ЭлементОформления2.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    Отбор2.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяТабличнойЧасти + ".Статус");
    Отбор2.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    Отбор2.ПравоеЗначение = "Успешно";
    Отбор2.Использование = Истина;
    
    ПолеОформления2 = ЭлементОформления2.Поля.Элементы.Добавить();
    ПолеОформления2.Поле = Новый ПолеКомпоновкиДанных(ИмяТабличнойЧасти);
    ПолеОформления2.Использование = Истина;
    
    ЭлементОформления2.Оформление.УстановитьЗначениеПараметра("ЦветТекста", Новый Цвет(0, 128, 0)); // Зеленый
    ЭлементОформления2.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(230, 255, 230)); // Светло-зеленый

    // Можно добавлять и другие правила, например, для выделения отдельных колонок
    ЭлементОформления3 = УсловноеОформлениеФормы.Элементы.Добавить();
    Отбор3 = ЭлементОформления3.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    Отбор3.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяТабличнойЧасти + ".Сумма");
    Отбор3.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше;
    Отбор3.ПравоеЗначение = 0;
    Отбор3.Использование = Истина;

    ПолеОформления3 = ЭлементОформления3.Поля.Элементы.Добавить();
    ПолеОформления3.Поле = Новый ПолеКомпоновкиДанных(ИмяТабличнойЧасти + ".Сумма"); // Только колонка 'Сумма'
    ПолеОформления3.Использование = Истина;

    ЭлементОформления3.Оформление.УстановитьЗначениеПараметра("ЦветТекста", Новый Цвет(200, 50, 50)); // Темно-красный для отрицательных сумм
    ЭлементОформления3.Оформление.УстановитьЗначениеПараметра("Шрифт", Новый Шрифт(,,Истина)); // Жирный
    
КонецПроцедуры

Затем, в обработке, мы вызываем эту процедуру. Предположим, что наша табличная часть на форме называется ТаблицаДанныхЛога:


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

Преимущества:

Недостатки:

2. Использование поля табличного документа

Второй, очень гибкий подход, который нам предлагает сообщество, это использование ТабличногоДокумента. Этот метод особенно хорошо подходит, если наша табличная часть предназначена только для просмотра и нам нужен полный контроль над ее визуальным представлением, включая различные стили ячеек, объединение, границы и т.д.

Принцип работы

  1. В каждой обработке мы создаем на форме реквизит типа ТабличныйДокумент (например, РезультатТабличногоДокумента) и размещаем на форме элемент ПолеТабличногоДокумента, связанный с этим реквизитом.
  2. Мы создаем общую процедуру в общем модуле. Эта процедура будет генерировать объект ТабличныйДокумент, заполнять его данными и применять к нему все необходимое оформление.
  3. Из каждой обработки мы вызываем эту общую процедуру, получаем готовый ТабличныйДокумент и присваиваем его нашему реквизиту формы.

Реализация формирования и оформления ТабличногоДокумента

Объект ТабличныйДокумент предоставляет мощные средства для программного создания макета и его оформления. Мы можем задавать цвета фона и текста, шрифты, границы для каждой ячейки или области, а также использовать параметры, что дает нам максимальную гибкость. Этот подход позволяет нам "нарисовать" таблицу так, как нам хочется, фактически создавая произвольный отчетный документ прямо на форме.

Рассмотрим пример общей процедуры, которая формирует ТабличныйДокумент:


// Пример общего модуля (например, 'ОбщийМодульФормированияОтчетов')
Функция СформироватьТабличныйДокументЛога(ДанныеДляОтображения) Экспорт
    
    // Создаем новый ТабличныйДокумент
    ТабДок = Новый ТабличныйДокумент();
    ТабДок.Очистить();
    
    // Определяем параметры оформления
    СтильЗаголовка = Новый СтильТекста;
    СтильЗаголовка.Шрифт = Новый Шрифт("Arial", 10, Истина); // Жирный шрифт
    СтильЗаголовка.ЦветТекста = Новый Цвет(0, 0, 128); // Темно-синий
    СтильЗаголовка.ЦветФона = Новый Цвет(220, 220, 255); // Светло-синий фон
    
    СтильОбычный = Новый СтильТекста;
    СтильОбычный.Шрифт = Новый Шрифт("Arial", 9);
    СтильОбычный.ЦветТекста = Новый Цвет(0, 0, 0);
    
    СтильОшибки = Новый СтильТекста;
    СтильОшибки.Шрифт = Новый Шрифт("Arial", 9, Истина);
    СтильОшибки.ЦветТекста = Новый Цвет(255, 0, 0); // Красный текст
    СтильОшибки.ЦветФона = Новый Цвет(255, 230, 230); // Светло-красный фон
    
    СтильУспешно = Новый СтильТекста;
    СтильУспешно.Шрифт = Новый Шрифт("Arial", 9);
    СтильУспешно.ЦветТекста = Новый Цвет(0, 128, 0); // Зеленый текст
    СтильУспешно.ЦветФона = Новый Цвет(230, 255, 230); // Светло-зеленый фон

    // Добавляем строки заголовков
    ОбластьЗаголовка = ТабДок.Область("R1C1:R1C" + ДанныеДляОтображения.Колонки.Количество());
    ОбластьЗаголовка.Стиль = СтильЗаголовка;
    ОбластьЗаголовка.ГраницаСлева = Новый Линия(ТипЛинииТабличногоДокумента.Тонкая);
    ОбластьЗаголовка.ГраницаСверху = Новый Линия(ТипЛинииТабличногоДокумента.Тонкая);
    ОбластьЗаголовка.ГраницаСправа = Новый Линия(ТипЛинииТабличногоДокумента.Тонкая);
    ОбластьЗаголовка.ГраницаСнизу = Новый Линия(ТипЛинииТабличногоДокумента.Тонкая);
    ОбластьЗаголовка.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
    ОбластьЗаголовка.ВертикальноеПоложение = ВертикальноеПоложение.Центр;

    Для Каждого Колонка Из ДанныеДляОтображения.Колонки Цикл
        ИндексКолонки = ДанныеДляОтображения.Колонки.Индекс(Колонка) + 1;
        ТабДок.Область("R1C" + ИндексКолонки).Текст = Колонка.Заголовок;
        ТабДок.Область("R1C" + ИндексКолонки).ШиринаКолонки = 20; // Примерная ширина
    КонецЦикла;
    
    ТабДок.Вывести(ОбластьЗаголовка);

    // Выводим данные
    Для Каждого СтрокаТЗ Из ДанныеДляОтображения Цикл
        ОбластьСтроки = ТабДок.Область("R" + (ТабДок.ВысотаТаблицы + 1) + "C1:R" + (ТабДок.ВысотаТаблицы + 1) + "C" + ДанныеДляОтображения.Колонки.Количество());
        
        // Применяем условное оформление к строке
        Если СтрокаТЗ.Статус = "Ошибка" Тогда
            ОбластьСтроки.Стиль = СтильОшибки;
        ИначеЕсли СтрокаТЗ.Статус = "Успешно" Тогда
            ОбластьСтроки.Стиль = СтильУспешно;
        Иначе
            ОбластьСтроки.Стиль = СтильОбычный;
        КонецЕсли;

        Для Каждого Колонка Из ДанныеДляОтображения.Колонки Цикл
            ИндексКолонки = ДанныеДляОтображения.Колонки.Индекс(Колонка) + 1;
            ОбластьЯчейки = ТабДок.Область("R" + (ТабДок.ВысотаТаблицы + 1) + "C" + ИндексКолонки);
            ОбластьЯчейки.Текст = СтрокаТЗ[Колонка.Имя];
            ОбластьЯчейки.ГраницаСлева = Новый Линия(ТипЛинииТабличногоДокумента.Тонкая);
            ОбластьЯчейки.ГраницаСнизу = Новый Линия(ТипЛинииТабличногоДокумента.Тонкая);
            ОбластьЯчейки.ГраницаСправа = Новый Линия(ТипЛинииТабличногоДокумента.Тонкая);
        КонецЦикла;
        
        ТабДок.Вывести(ОбластьСтроки);
    КонецЦикла;
    
    Возврат ТабДок;
КонецФункции

А в модуле формы обработки мы вызываем эту функцию и присваиваем результат:


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

Преимущества:

Недостатки:

3. Переиспользование общей формы

Хотя напрямую "вставить" одну форму в другую в 1С невозможно, мы можем использовать механизм общих форм для централизации компонента и его настроек.

Принцип работы

  1. Мы создаем отдельную ОбщуюФорму (например, ОбщаяФормаПросмотраЛога), которая будет содержать нашу табличную часть как свой собственный реквизит формы и все необходимое условное оформление (настроенное в конфигураторе или программно, как в первом подходе).
  2. Из каждой обработки мы вызываем эту ОбщуюФорму в отдельном окне с помощью метода ОткрытьФорму(), передавая ей необходимые данные для отображения через параметры.
  3. В ОбщейФорме мы принимаем эти параметры и заполняем ее табличную часть.

Реализация

В модуле каждой обработки:


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

// Пример серверной функции для получения данных
&НаСервере
Функция ПолучитьДанныеДляЛогаНаСервере()
    Возврат ОбщиеПроцедурыДляОбработок.ПолучитьСписокДанных(НаборИД);
КонецФункции

В модуле ОбщейФормы.ОбщаяФормаПросмотраЛога:


// В модуле формы ОбщаяФормаПросмотраЛога
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("Данные") Тогда
        // Присваиваем переданные данные реквизиту формы "ТаблицаНаФормеЛога"
        ТаблицаНаФормеЛога = Параметры.Данные;
    КонецЕсли;
    
    // Если условное оформление настроено программно в этой форме
    // ОбщийМодульОформленияСервер.ПрименитьУсловноеОформлениеКТабличнойЧасти(ЭтаФорма, "ТаблицаНаФормеЛога");
КонецПроцедуры

На форме каждой обработки мы размещаем кнопку, которая будет вызывать процедуру ПоказатьОбщийЛог.

Преимущества:

Недостатки:

Дополнительные соображения для мобильных приложений

При выборе подхода и его реализации, нам необходимо учитывать особенности мобильной платформы 1С:

Таким образом, мы видим, что задача централизации табличной части и ее условного оформления в 1С мобильном приложении имеет несколько решений, каждое из которых обладает своими преимуществами и недостатками. Нам предстоит выбрать наиболее подходящий вариант, исходя из требований к интерактивности, сложности оформления и удобства использования.

Для случая, когда табличная часть нужна "только на посмотреть" и требуется максимальный контроль над "красивостью" через условное оформление, мы бы рекомендовали рассмотреть варианты программного управления условным оформлением для табличной части-реквизита или использование поля табличного документа. Первый вариант более близок к исходной структуре (табличная часть как реквизит), но требует программного "накликивания" УО. Второй дает несравненно большую свободу в дизайне и оформлении, превращая табличную часть в полноценный мини-отчет прямо на форме.

← На главную