К статье
Практический материал

Разработка и Конфигурация · 11 мин

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

Как заполнить таблицу значений на форме в 1С 8: реквизиты формы, методы Добавить, Загрузить, ЗначениеВДанныеФормы, примеры кода и типичные ошибки.

Таблица значений на форме в 1С 8 — один из самых частых приёмов при разработке управляемых форм: подбор товаров, отображение промежуточных результатов расчёта, вывод данных запроса для выбора пользователем. Однако у начинающих разработчиков регулярно возникает путаница между типом «ТаблицаЗначений», реквизитом формы и коллекцией «ДанныеФормыТаблица», из-за чего данные либо не отображаются, либо вызывают ошибки преобразования.

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

Ниже разобраны оба подхода с готовыми примерами кода, варианты заполнения из запроса и из документа, а также типичные ошибки, из-за которых таблица остаётся пустой или форма «падает» с ошибкой.

Создание реквизита формы типа «Таблица значений»

Первый шаг — объявить реквизит формы. Откройте форму в конфигураторе, перейдите на закладку «Реквизиты» и добавьте новый реквизит с типом «ТаблицаЗначений». После этого в дереве реквизита создайте подчинённые колонки: для каждой колонки задайте имя и тип (строка, число, ссылка на справочник и т.д.). Состав колонок должен совпадать с теми полями, которые вы собираетесь заполнять программно.

Затем перетащите реквизит в дерево элементов формы — платформа автоматически создаст таблицу с колонками. Если колонку нужно скрыть от пользователя (например, служебный идентификатор), просто не добавляйте её в элементы формы или снимите видимость у конкретного поля.

Альтернатива — создать реквизит программно через метод ИзменитьРеквизиты(). Это оправдано, когда состав колонок заранее неизвестен и зависит от настроек. Однако такой подход сложнее в сопровождении: изменение реквизитов формы возможно только на сервере и требует аккуратной работы с добавлением элементов отображения.

Заполнение таблицы вручную через Добавить()

Самый прямой способ — построчное добавление данных в цикле. Метод Добавить() создаёт новую строку коллекции, после чего поля заполняются обращением по имени колонки:

&НаСервере

Процедура ЗаполнитьТаблицуНаСервере()

ТаблицаТоваров.Очистить();

Для Каждого СтрокаДанных Из МассивДанных Цикл

НоваяСтрока = ТаблицаТоваров.Добавить();

НоваяСтрока.Номенклатура = СтрокаДанных.Номенклатура;

НоваяСтрока.Количество = СтрокаДанных.Количество;

НоваяСтрока.Цена = СтрокаДанных.Цена;

КонецЦикла;

КонецПроцедуры

Если структура источника совпадает по именам полей с колонками таблицы, удобнее использовать ЗаполнитьЗначения(НоваяСтрока, СтрокаДанных) — метод перенесёт все одноимённые свойства за один вызов. Это сокращает код и снижает риск забыть колонку при доработке.

Обратите внимание на вызов Очистить() перед заполнением. Без него повторное выполнение процедуры добавит строки к уже существующим, и пользователь увидит дубли. Это одна из самых частых ошибок при программном заполнении.

Заполнение из запроса на сервере

Типовой сценарий — вывести на форму результат запроса: остатки, цены, список документов. Здесь есть два рабочих варианта. Первый — выгрузить результат запроса в таблицу значений и передать её в реквизит формы через ЗначениеВДанныеФормы():

&НаСервере

Процедура ЗаполнитьИзЗапроса()

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Ссылка КАК Номенклатура,

| Товары.Код КАК Код

|ИЗ

| Справочник.Номенклатура КАК Товары";

РезультатТаблица = Запрос.Выполнить().Выгрузить();

ЗначениеВДанныеФормы(РезультатТаблица, ТаблицаТоваров);

КонецПроцедуры

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

Сравнение вариантов заполнения

ЗначениеВДанныеФормы()

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

Цикл с Добавить()

Гибкий вариант, когда данные нужно обработать или собрать из нескольких источников. Медленнее на очень больших объёмах, но нагляднее.

Загрузить() с массивом структур

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

Передача данных между клиентом и сервером

В управляемых формах код делится на клиентский и серверный, и это источник многих ошибок. Тип «ТаблицаЗначений» недоступен в контексте тонкого клиента — работать с ним можно только на сервере. На клиенте доступна коллекция реквизита формы (ДанныеФормыТаблица), у которой есть методы Добавить(), Очистить(), НайтиСтроки().

