Табличная часть объекта 1С: как устроена, как добавить в конфигураторе и обработать кодом
Содержание
Табличная часть в 1С — это список строк с одинаковым набором колонок, который хранится внутри объекта: документа, справочника, плана счетов и других. Строки «Товары» в реализации, строки «Начисления» в документе начисления зарплаты, контактные лица в карточке — всё это табличные части. Создаются они в конфигураторе на вкладке Данные объекта, а из кода доступны как Объект.ИмяТабличнойЧасти.
Типичная ситуация: бухгалтер просит добавить в поступление колонку «Номер партии», а программист должен решить, где её хранить — в реквизите документа или в строке табличной части. Ответ зависит от того, одно значение на документ или своё на каждую строку. Механика табличных частей задаётся платформой 8.3, поэтому она одинакова для БП, ЗУП, УТ и самописных конфигураций.
Что такое табличная часть и чем она отличается от реквизита
Реквизит хранит одно значение на объект: дату, контрагента, склад. Табличная часть хранит произвольное число строк, у каждой строки свои значения колонок. Колонки табличной части в конфигураторе тоже называются реквизитами — это реквизиты табличной части.
У каждой табличной части есть два стандартных реквизита, их не нужно создавать:
- 🔢
НомерСтроки— порядковый номер строки, начинается с 1; - 🔗
Ссылка— ссылка на объект-владелец (документ или элемент справочника).
В базе данных табличная часть лежит в отдельной таблице. Её строки связаны с основной таблицей объекта по ссылке и упорядочены по номеру строки. Отсюда два практических следствия:
- Табличная часть не живёт отдельно от объекта. Удалили документ — удалились и его строки.
- Записать одну строку нельзя. При записи объекта платформа перезаписывает всю табличную часть целиком.
Табличная часть и таблица значений
Их часто путают, потому что методы похожи.
| Признак | Табличная часть | Таблица значений |
|---|---|---|
| Где описана | В конфигураторе, у объекта метаданных | Создаётся кодом: Новый ТаблицаЗначений |
| Хранится в базе | Да, вместе с объектом | Нет, только в памяти |
| Набор колонок | Задан в конфигураторе | Любой, добавляется кодом |
| Индексы для поиска | Нет | Есть: Индексы.Добавить() |
| Свернуть строки | Нет метода | Есть: Свернуть() |
Если нужно временно сгруппировать или быстро искать по строкам табличной части — выгрузите её в таблицу значений методом Выгрузить(), обработайте и при необходимости загрузите обратно через Загрузить().
Виды табличных частей: у каких объектов они бывают
Табличную часть можно добавить не к любому объекту метаданных. Она есть у прикладных объектов, которые хранят «шапку» и строки:
- 📄 документы — товары, услуги, оплаты;
- 📚 справочники — например, контактные лица, дополнительные реквизиты;
- 🧾 планы счетов — субконто счета (это отдельная стандартная табличная часть
ВидыСубконто); - 📊 планы видов характеристик, планы видов расчёта, планы обмена;
- 🔄 бизнес-процессы и задачи;
- 🛠 обработки и отчёты — здесь табличная часть не хранится в базе, она живёт, пока открыта форма или существует объект обработки.
У регистров, констант, перечислений и журналов документов табличных частей нет. Регистр сам по себе набор записей, его «строки» — это записи регистра.
Пользовательские и стандартные
По происхождению табличные части делятся на два вида:
| Вид | Кто создаёт | Пример |
|---|---|---|
| Пользовательская | Разработчик в конфигураторе | Товары в документе |
| Стандартная | Платформа | ВидыСубконто у плана счетов, БазовыеВидыРасчета у плана видов расчёта |
Особенность иерархических справочников
У табличной части иерархического справочника есть свойство Использование. Оно задаёт, у кого будут строки: только у элементов, только у групп или у тех и других. По умолчанию — для элемента. Если в группе табличная часть не видна, первым делом проверьте это свойство.
Как создать табличную часть в конфигураторе
Порядок одинаков для документа и справочника. На типовой конфигурации на поддержке не меняйте объекты напрямую — добавляйте табличные части через расширение, иначе обновления придётся объединять вручную.
Шаг 1. Добавить табличную часть
- Откройте
Конфигурация → Открыть конфигурацию. - В дереве найдите объект, например документ, и откройте его двойным щелчком.
- Перейдите на вкладку
Данные. - Выделите узел
Табличные частии нажмите кнопку добавления (зелёный плюс). - Задайте имя без пробелов, с буквы:
Партии,ТоварыВозврат. Синоним заполнится автоматически.
Шаг 2. Описать колонки
- Выделите новую табличную часть и снова нажмите добавление — появится реквизит табличной части.
- Задайте имя и тип:
Номенклатура—СправочникСсылка.Номенклатура,Количество—Число(15, 3),Сумма—Число(15, 2). - При необходимости задайте свойства колонки: проверку заполнения, выбор по связям параметров, индексирование.
Шаг 3. Вывести на форму
- Откройте форму объекта на вкладке
Формы. - В правом верхнем окне
РеквизитыраскройтеОбъекти найдите табличную часть. - Перетащите её мышью в дерево элементов слева. Платформа создаст элемент
Таблицас колонками. - Лишние колонки удалите из элементов формы — из данных объекта они не исчезнут.
Шаг 4. Обновить конфигурацию базы данных
Нажмите F7 или Конфигурация → Обновить конфигурацию базы данных. Новая табличная часть — это новая таблица в базе, поэтому изменение структуры требует монопольного доступа. В клиент-серверной базе пользователи, скорее всего, должны будут выйти.
Перед обновлением структуры рабочей базы сделайте резервную копию: Администрирование → Выгрузить информационную базу в конфигураторе или средствами СУБД.
Если нужна табличная часть в расширении
В расширении заимствуйте объект (контекстное меню → Добавить в расширение), затем добавьте к нему свою табличную часть так же, как в основной конфигурации. Такое расширение меняет структуру данных, поэтому после его подключения тоже нужно обновить конфигурацию
базы, и действует то же правило про монопольный доступ.
Работа с табличными частями на встроенном языке
Из модуля объекта табличная часть доступна по имени, из модуля формы — через основной реквизит Объект. На сервере это ТабличнаяЧасть, на форме — ДанныеФормыКоллекция. Набор основных методов у них близкий.
Основные методы
| Метод | Что делает |
|---|---|
Добавить() | Добавляет строку в конец, возвращает её |
Вставить(Индекс) | Вставляет строку в позицию |
Удалить(Строка) | Удаляет строку (по строке или индексу) |
Очистить() | Удаляет все строки |
Количество() | Число строк |
Итог("Сумма") | Сумма по колонке |
НайтиСтроки(Структура) | Массив строк по отбору |
Выгрузить() / Загрузить() | В таблицу значений и обратно |
ВыгрузитьКолонку("Имя") | Массив значений одной колонки |
Сортировать("Колонка Убыв") | Сортировка строк |
Индекс строки начинается с 0, а НомерСтроки — с 1. На этом часто ошибаются.
Заполнить табличную часть кодом
Пример для модуля объекта документа: перенести строки из таблицы значений и посчитать сумму.
Процедура ЗаполнитьТовары(ТаблицаИсточник) Экспорт
Товары.Очистить();
Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл
НоваяСтрока = Товары.Добавить();
НоваяСтрока.Номенклатура = СтрокаИсточника.Номенклатура;
НоваяСтрока.Количество = СтрокаИсточника.Количество;
НоваяСтрока.Цена = СтрокаИсточника.Цена;
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
КонецЦикла;
СуммаДокумента = Товары.Итог("Сумма");
КонецПроцедуры
Если колонки источника называются так же, как в табличной части, короче написать Товары.Загрузить(ТаблицаИсточник). Колонки с другими именами платформа просто пропустит.
Удалить строки по условию
Удалять при прямом обходе Для Каждого нельзя: после удаления индексы сдвигаются, и строки пропускаются. Надёжно — обходить с конца:
КоличествоСтрок = Товары.Количество();
Для Сч = 1 По КоличествоСтрок Цикл
Строка = Товары[КоличествоСтрок - Сч];
Если Строка.Количество = 0 Тогда
Товары.Удалить(Строка);
КонецЕсли;
КонецЦикла;
Второй способ — собрать строки через НайтиСтроки(Новый Структура("Количество", 0)) и удалить каждую из полученного массива.
Свернуть одинаковые строки
У табличной части нет метода Свернуть(), поэтому делают через таблицу значений:
ТЗ = Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура, Цена", "Количество, Сумма");
Товары.Загрузить(ТЗ);
Событие на форме при изменении колонки
Чтобы пересчитать сумму при вводе количества, выделите колонку ТоварыКоличество в элементах формы, на палитре свойств найдите событие ПриИзменении и создайте обработчик:
&НаКлиенте
Процедура ТоварыКоличествоПриИзменении(Элемент)
ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
ТекущиеДанные.Сумма = ТекущиеДанные.Количество * ТекущиеДанные.Цена;
КонецПроцедуры
Табличная часть в запросе
К строкам обращаются как к отдельной таблице через точку:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.НомерСтроки,
| Товары.Номенклатура,
| Товары.Количество,
| Товары.Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &Ссылка
|УПОРЯДОЧИТЬ ПО
| Товары.НомерСтроки";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Выборка = Запрос.Выполнить().Выбрать();
Есть и второй синтаксис — вложенная таблица в выборке из самого документа: ВЫБРАТЬ Ссылка, Товары.(Номенклатура, Количество) ИЗ Документ.РеализацияТоваровУслуг. Тогда поле Товары в результате содержит результат запроса со строками этого документа.
Типичные ошибки при работе с табличными частями
Объект.Товары, а не просто Товары. Проверьте имя в дереве конфигурации.Товары[Товары.Количество()] уже не существует. Последняя строка — Товары[Товары.Количество() - 1].Для Каждого. Обходите с конца или удаляйте по массиву из НайтиСтроки.Ссылка.ПолучитьОбъект(), изменить и вызвать Записать().Использование табличной части стоит «Для элемента». Поменяйте на нужное значение и обновите конфигурацию базы.Объект → ИмяТабличнойЧасти в таблицу на форме.Примеры табличных частей в типовых конфигурациях
Разобраться в чужой табличной части проще всего на типовых документах. Точное имя табличной части смотрите в конфигураторе: откройте объект и раскройте узел Табличные части на вкладке Данные. В режиме 1С:Предприятие ориентируйтесь по вкладкам формы.
Что обычно лежит в табличных частях типовых решений:
| Объект | Что хранят строки |
|---|---|
| Реализация и поступление товаров | Товары и услуги отдельными табличными частями, у каждой свои колонки: количество, цена, ставка НДС, счета учёта |
| Авансовый отчёт | Выданные авансы, приобретённые товары, оплата поставщикам — каждая на своей вкладке формы |
| Документы начисления зарплаты в ЗУП | Начисления и удержания по сотрудникам |
| Справочник с дополнительными реквизитами | Пары «свойство — значение» в табличной части дополнительных реквизитов |
Вкладки формы документа обычно совпадают с табличными частями: одна вкладка — одна табличная часть. Если у вас открыт документ и не понятно, где лежит колонка, начните с этого.
Оптимизация: когда табличная часть тормозит
Табличная часть удобна до определённого объёма. Документ на 20 000 строк будет открываться и записываться заметно медленнее, потому что при каждой записи все строки удаляются и вставляются заново.
Что помогает на практике:
- 📦 Не раздувайте одну табличную часть. Если строки нужны только для отчёта, а не для учёта, храните их в регистре сведений, а в документе — итоги.
- 🔎 Не разыменовывайте ссылки в цикле. Каждое
Строка.Номенклатура.ЕдиницаИзмеренияв цикле — отдельное обращение к базе. Получите нужные поля одним запросом по табличной части с соединением. - ⚡ Ищите по таблице значений с индексом.
НайтиСтрокипо табличной части перебирает строки. Для частого поиска выгрузите её, добавьте индексТЗ.Индексы.Добавить("Номенклатура")и ищите в таблице значений. - 🗂 Индексируйте колонку, по которой фильтруете в запросах. У реквизита табличной части есть свойство
Индексировать. Оно полезно, если вы часто ищете документы по значению в строках, например по номенклатуре. - 🖥 Не гоняйте табличную часть между клиентом и сервером. Каждый серверный вызов из формы передаёт данные формы. Заполнение и пересчёт сотен строк делайте в одной процедуре
&НаСервере, а не построчно. - 📤 Используйте
ВыгрузитьКолонку, когда нужен только массив значений одной колонки, например для параметра запросаВ (&Номенклатура).
Если документ «тяжёлый», замерьте, что именно медленно: включите замер производительности в конфигураторе (Отладка → Замер производительности) и запишите документ. Видно будет, какие строки кода съедают время.
Частые вопросы
Сколько строк может быть в табличной части?
Можно ли переименовать табличную часть, если в ней уже есть данные?
Чем отличается Объект.Товары на форме от Товары в модуле объекта?
ДанныеФормыКоллекция), доступные на клиенте. В модуле объекта — табличная часть прикладного объекта на сервере. Методы похожи, но, например, Выгрузить() в таблицу значений доступен только на сервере.Как сделать, чтобы документ не записывался без строк?
Можно ли сделать табличную часть внутри табличной части?
КлючСтроки с уникальным идентификатором.