Как создать таблицу значений на управляемой форме в 1С и правильно работать с ней?

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

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

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

Если структура таблицы (состав и типы колонок) известна заранее, проще и быстрее всего настроить её визуально в конфигураторе. Разберем этот процесс по шагам:

  1. Откроем форму нашей обработки или документа в конфигураторе.
  2. В правом верхнем окне перейдем на вкладку Реквизиты.
  3. Добавим новый реквизит формы, нажав кнопку «Добавить». Назовем его, например, МояТаблицаФормы.
  4. В свойствах созданного реквизита в поле Тип выберем значение ТаблицаЗначений.
  5. Важный шаг: не торопитесь перетаскивать реквизит на форму. Пустая таблица значений без колонок не отобразится в интерфейсе. Нам необходимо сначала добавить колонки. Для этого кликнем правой кнопкой мыши по созданному реквизиту МояТаблицаФормы и выберем пункт Добавить колонку реквизита.
  6. Создадим две колонки. Первую назовем, например, Товар (тип значения — ссылка на справочник номенклатуры), а вторую — Количество (тип значения — число).
  7. Теперь, когда структура таблицы полностью определена, перетащим мышью реквизит МояТаблицаФормы из правого окна в левое окно — в дерево Элементы формы.
  8. Платформа автоматически предложит создать таблицу и заполнит её колонками. Элемент управления появится на форме и будет полностью готов к работе и вводу данных пользователем.

Способ 2. Использование табличной части объекта как альтернатива

Давайте проанализируем альтернативный вариант, который часто рекомендуют опытные разработчики. Вместо создания реквизита формы с типом ТаблицаЗначений мы можем создать полноценную Табличную часть в самом объекте конфигурации (в обработке или документе).

Рассмотрим плюсы и минусы этого подхода:

Тем не менее, если ваша задача проста и таблица нужна исключительно для временного хранения данных «здесь и сейчас» (без необходимости сохранения в ИБ или обработки в модуле объекта), то создание обычного реквизита формы с типом ТаблицаЗначений является более легким и изящным решением, которое не загромождает структуру метаданных конфигурации.

Архитектурный нюанс: Разница между «ТаблицаЗначений» и «ДанныеФормыКоллекция»

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

Когда мы создаем реквизит формы с типом ТаблицаЗначений и открываем форму в режиме «1С:Предприятие», платформа автоматически преобразует его на клиенте в специальный тип данных — ДанныеФормыКоллекция. Этот объект адаптирован для быстрой передачи по каналам связи между клиентом и сервером.

С объектом ДанныеФормыКоллекция можно успешно работать как на клиенте, так и на сервере. Он поддерживает базовые интерактивные методы:

Однако у ДанныеФормыКоллекция отсутствуют сложные аналитические методы стандартной таблицы значений, такие как Свернуть(), Сортировать(), ЗаполнитьЗначения(), Скопировать() или ВыгрузитьКолонку().

Взаимное преобразование данных (Конвертация на сервере)

Что же делать, если перед выводом данных пользователю нам необходимо выполнить сложную обработку таблицы на сервере — например, быстро свернуть строки по одинаковым товарам или отсортировать их по сумме?

Для решения этой задачи в управляемых формах предусмотрен механизм взаимного преобразования типов с помощью встроенных функций платформы:

Давайте разберем практический пример реализации такой серверной группировки:


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

Программное (динамическое) создание таблицы на форме

Иногда возникают ситуации, когда структура таблицы заранее неизвестна и должна формироваться динамически в зависимости от действий пользователя (например, при построении матрицы распределения товаров по складам, где склады выступают в роли колонок). В этом случае нам потребуется программное создание таблицы на сервере в два этапа.

Этап 1: Создание структуры данных. Для этого применяется метод формы ИзменитьРеквизиты(). Сначала мы формируем массив объектов типа РеквизитФормы, а затем передаем его в систему.

