Таблица значений 1С: создание, методы и примеры кода

Дата: 19.09.2026 04:42:56
ТаблицаЗначений
Коллекции значений
Встроенный язык
Запросы
Управляемые формы
Производительность
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

Таблица значений 1С — главная коллекция для работы с данными в памяти: строки и колонки, как у табличной части документа, только без записи в базу. В неё выгружают результат запроса, через неё собирают данные для печатной формы, отчёта или загрузки из Excel, в ней считают промежуточные итоги при проведении. Ниже — как в 1С 8.3 программно создать таблицу с типизированными колонками, найти и удалить строки, свернуть данные, передать таблицу в запрос и на форму. В конце — шпаргалка по методам и приёмы, из-за которых код тормозит.

Таблица значений 1С 8.3: где она работает

Тип ТаблицаЗначений существует на сервере, в толстом клиенте и во внешнем соединении. В тонком клиенте и веб-клиенте его нет. Поэтому в управляемой форме строка Новый ТаблицаЗначений внутри процедуры с директивой &НаКлиенте заканчивается ошибкой «Тип не определен (ТаблицаЗначений)». Вернуть таблицу из серверной функции в клиентскую процедуру тоже не выйдет: этот тип не передаётся между клиентом и сервером.

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

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

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

Готовые данные выгружают так:

  • Запрос.Выполнить().Выгрузить() — колонки и их типы берутся из запроса;
  • ДокументОбъект.Товары.Выгрузить() — копия табличной части, обратно её кладут методом Загрузить();
  • РеквизитФормыВЗначение("ИмяРеквизита") — таблица из реквизита формы, только на сервере;
  • Таблица.СкопироватьКолонки() — пустая таблица с той же структурой.

Рабочий пример — общий модуль для таблицы продаж и форма обработки со сводкой по складам. Типы колонок примитивные, код компилируется в любой конфигурации с режимом совместимости от 8.3.6.

// ===== Общий модуль ТаблицыЗначенийСервер =====
// Свойства модуля: флажок «Сервер». «Вызов сервера» не нужен:
// модуль вызывается из серверных процедур формы. Платформа 8.3.6 и новее,
// режим совместимости конфигурации не ниже 8.3.6 (СтрСоединить, СтрШаблон).

#Область ПрограммныйИнтерфейс

// Создаёт пустую таблицу продаж с типизированными колонками.
//
// Возвращаемое значение:
//  ТаблицаЗначений - колонки Склад, Артикул, Дата, Количество, Сумма.
//
Функция НоваяТаблицаПродаж() Экспорт

	ТипСтрока     = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50));
	ТипДата       = Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата));
	ТипКоличество = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3));
	ТипСумма      = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));

	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить("Склад", ТипСтрока, "Склад");
	Таблица.Колонки.Добавить("Артикул", ТипСтрока, "Артикул");
	Таблица.Колонки.Добавить("Дата", ТипДата, "Дата продажи");
	Таблица.Колонки.Добавить("Количество", ТипКоличество, "Количество");
	Таблица.Колонки.Добавить("Сумма", ТипСумма, "Сумма");

	Возврат Таблица;

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

// Добавляет в таблицу строку продажи.
//
// Возвращаемое значение:
//  СтрокаТаблицыЗначений - добавленная строка.
//
Функция ДобавитьПродажу(Таблица, Склад, Артикул, Дата, Количество, Сумма) Экспорт

	НоваяСтрока = Таблица.Добавить();
	НоваяСтрока.Склад      = Склад;
	НоваяСтрока.Артикул    = Артикул;
	НоваяСтрока.Дата       = Дата;
	НоваяСтрока.Количество = Количество;
	НоваяСтрока.Сумма      = Сумма;

	Возврат НоваяСтрока;

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