Если заполнение требует обращения к базе данных, выполняйте его в серверной процедуре (директива &НаСервере), а из клиентского обработчика только вызывайте её. Передавать таблицу значений параметром в клиентскую процедуру нельзя — используйте массив структур или заполняйте реквизит формы прямо на сервере: изменения реквизита платформа сама доставит на клиента.

Загрузка массива структур методом Загрузить()

Метод Загрузить() принимает массив структур и заполняет таблицу за один вызов. Это удобно, когда данные приходят из внешнего источника, собираются на клиенте или возвращаются из общего модуля:

&НаСервере

Процедура ЗаполнитьМассивом()

МассивСтрок = Новый Массив;

Строка = Новый Структура("Номенклатура, Количество, Цена");

Строка.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000001");

Строка.Количество = 5;

Строка.Цена = 1200;

МассивСтрок.Добавить(Строка);

ТаблицаТоваров.Загрузить(МассивСтрок);

КонецПроцедуры

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

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

Обратное действие: чтение таблицы с формы

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

&НаСервере

Функция ПолучитьДанныеТаблицы()

Возврат ДанныеФормыВЗначение(ТаблицаТоваров, Тип("ТаблицаЗначений"));

КонецФункции

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

Типичные ошибки
01
Попытка присвоить реквизиту формы объект ТаблицаЗначений напрямую — возникает ошибка несоответствия типов, нужно ЗначениеВДанныеФормы()
02
Отсутствие Очистить() перед заполнением — строки дублируются при каждом повторном вызове
03
Заполнение на клиенте с обращением к данным базы — методы запросов недоступны, код падает с ошибкой
04
Несовпадение имён колонок запроса и реквизита формы — колонки остаются пустыми без явной ошибки
05
Использование таблицы значений вместо динамического списка для больших данных — форма открывается медленно

Проверка результата и отладка

После заполнения убедитесь, что данные действительно попали в реквизит. Простейшая проверка — вывести количество строк: Сообщить(ТаблицаТоваров.Количество()) в конце серверной процедуры. Если число больше нуля, а на форме пусто — проблема в элементах формы: проверьте, что таблица связана именно с этим реквизитом (свойство «ПутьКДанным» у элемента формы).

Если количество строк равно нулю — проблема в источнике: проверьте запрос в консоли запросов, убедитесь, что условия отбора не отсекают все данные. Также полезно в отладчике посмотреть содержимое первой строки коллекции и сверить имена колонок с именами полей источника.

Контрольные точки

Как проверить результат

Количество строк в реквизите после заполнения
Норма

Количество() возвращает ожидаемое число

Тревожный признак

Возвращает 0 — данные не получены из источника

Отображение на форме
Норма

Строки видны в таблице формы сразу после открытия или нажатия команды

Тревожный признак

В реквизите данные есть, на форме пусто — неверный ПутьКДанным у элемента

Типы колонок
Норма

Ссылки отображаются как ссылки, даты и числа форматируются корректно

Тревожный признак

В колонках строковое представление вместо ссылок — тип колонки задан неверно

FAQ

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

Нет. На управляемой форме любые отображаемые данные должны храниться в реквизитах формы. Временную таблицу значений можно создать внутри серверной процедуры для промежуточных расчётов, но для показа пользователю реквизит обязателен.

Почему возникает ошибка «Недопустимое значение» при ЗначениеВДанныеФормы()?

Чаще всего из-за несовпадения типов: например, в колонке реквизита задан тип «Строка», а в таблице значений — ссылка на справочник, или наоборот. Приведите типы колонок реквизита к типам полей источника. Также ошибка возможна, если таблица значений содержит колонки типа, недопустимого для реквизитов формы.

Как заполнить таблицу при открытии формы?

Вызовите процедуру заполнения из обработчика ПриСозданииНаСервере. В этом обработчике реквизиты формы уже созданы, и заполненные данные отобразятся сразу при открытии. Обработчик ПриОткрытии выполняется на клиенте и для обращения к базе не подходит.

Чем таблица значений на форме отличается от динамического списка?

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

Как добавить строку в таблицу на клиенте без вызова сервера?

У коллекции реквизита формы метод Добавить() доступен и на клиенте. Если для заполнения строки не нужны данные из базы (например, добавляется пустая строка или копия текущей), весь код можно выполнить в клиентской процедуре без серверного вызова — это ускорит работу формы.

Почему после Загрузить() пропадают ранее введённые пользователем строки?

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

Итог

Что важно запомнить

Заполнение таблицы на форме всегда идёт через реквизит типа «ТаблицаЗначений»: построчно через Добавить(), массово через Загрузить() или ЗначениеВДанныеФормы(). Работайте с базой только на сервере, очищайте таблицу перед повторным заполнением и следите за совпадением имён и типов колонок.