Этап 2: Создание элементов интерфейса. Мы добавляем на форму визуальный элемент управления типа ТаблицаФормы и связываем его колонки с созданными динамическими реквизитами через свойство ПутьКДанным.

Рассмотрим детальный пример кода:


&НаСервере
Процедура СоздатьТаблицуДинамически()
    
    // Массив для хранения добавляемых реквизитов
    ДобавляемыеРеквизиты = Новый Массив;
    
    // 1. Создаем сам реквизит-контейнер для таблицы значений
    ИмяТаблицы = "ДинамическаяТЗ";
    РеквизитТаблица = Новый РеквизитФормы(ИмяТаблицы, Новый ОписаниеТипов("ТаблицаЗначений"), , "Динамическая таблица");
    ДобавляемыеРеквизиты.Добавить(РеквизитТаблица);
    
    // 2. Создаем колонки и привязываем их к нашей таблице (указывая путь во втором параметре)
    РеквизитКолонкаТовар = Новый РеквизитФормы("Товар", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), ИмяТаблицы, "Товар");
    РеквизитКолонкаКол = Новый РеквизитФормы("Количество", Новый ОписаниеТипов("Число"), ИмяТаблицы, "Количество");
    
    ДобавляемыеРеквизиты.Добавить(РеквизитКолонкаТовар);
    ДобавляемыеРеквизиты.Добавить(РеквизитКолонкаКол);
    
    // Применяем изменения структуры формы
    ИзменитьРеквизиты(ДобавляемыеРеквизиты);
    
    // 3. Создаем визуальный элемент таблицы на форме
    ЭлементТаблица = Элементы.Добавить(ИмяТаблицы, Тип("ТаблицаФормы"), Форма);
    ЭлементТаблица.ПутьКДанным = ИмяТаблицы;
    
    // 4. Создаем визуальные колонки внутри таблицы
    НоваяКолонкаТовар = Элементы.Добавить(ИмяТаблицы + "_Товар", Тип("ПолеФормы"), ЭлементТаблица);
    НоваяКолонкаТовар.Вид = ВидПоляФормы.ПолеВвода;
    НоваяКолонкаТовар.ПутьКДанным = ИмяТаблицы + ".Товар";
    
    НоваяКолонкаКол = Элементы.Добавить(ИмяТаблицы + "_Количество", Тип("ПолеФормы"), ЭлементТаблица);
    НоваяКолонкаКол.Вид = ВидПоляФормы.ПолеВвода;
    НоваяКолонкаКол.ПутьКДанным = ИмяТаблицы + ".Количество";
    
КонецПроцедуры

Ограничение передачи таблиц значений между клиентом и сервером

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

Если вам нужно передать порцию табличных данных с клиента на сервер без контекста всей управляемой формы (например, при вызове быстрой директивы &НаСервереБезКонтекста), данные необходимо предварительно упаковать в разрешенные на клиенте универсальные коллекции. Наиболее удобный способ — выгрузить строки таблицы в Массив, элементами которого будут объекты типа Структура, где ключами выступают имена колонок.

Рассмотрим, как это реализовать на практике:


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

&НаСервереБезКонтекста
Процедура ОбработатьДанныеНаСервере(ДанныеТаблицы)
    
    // На сервере мы можем легко прочитать переданный массив структур
    Для Каждого СтрокаДанных Из ДанныеТаблицы Цикл
        Номенклатура = СтрокаДанных.Товар;
        Объем = СтрокаДанных.Количество;
        // Здесь выполняем необходимую бизнес-логику
    КонецЦикла;
    
КонецПроцедуры

Программное условное оформление таблицы

Для улучшения эргономики интерфейса часто требуется выделять строки таблицы цветом при наступлении определенных условий (например, окрашивать строки с нулевым или отрицательным количеством в красный цвет).

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

Давайте разберем пример программной настройки условного оформления нашей таблицы:


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

Использование этого встроенного механизма гарантирует высокую скорость работы интерфейса и корректное отображение табличных данных на любых типах клиентов в системе «1С:Предприятие 8.3».

← На главную