// Удаляет строки, в которых и количество, и сумма равны нулю.
// Обход идёт с конца: удаление не сдвигает строки, которые ещё не проверены.
//
Процедура УдалитьНулевыеСтроки(Таблица) Экспорт

	ВсегоСтрок = Таблица.Количество();
	Для Шаг = 1 По ВсегоСтрок Цикл
		СтрокаТаблицы = Таблица[ВсегоСтрок - Шаг];
		Если СтрокаТаблицы.Количество = 0 И СтрокаТаблицы.Сумма = 0 Тогда
			Таблица.Удалить(СтрокаТаблицы);
		КонецЕсли;
	КонецЦикла;

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

// Возвращает итоги по складам и артикулам, отсортированные по складу
// и по убыванию суммы. Исходная таблица не меняется.
//
// Параметры:
//  Продажи - ТаблицаЗначений - таблица из НоваяТаблицаПродаж().
//  Склад   - Строка - если заполнен, в итоги попадёт только этот склад.
//
// Возвращаемое значение:
//  ТаблицаЗначений - колонки Склад, Артикул, Количество, Сумма.
//
Функция СводкаПоСкладам(Продажи, Склад = "") Экспорт

	Колонки = "Склад, Артикул, Количество, Сумма";

	Если ПустаяСтрока(Склад) Тогда
		Сводка = Продажи.Скопировать(, Колонки);
	Иначе
		СтрокиСклада = Продажи.НайтиСтроки(Новый Структура("Склад", Склад));
		Сводка = Продажи.Скопировать(СтрокиСклада, Колонки);
	КонецЕсли;

	Сводка.Свернуть("Склад, Артикул", "Количество, Сумма");
	Сводка.Сортировать("Склад, Сумма Убыв");

	Возврат Сводка;

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

// Преобразует таблицу значений в массив структур с теми же именами колонок.
// Массив структур, в отличие от таблицы, можно вернуть на клиент.
//
Функция ТаблицаВМассивСтруктур(Таблица) Экспорт

	ИменаКолонок = Новый Массив;
	Для Каждого Колонка Из Таблица.Колонки Цикл
		ИменаКолонок.Добавить(Колонка.Имя);
	КонецЦикла;
	КлючиСтруктуры = СтрСоединить(ИменаКолонок, ",");

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

	Возврат Результат;

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

#КонецОбласти

// ===== Модуль формы обработки (управляемая форма) =====
// Реквизиты формы: Склад (Строка) и Сводка (ТаблицаЗначений) с колонками
// Склад, Артикул, Количество, Сумма, добавленными в конфигураторе.

&НаКлиенте
Процедура Сформировать(Команда)

	СформироватьНаСервере();

	// На клиенте Сводка - это ДанныеФормыКоллекция: Количество() и Итог() есть, Свернуть() и Скопировать() нет.
	ПоказатьПредупреждение(, СтрШаблон("Строк в сводке: %1", Сводка.Количество()));

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

&НаСервере
Процедура СформироватьНаСервере()

	Продажи = ТаблицыЗначенийСервер.НоваяТаблицаПродаж();

	// Пример данных. В рабочей обработке таблицу вернёт запрос: Запрос.Выполнить().Выгрузить().
	ТаблицыЗначенийСервер.ДобавитьПродажу(Продажи, "Основной", "A-100", '20250303', 5, 1500);
	ТаблицыЗначенийСервер.ДобавитьПродажу(Продажи, "Основной", "A-100", '20250304', 2, 600);
	ТаблицыЗначенийСервер.ДобавитьПродажу(Продажи, "Основной", "B-200", '20250304', 0, 0);
	ТаблицыЗначенийСервер.ДобавитьПродажу(Продажи, "Филиал", "A-100", '20250305', 1, 310);

	ТаблицыЗначенийСервер.УдалитьНулевыеСтроки(Продажи);
	Результат = ТаблицыЗначенийСервер.СводкаПоСкладам(Продажи, Склад);

	ЗначениеВРеквизитФормы(Результат, "Сводка");

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

Разбор ключевых строк

ОписаниеТипов у каждой колонки. В новой строке типизированная колонка сразу содержит пустое значение своего типа: 0, пустую строку, пустую дату. У колонки без типа там Неопределено, и выражение СтрокаТаблицы.Сумма + 100 падает с ошибкой. Второй довод — запрос: без типов таблицу не передать параметром.

