Разработка и Конфигурация · 11 мин
Как заполнить таблицу значений на форме 1С
Как заполнить таблицу значений на форме 1С: создание реквизита, добавление колонок, программное заполнение, перенос данных в ДанныеФормыКоллекция и типичные ошибки.
Таблица значений на форме в 1С — один из самых частых инструментов при разработке нестандартных обработок, подборов номенклатуры, настроек отчётов и служебных экранов. Задача кажется простой, но у начинающих разработчиков она регулярно вызывает ошибки: таблица не отображается, данные пропадают при переходе между клиентом и сервером, а попытка обратиться к ней как к обычному объекту «ТаблицаЗначений» заканчивается сообщением о несоответствии типов.
Ключевая сложность в том, что на управляемой форме таблица значений хранится не в привычном виде, а в специальном контейнере ДанныеФормыКоллекция. Платформа автоматически преобразует реквизит формы при сериализации, и работать с ним напрямую методами Добавить() и Найти() объектной таблицы значений нельзя — нужны специальные приёмы.
Ниже разобран полный цикл: создание реквизита формы, вывод таблицы на форму, программное заполнение на сервере и на клиенте, обратное преобразование в объект ТаблицаЗначений для обработки и типичные ошибки, из-за которых данные теряются или форма падает с ошибкой.
Создание реквизита формы типа «Таблица значений»
Первый шаг — добавить реквизит в структуру формы. Откройте форму в конфигураторе, перейдите на закладку «Реквизиты» в правой части редактора формы и нажмите «Добавить». В свойстве «Тип» выберите ТаблицаЗначений. После этого реквизит появится в дереве, но пока без единой колонки.
Колонки добавляются как подчинённые реквизиты: выделите созданную таблицу и снова нажмите «Добавить» — новый реквизит попадёт внутрь таблицы. Для каждой колонки задайте имя и тип данных. Типы выбирайте максимально точно: если колонка хранит ссылку на номенклатуру, укажите СправочникСсылка.Номенклатура, а не строку — это даст пользователю поле ввода с выбором из справочника и корректное отображение.
Обратите внимание на свойство «Сохраняемые данные» у реквизита. Оно влияет на то, будет ли содержимое таблицы передаваться между клиентом и сервером при каждом вызове. Для больших таблиц (тысячи строк) передача данных при каждом серверном вызове замедляет форму — в таких случаях стоит пересмотреть архитектуру и обрабатывать данные порциями.
Вывод таблицы на форму
Сам реквизит не виден пользователю — его нужно перетащить в дерево элементов формы (левая часть редактора). Платформа автоматически создаст элемент «Таблица» с колонками-полями. Если этого не произошло, проверьте, что у элемента формы в свойстве «ПутьКДанным» указан именно ваш реквизит.
Для таблицы доступны полезные настройки отображения: командная панель с кнопками добавления и удаления строк, режим редактирования (в таблице или отдельной формой), подвал для итогов по числовым колонкам. Если таблица предназначена только для просмотра, установите свойство «ТолькоПросмотр» — тогда пользователь не сможет случайно изменить данные.
Если таблица нужна программно, но не должна отображаться, просто не добавляйте её в элементы формы. Реквизит останется доступен из кода, что удобно для служебных промежуточных данных.
Программное заполнение таблицы на сервере
Наиболее надёжный способ заполнить таблицу большим объёмом данных — сделать это в серверной процедуре через промежуточный объект ТаблицаЗначений. Это позволяет использовать запросы, выгрузку результатов и все объектные методы.
&НаСервере
Процедура ЗаполнитьТаблицуНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 100
| Номенклатура.Ссылка КАК Номенклатура,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
ТЗ = Запрос.Выполнить().Выгрузить();
ТаблицаНаФорме.Очистить();
ЗначениеВДанныеФормы(ТЗ, ТаблицаНаФорме);
КонецПроцедуры
Ключевая строка здесь — ЗначениеВДанныеФормы(ТЗ, ТаблицаНаФорме). Она копирует содержимое объектной таблицы значений в реквизит формы. Без этого преобразования присваивание ТаблицаНаФорме = ТЗ либо вызовет ошибку, либо заменит реквизит неподходящим объектом.
&НаСервере
Процедура Заполнить()
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Наименование");
ТЗ.Колонки.Добавить("Количество");
Строка = ТЗ.Добавить();
Строка.Наименование = "Тест";
Строка.Количество = 5;
ЗначениеВДанныеФормы(ТЗ, ТаблицаНаФорме);
КонецПроцедурыЗаполнение таблицы на клиенте
Если строки добавляются по одной — например, пользователь сканирует штрихкоды или подбирает товары — серверный вызов на каждую строку избыточен. ДанныеФормыКоллекция поддерживает метод Добавить() и на клиенте, поэтому можно работать напрямую:
&НаКлиенте
Процедура ДобавитьСтроку(Команда)
НоваяСтрока = ТаблицаНаФорме.Добавить();
НоваяСтрока.Наименование = "Новая позиция";
НоваяСтрока.Количество = 1;
КонецПроцедуры
Такой подход не выполняет обращения к серверу, и форма реагирует мгновенно. Для массового добавления (сотни строк в цикле) клиентское заполнение тоже допустимо, но если данные приходят из базы, логичнее один раз получить их на сервере и перенести через ЗначениеВДанныеФормы.
Как выбрать способ заполнения
Чтение и обработка данных из таблицы формы
Когда нужно выполнить сложную обработку уже заполненной таблицы — свёртку, поиск дублей, перенос в документ — удобнее получить объектную ТаблицуЗначений обратно. Для этого служит метод РеквизитФормыВЗначение():
&НаСервере
Процедура ОбработатьТаблицуНаСервере()
ТЗ = РеквизитФормыВЗначение("ТаблицаНаФорме");
ТЗ.Свернуть("Номенклатура", "Количество");
ЗначениеВДанныеФормы(ТЗ, ТаблицаНаФорме);
КонецПроцедуры
Обратите внимание: РеквизитФормыВЗначение принимает имя реквизита строкой, а ЗначениеВДанныеФормы — сам объект реквизита. Это частая причина путаницы. Пара таких вызовов «туда-обратно» — стандартный приём для серверной обработки данных формы.
Для простого перебора строк без преобразования можно обойтись и прямым обходом: Для Каждого Строка Из ТаблицаНаФорме Цикл работает и на клиенте, и на сервере без дополнительных преобразований.
- 1Создайте реквизит формы типа «ТаблицаЗначений» и добавьте в него колонки с точными типами
- 2Перетащите реквизит в элементы формы, чтобы появилась видимая таблица
- 3На сервере сформируйте ТаблицуЗначений (запросом или вручную)
- 4Очистите реквизит и скопируйте данные через ЗначениеВДанныеФормы()
- 5Откройте форму и проверьте, что строки отображаются и редактируются
Типичные ошибки и их устранение
Больше всего проблем возникает из-за путаницы между ТаблицаЗначений и ДанныеФормыКоллекция. Вторая по частоте причина — вызов серверных методов с попыткой передать реквизит формы как параметр в общий модуль: платформа не сериализует ДанныеФормыКоллекция для такой передачи, поэтому сначала преобразуйте её в объектную таблицу.
Отдельный случай — динамическое изменение состава колонок. Если структура таблицы должна меняться в зависимости от настроек, обычного реквизита недостаточно: нужно программно добавлять реквизиты через массив ИзменитьРеквизиты() и создавать элементы формы вручную. Это рабочий, но трудоёмкий путь; если колонок много и они известны заранее, проще создать все в конфигураторе и управлять видимостью.
Проверка результата
После заполнения убедитесь, что таблица работает как ожидается. Откройте форму в режиме предприятия и пройдите по контрольным точкам: строки видны, колонки имеют правильные типы, добавление и удаление строк не вызывает ошибок, данные не пропадают после серверных вызовов.
Как проверить результат
После заполнения строки видны в таблице формы сразу
Таблица пустая — проверьте вызов ЗначениеВДанныеФормы и ПутьКДанным элемента
В ссылочных колонках доступен выбор из справочника
Поле отображается как строка без кнопки выбора — тип колонки задан неверно
Старые строки заменяются новыми
Строки дублируются — перед заполнением не вызван метод Очистить()
Данные сохраняются после любого обращения к серверу
Таблица очищается — проверьте, не пересоздаётся ли реквизит в коде
Что важно запомнить
Реквизит формы типа «ТаблицаЗначений» хранится как ДанныеФормыКоллекция. Заполняйте его либо напрямую методом Добавить(), либо через объектную ТаблицуЗначений с копированием через ЗначениеВДанныеФормы(). Для обратной обработки используйте РеквизитФормыВЗначение(). Всегда очищайте таблицу перед повторным заполнением.
Частые вопросы
Можно ли заполнить таблицу значений на форме без вызова сервера?
Да, если данные уже есть на клиенте: ДанныеФормыКоллекция поддерживает методы Добавить(), Вставить(), Очистить() и перебор в цикле прямо в клиентском коде. Обращение к серверу нужно только тогда, когда данные требуется получить из базы запросом или через серверные функции.
Почему возникает ошибка «Несоответствие типов» при передаче таблицы в общий модуль?
Реквизит формы — это ДанныеФормыКоллекция, а не ТаблицаЗначений, и он не сериализуется для передачи в серверные общие модули. Решение: в серверной процедуре формы вызовите РеквизитФормыВЗначение("ИмяТаблицы"), получите объектную таблицу и передайте уже её.
Как добавить колонку в таблицу программно во время работы формы?
Через метод формы ИзменитьРеквизиты(): сформируйте массив добавляемых реквизитов (объекты ОписаниеРеквизитаФормы с путём к таблице), вызовите метод, затем программно создайте элемент формы для новой колонки через Элементы.Добавить(). Состав колонок существующего реквизита напрямую изменить нельзя.
Чем таблица значений на форме отличается от динамического списка?
Таблица значений — это редактируемый набор произвольных данных, который вы заполняете сами и который не связан с базой напрямую. Динамический список — это готовый запрос к таблице базы данных с автоматическим обновлением. Для подбора и временных данных используйте таблицу значений, для просмотра регистров и справочников — динамический список.
Почему данные в таблице пропадают после серверного вызова?
Чаще всего реквизит пересоздаётся или очищается в серверной процедуре, либо таблица заполнялась не в реквизит формы, а в локальную переменную. Проверьте, что заполнение идёт именно в реквизит формы через ЗначениеВДанныеФормы() или Добавить(), и что нигде в коде не вызывается лишний Очистить().
Можно ли отсортировать таблицу на форме?
У ДанныеФормыКоллекция нет метода Сортировать(). Варианты: преобразовать в ТаблицуЗначений через РеквизитФормыВЗначение, отсортировать и вернуть обратно, либо разрешить пользователю сортировку интерактивно — таблица формы поддерживает сортировку по щелчку на заголовке колонки, если это не отключено в свойствах.