Добавить() и обращение к колонкам. Метод возвращает СтрокаТаблицыЗначений; к ячейке обращаются через точку (НоваяСтрока.Сумма) или в квадратных скобках (СтрокаТаблицы["Сумма"]), если имя колонки лежит в переменной. Если поля совпадают по именам, строку заполняют одной командой ЗаполнитьЗначенияСвойств(НоваяСтрока, Источник). Подробнее — в статье о строке таблицы значений.

Обратный цикл в УдалитьНулевыеСтроки. Удаление строки сдвигает все следующие на одну позицию. Если удалять в цикле Для Каждого или по индексу от начала, строка сразу за удалённой будет пропущена. При обходе с конца сдвигаются только уже проверенные строки.

Скопировать перед Свернуть. Свернуть("Склад, Артикул", "Количество, Сумма") меняет саму таблицу: группирует по первому списку колонок, суммирует второй, а все прочие колонки удаляет. Чтобы не испортить исходные данные, сворачивают копию. НайтиСтроки возвращает массив строк, и Скопировать принимает его первым параметром. Есть и вариант со структурой отбора, но массив работает в любой версии 8.3.

Сортировать("Склад, Сумма Убыв"). Направление пишут через пробел после имени колонки: Возр (по умолчанию) или Убыв.

ТаблицаВМассивСтруктур. Массив структур свободно передаётся на клиент. ЗаполнитьЗначенияСвойств копирует в структуру ячейки с совпадающими именами. СтрСоединить и СтрШаблон есть в платформе начиная с 8.3.6 и доступны, если режим совместимости конфигурации не ниже 8.3.6. В старых конфигурациях вместо СтрШаблон берут СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку из БСП.

ЗначениеВРеквизитФормы. Метод переносит таблицу в реквизит формы. Колонки реквизита должны быть заданы в конфигураторе с теми же именами, иначе данные в форме не появятся.

Обход строк и колонок

Строки обходят циклом Для Каждого или по индексу от 0 до Количество() - 1. Колонки — коллекция Таблица.Колонки, у каждого элемента есть Имя, ТипЗначения, Заголовок. Функция ниже выводит в текст любую таблицу — пригодится для логов:

// Выводит таблицу в текст: строки через перевод строки, значения через табуляцию.
// Работает с любой таблицей - имена колонок берутся из коллекции Колонки.
Функция ТаблицаВТекст(Таблица)

	Строки = Новый Массив;
	Для Каждого СтрокаТаблицы Из Таблица Цикл
		Значения = Новый Массив;
		Для Каждого Колонка Из Таблица.Колонки Цикл
			Значения.Добавить(Строка(СтрокаТаблицы[Колонка.Имя]));
		КонецЦикла;
		Строки.Добавить(СтрСоединить(Значения, Символы.Таб));
	КонецЦикла;

	Возврат СтрСоединить(Строки, Символы.ПС);

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

Поиск, отбор и итоги

Найти("A-100", "Артикул") возвращает первую строку с таким значением или Неопределено. НайтиСтроки(Отбор) принимает структуру «колонка — значение» и возвращает массив всех подходящих строк. Итог("Сумма") считает сумму по колонке, ВыгрузитьКолонку("Артикул") отдаёт значения колонки массивом — его удобно передать в запрос в условие В (&Артикулы).

Если поиск идёт в цикле по другой таблице, сначала создают индекс по колонкам отбора. Без индекса каждый вызов НайтиСтроки перебирает всю таблицу:

// Заказы: колонки Склад, Артикул, Продано (Число).
// Продажи: таблица из НоваяТаблицаПродаж().
Процедура ЗаполнитьПроданоВЗаказах(Заказы, Продажи)

	// Индекс создаётся один раз, до цикла с множеством поисков
	Продажи.Индексы.Добавить("Склад, Артикул");
	Отбор = Новый Структура("Склад, Артикул");

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

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

Индекс создают после заполнения таблицы: он обновляется при каждом добавлении строки. Для поиска по одному ключу часто проще собрать соответствие «ключ — строка».

Таблица значений в запросе и на форме

Таблицу передают в запрос параметром, кладут во временную таблицу и соединяют с данными базы. Вместо сотни запросов в цикле выполняется один:

// Сопоставляет артикулы из таблицы с номенклатурой одним запросом.
// Для конфигураций, где у справочника Номенклатура есть реквизит Артикул.
Функция НоменклатураПоАртикулам(Продажи) Экспорт

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Продажи.Артикул КАК Артикул,
	|	Продажи.Сумма КАК Сумма
	|ПОМЕСТИТЬ ВТ_Продажи
	|ИЗ
	|	&Продажи КАК Продажи
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ВТ_Продажи.Артикул КАК Артикул,
	|	ВТ_Продажи.Сумма КАК Сумма,
	|	Номенклатура.Ссылка КАК Номенклатура
	|ИЗ
	|	ВТ_Продажи КАК ВТ_Продажи
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
	|		ПО ВТ_Продажи.Артикул = Номенклатура.Артикул";
	Запрос.УстановитьПараметр("Продажи", Продажи);

	Возврат Запрос.Выполнить().Выгрузить();

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

У колонок таблицы, которую передают в запрос, должен быть явный тип. Таблица из Выгрузить() типизирована сама, а колонки, созданные вручную, — только если тип указан в Колонки.Добавить. Лишние колонки перед передачей проще отрезать: Продажи.Скопировать(, "Артикул, Сумма").

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

&НаКлиенте
Процедура ПоказатьЛидера(Команда)

	Строки = СводкаДляКлиента();
	Если Строки.Количество() > 0 Тогда
		Лидер = Строки[0];
		Сообщить(СтрШаблон("%1, %2: %3", Лидер.Склад, Лидер.Артикул, Лидер.Сумма));
	КонецЕсли;

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

&НаСервере
Функция СводкаДляКлиента()

	Таблица = РеквизитФормыВЗначение("Сводка");
	Таблица.Сортировать("Сумма Убыв");

	// Возврат Таблица; - так нельзя: таблица значений не передаётся на клиент
	Возврат ТаблицыЗначенийСервер.ТаблицаВМассивСтруктур(Таблица);

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

Шпаргалка: методы таблицы значений

МетодЧто делаетПример
Колонки.ДобавитьДобавляет колонку с именем, типом, заголовкомТ.Колонки.Добавить("Сумма", ТипСумма)
Колонки.НайтиВозвращает колонку или НеопределеноТ.Колонки.Найти("Сумма")
Колонки.УдалитьУдаляет колонкуТ.Колонки.Удалить(Колонка)
Добавить / ВставитьНовая строка в конец / в позицию по индексуТ.Добавить(), Т.Вставить(0)
УдалитьУдаляет строку (объект строки или индекс)Т.Удалить(СтрокаТаблицы)
КоличествоЧисло строкТ.Количество()
Получить / [ ]Строка по индексу, нумерация с 0Т[0]
ИндексНомер строки в таблицеТ.Индекс(СтрокаТаблицы)
НайтиПервая строка со значением или НеопределеноТ.Найти("A-100", "Артикул")
НайтиСтрокиМассив строк по структуре отбораТ.НайтиСтроки(Отбор)
Индексы.ДобавитьИндекс для быстрого поискаТ.Индексы.Добавить("Склад, Артикул")
СвернутьГруппирует и суммирует, лишние колонки удаляетТ.Свернуть("Артикул", "Сумма")
ИтогСумма по колонкеТ.Итог("Сумма")
СортироватьСортирует по одной или нескольким колонкамТ.Сортировать("Дата Убыв")
СкопироватьНовая таблица из части строк и колонокТ.Скопировать(, "Артикул, Сумма")
СкопироватьКолонкиПустая таблица той же структурыТ.СкопироватьКолонки()
ВыгрузитьКолонкуЗначения колонки массивомТ.ВыгрузитьКолонку("Артикул")
ЗагрузитьКолонкуЗаполняет колонку из массива по порядку строкТ.ЗагрузитьКолонку(Цены, "Цена")
ЗаполнитьЗначенияПишет одно значение во все строки колонкиТ.ЗаполнитьЗначения(0, "Скидка")
СдвинутьПеремещает строку вверх или внизТ.Сдвинуть(СтрокаТаблицы, -1)
ОчиститьУдаляет все строки, колонки остаютсяТ.Очистить()

Как не надо использовать таблицу значений

Сама таблица работает быстро. Тормозит то, как её применяют:

  • Выгрузить всё и отфильтровать циклом. Выгрузить() без условия ГДЕ тащит в память сервера весь регистр. Отбор — в запрос, в таблицу — только нужное.
  • Запрос в цикле по строкам. Отдельный запрос за ценой для каждой строки — сотни обращений к базе. Передайте таблицу или колонку массивом в один запрос.
  • Поиск в цикле без индекса. НайтиСтроки внутри цикла по другой таблице на тысячах строк без индекса даёт квадратичный перебор.
  • Сортировка по ссылкам без СравнениеЗначений. При сортировке по колонке со ссылками платформа читает из базы представление каждой ссылки. Если нужен порядок, а не алфавит, передайте Новый СравнениеЗначений вторым параметром Сортировать; если нужен алфавит — добавьте колонку с наименованием ещё в запросе.
  • Большая таблица в реквизите формы. Данные формы ездят между клиентом и сервером при каждом вызове &НаСервере. В реквизите держите только то, что видит пользователь, расчёты ведите в &НаСервереБезКонтекста.
  • Выгрузка миллионов строк ради одного прохода. Если данные нужно просто перебрать один раз, используйте Запрос.Выполнить().Выбрать(): выборка обходит уже полученный результат и не строит в памяти вторую полную копию данных, как Выгрузить().

Если отчёт уже медленный, начните с замера производительности — о типовых причинах в разделе «1С тормозит».

Типичные ошибки

  • «Тип не определен (ТаблицаЗначений)». Таблица создаётся в процедуре &НаКлиенте или в клиентском общем модуле. Перенесите код в &НаСервере или &НаСервереБезКонтекста.
  • «Поле объекта не обнаружено (Сум)». Опечатка в имени колонки, или колонку удалил Свернуть, или её не взял Скопировать.
  • «Индекс находится за границами диапазона». Цикл по индексу до Количество() вместо Количество() - 1 или обращение Т[0] к пустой таблице.
  • «Преобразование значения к типу Число не может быть выполнено». Арифметика с ячейкой, где лежит Неопределено: колонке не задан тип.
  • «Тип не может быть выбран в запросе». Таблица передана параметром, но у колонки нет типа или в ней лежат значения, которые запрос не обрабатывает. Задайте тип в Колонки.Добавить.
  • Пропущенные строки при удалении. Ошибки нет, но часть строк остаётся: удаляли внутри Для Каждого. Нужен обратный цикл.

Частые вопросы

Чем таблица значений отличается от табличной части?

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

Как проверить, что значение имеет тип таблица значений?

Сравнением типов: ТипЗнч(Значение) = Тип("ТаблицаЗначений"). Так проверяют параметр, который может быть и таблицей, и массивом.

Как передать таблицу значений на клиент и обратно?

Напрямую — никак. Если данные нужны клиентскому коду, преобразуйте таблицу в массив структур. Чтобы «пронести» таблицу между серверными вызовами, в процедуре &НаСервере положите её во временное хранилище с идентификатором формы: Адрес = ПоместитьВоВременноеХранилище(Таблица, УникальныйИдентификатор). На клиент уходит адрес, при следующем вызове таблицу забирают через ПолучитьИзВременногоХранилища(Адрес). Без второго параметра значение удаляется при очередном вызове сервера.

Когда взять не таблицу, а другую коллекцию?

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

Когда проще заказать

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

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.