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

В этой статье мы разберём все возможные способы записи в табличные части: от базового ручного добавления строк до сложных программных алгоритмов с использованием Объект.ТабличнаяЧасть, Добавить() и ЗаполнитьЗначенияСвойств(). Особое внимание уделим типичным ошибкам, которые приводят к потере данных или нарушению целостности документов. А для тех, кто только начинает осваивать , мы подготовили пошаговые инструкции с визуальными примерами.

Материал будет полезен:

  • 📊 Бухгалтерам и кадровикам, которые хотят автоматизировать рутинные операции;
  • 💻 Программистам 1С, пишущим обработки для массового заполнения документов;
  • 🎓 Студентам и новичкам, изучающим платформу 1С:Предприятие;
  • 🔧 Администраторам баз, которым нужно быстро исправить ошибки в данных.
📊 Какой способ записи в табличную часть вы используете чаще?
Ручной ввод через интерфейс
Программное заполнение в обработках
Копирование из других документов
Импорт из Excel/XML
Не работал с табличными частями

1. Структура табличной части документа: что нужно знать перед записью

Прежде чем добавлять данные в табличную часть, важно понять её внутреннее устройство. В 1С:Предприятие 8.3 табличная часть — это коллекция строк, каждая из которых представляет собой набор реквизитов (полей). Например, в документе РеализацияТоваровУслуг табличная часть Товары содержит поля Номенклатура, Количество, Цена и Сумма.

Ключевые особенности табличных частей:

  • 🔹 Иерархичность: одна табличная часть может содержать вложенные таблицы (например, Услуги внутри Товары);
  • 🔹 Типизация данных: каждое поле имеет жёстко заданный тип (число, строка, справочник и т.д.);
  • 🔹 Связь с документом: табличная часть не существует отдельно — она всегда привязана к конкретному документу;
  • 🔹 Индексация: строки нумеруются с 0, а не с 1 (важно для программной работы).

Если вы работаете через конфигуратор, структуру табличной части можно увидеть в дереве метаданных: откройте нужный документ (например, ПоступлениеТоваровУслуг) и разверните ветку Табличные части. Там будут перечислены все доступные поля с их типами.

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

2. Ручная запись в табличную часть: пошаговая инструкция для пользователей

Для большинства пользователей основной способ заполнения табличных частей — это ручной ввод через интерфейс программы. Рассмотрим процесс на примере документа ПоступлениеТоваровУслуг:

Шаг 1. Откройте документ через меню Покупки → Поступления (акты, накладные) и создайте новый или выберите существующий.

Шаг 2. Перейдите на вкладку с табличной частью (обычно называется Товары или Материалы).

Шаг 3. Нажмите кнопку Добавить (или Insert на клавиатуре) — в таблице появится новая строка.

Шаг 4. Заполните поля строки:

  • 📦 В колонке Номенклатура выберите товар из справочника (можно использовать поиск по наименованию или артикулу);
  • 🔢 В Количество укажите числовое значение;
  • 💰 В Цена введите стоимость за единицу (система может подставить цену автоматически из справочника);
  • 📝 Поле Сумма обычно рассчитывается автоматически как Количество × Цена.

Шаг 5. После заполнения сохраните документ кнопкой Записать или Провести и закрыть.

Выбраны все обязательные номенклатурные позиции|

Количество и цены соответствуют договорённостям|

Суммы пересчитаны корректно (нет округлений)|

Документ не содержит дублирующихся строк-->

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

⚠️ Внимание: При ручном вводе больших объёмов данных (более 50 строк) может начать "тормозить". В таких случаях лучше использовать групповое добавление через обработку или импорт из Excel.

3. Программная запись в табличную часть: основные методы

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

Метод Описание Пример кода
Добавить() Добавляет новую строку в конец табличной части
НоваяСтрока = ДокументОбъект.Товары.Добавить();
Вставить() Вставляет строку в указанную позицию (индекс)
ДокументОбъект.Товары.Вставить(0); // В начало
ЗаполнитьЗначенияСвойств() Массовое заполнение полей строки по именам
НоваяСтрока.ЗаполнитьЗначенияСвойств(

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

);

Очистить() Удаляет все строки из табличной части
ДокументОбъект.Товары.Очистить();

Рассмотрим полный пример программного заполнения табличной части для документа РеализацияТоваровУслуг:

Процедура ЗаполнитьТабличнуюЧасть(ДокументОбъект)

// Очищаем существующие строки

ДокументОбъект.Товары.Очистить();

// Добавляем первую строку

НоваяСтрока1 = ДокументОбъект.Товары.Добавить();

НоваяСтрока1.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Ноутбук");

НоваяСтрока1.Количество = 2;

НоваяСтрока1.Цена = 50000;

НоваяСтрока1.Сумма = НоваяСтрока1.Количество * НоваяСтрока1.Цена;

// Добавляем вторую строку с заполнением через Структуру

НоваяСтрока2 = ДокументОбъект.Товары.Добавить();

НоваяСтрока2.ЗаполнитьЗначенияСвойств(

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

Справочники.Номенклатура.НайтиПоНаименованию("Монитор"),

1,

25000

)

);

// Пересчитываем итоги документа

ДокументОбъект.ПересчитатьИтоги();

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

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

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

НоваяСтрока = ДокументОбъект.Товары.Добавить();

НоваяСтрока.ЗаполнитьЗначенияСвойств(Строка);

КонецЦикла;

Это копирует все реквизиты строки, включая скрытые системные поля.-->

4. Работа с вложенными табличными частями

Некоторые документы в содержат многоуровневые табличные части. Например, в документе ЗаказПокупателя может быть табличная часть Товары, а у каждой строки — вложенная таблица СерийныеНомера или Характеристики.

Для работы с такими структурами используйте цепочку обращений:

// Добавляем строку в основную табличную часть

СтрокаТовара = ДокументОбъект.Товары.Добавить();

СтрокаТовара.Номенклатура = Товар;

// Добавляем строку во вложенную таблицу "СерийныеНомера"

СерийныйНомер = СтрокаТовара.СерийныеНомера.Добавить();

СерийныйНомер.Серия = "АА12345678";

СерийныйНомер.СрокГодности = ТекущаяДата() + 365;

Обратите внимание на ключевые моменты:

  • 🔗 Вложенная табличная часть доступна только после добавления строки в основную таблицу;
  • 🔄 Изменения во вложенных таблицах не всегда автоматически сохраняются — иногда требуется явный вызов Записать();
  • 📊 Для отображения вложенных таблиц в форме документа может потребоваться настройка интерфейса через конфигуратор.
⚠️ Внимание: При массовом заполнении вложенных табличных частей (более 100 строк) может выдавать ошибку переполнения памяти. В таких случаях разбейте операцию на части по 50-100 строк с промежуточным сохранением документа.

5. Типичные ошибки и их решение

При работе с табличными частями даже опытные пользователи сталкиваются с типичными проблемами. Рассмотрим самые распространённые ошибки и способы их устранения:

Ошибка Причина Решение
Ошибка при вызове метода контекста (Добавить) Табличная часть заблокирована или документ не в режиме редактирования Проверьте, что документ открыт для изменения (Объект.ПометкаУдаления = Ложь)
Суммы в строках не пересчитываются Не вызван метод ПересчитатьИтоги() или отключены события пересчёта Добавьте вызов ДокументОбъект.ПересчитатьИтоги() после изменений
Поле объекта не обнаружено (Номенклатура) Опечатка в имени реквизита или поле не существует в этой табличной части Проверьте имя поля через синтакс-помощник (Ctrl+Пробел)
Данные не сохраняются после записи Отсутствует вызов Объект.Записать() или транзакция не зафиксирована Убедитесь, что документ записан: ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

Особенно часто ошибки возникают при работе с динамическими списками или когда табличная часть привязана к регистру накопления. В таких случаях:

  1. Проверьте права доступа пользователя к объекту;
  2. Убедитесь, что не активны блокировки от других сеансов;
  3. Используйте Попытка...Исключение для обработки ошибок:
    Попытка
    

    ДокументОбъект.Товары.Добавить();

    Исключение

    Сообщить(ОписаниеОшибки());

    КонецПопытки;

Что делать если 1С "зависла" при записи в табличную часть?

Если после программного изменения табличной части перестала отвечать:

1. Дождитесь 2-3 минуты — возможно, идёт фоновая обработка данных.

2. Если зависание продолжается, закройте сеанс через Диспетчер задач (не через крестик окна!).

3. После повторного входа проверьте целостность базы через Тестирование и исправление в Конфигураторе.

4. Для предотвращения таких ситуаций используйте транзакции:

НачатьТранзакцию();

Попытка

// Код изменения табличной части

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

Сообщить("Ошибка: " + ОписаниеОшибки());

КонецПопытки;

6. Оптимизация работы с большими табличными частями

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

1. Массовое добавление через Загрузить():

// Создаём массив структур с данными

Данные = Новый Массив();

Для Сч = 1 По 1000 Цикл

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

КонецЦикла;

// Загружаем данные одним пакетом

ДокументОбъект.Товары.Загрузить(Данные);

2. Отключение пересчёта итогов:

// Отключаем автоматический пересчёт

ДокументОбъект.ОтключитьПересчетИтогов();

// Массовое добавление строк

Для Каждого Элемент Из Источник Цикл

НоваяСтрока = ДокументОбъект.Товары.Добавить();

// Заполнение строки

КонецЦикла;

// Включаем пересчёт и вызываем его явно

ДокументОбъект.ВключитьПересчетИтогов();

ДокументОбъект.ПересчитатьИтоги();

3. Использование временных таблиц: для обработки очень больших объёмов данных (более 10 000 строк) целесообразно:

  • 📥 Выгрузить данные во временную таблицу;
  • 🔄 Обработать их пакетами по 1000 строк;
  • 📤 Загрузить обратно в табличную часть.
💡

При работе с большими табличными частями (1000+ строк) всегда отключайте автоматический пересчёт итогов и используйте пакетную загрузку данных. Это ускорит выполнение кода в 5-10 раз.

Для периодической обработки больших документов (например, ежемесячная загрузка прайс-листов) создайте фоновое задание через ПланыОбмена или РегламентныеЗадания. Это позволит избежать блокировки интерфейса пользователя.

7. Обмен данными: импорт и экспорт табличных частей

Часто данные для табличных частей поступают из внешних источников: Excel, XML, других программ. Рассмотрим основные способы импорта/экспорта:

Импорт из Excel:

// Чтение файла Excel через COM-объект

Excel = Новый COMОбъект("Excel.Application");

РабочаяКнига = Excel.Workbooks.Open("C:\price.xlsx");

Лист = РабочаяКнига.Sheets(1);

// Чтение данных начиная со 2 строки

СтрокаExcel = 2;

Пока Лист.Cells(СтрокаExcel, 1).Value <> Неопределено Цикл

НоваяСтрока = ДокументОбъект.Товары.Добавить();

НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(Лист.Cells(СтрокаExcel, 1).Value);

НоваяСтрока.Цена = Лист.Cells(СтрокаExcel, 2).Value;

СтрокаExcel = СтрокаExcel + 1;

КонецЦикла;

Экспорт в XML:

// Создаём XML-документ

XMLДокумент = Новый ЗаписьXML();

XMLДокумент.ЗаписатьОбъявлениеXML();

XMLДокумент.ЗаписатьНачалоЭлемента("Товары");

// Экспортируем данные

Для Каждого Строка Из ДокументОбъект.Товары Цикл

XMLДокумент.ЗаписатьНачалоЭлемента("Товар");

XMLДокумент.ЗаписатьАтрибут("Номенклатура", Строка.Номенклатура.Наименование);

XMLДокумент.ЗаписатьАтрибут("Количество", Строка.Количество);

XMLДокумент.ЗаписатьКонецЭлемента(); // Товар

КонецЦикла;

XMLДокумент.ЗаписатьКонецЭлемента(); // Товары

XMLДокумент.Закрыть();

// Сохраняем в файл

XMLДокумент.Записать("C:\export.xml");

Для регулярного обмена данными настройте планы обмена или используйте веб-сервисы. Например, для интеграции с интернет-магазином на Bitrix или Woocommerce можно создать обработку, которая будет:

  1. Получать JSON с заказами;
  2. Преобразовывать его в структуры;
  3. Создавать документы РеализацияТоваровУслуг с заполненными табличными частями.
⚠️ Внимание: При импорте данных из внешних источников всегда проверяйте:
  • 🔍 Соответствие типов данных (например, число вместо строки в поле Количество вызовет ошибку);
  • 🔐 Наличие справочников (если в файле указан товар, которого нет в базе, строка не загрузится);
  • 📏 Ограничения на длину полей (например, поле Комментарий может быть ограничено 100 символами).

8. Продвинутые техники: динамическое формирование табличных частей

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

Процедура ЗаполнитьТабличнуюЧастьПоУсловиям(ДокументОбъект)

// Очищаем табличную часть

ДокументОбъект.Товары.Очистить();

// Получаем список номенклатуры по фильтру

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

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

"ВЫБРАТЬ

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

| Номенклатура.ЦенаПоумолчанию КАК Цена

|ИЗ

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

|ГДЕ

| Номенклатура.ЭтоГруппа = ЛОЖЬ

| И Номенклатура.Артикул НЕ ПУСТАЯ ССЫЛКА";

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

Выборка = Результат.Выбрать();

// Динамическое заполнение

Пока Выборка.Следующий() Цикл

НоваяСтрока = ДокументОбъект.Товары.Добавить();

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

// Условное заполнение количества

Если Выборка.Цена > 10000 Тогда

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

Иначе

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

КонецЕсли;

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

КонецЦикла;

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

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

Процедура ДобавитьГруппуНоменклатуры(Группа, ДокументОбъект)

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

| Номенклатура.Родитель = &Группа";

Запрос.УстановитьПараметр("Группа", Группа);

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

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.Номенклатура.ЭтоГруппа Тогда

ДобавитьГруппуНоменклатуры(Выборка.Номенклатура, ДокументОбъект); // Рекурсия

Иначе

НоваяСтрока = ДокументОбъект.Товары.Добавить();

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

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

КонецЕсли;

КонецЦикла;

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

Для оптимизации производительности при динамическом формировании:

  • 📌 Используйте кеширование часто запрашиваемых данных;
  • 🔄 Применяйте пакетную обработку (например, по 100 строк за итерацию);
  • 📊 Для больших выборок используйте временные таблицы вместо прямых запросов.
💡

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

FAQ: Ответы на частые вопросы

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

Используйте метод Очистить():

ДокументОбъект.Товары.Очистить();

Если нужно удалить только определённые строки, используйте цикл с условием:

Для Инд = ДокументОбъект.Товары.Количество() - 1 По 0 Цикл

Если ДокументОбъект.Товары[Инд].Количество = 0 Тогда

ДокументОбъект.Товары.Удалить(Инд);

КонецЕсли;

КонецЦикла;

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

Да, для этого:

  1. Сохраните строку во временную переменную;
  2. Удалите оригинальную строку;
  3. Вставьте её в новую позицию.

Пример:

// Сохраняем строку с индексом 2

Строка = ДокументОбъект.Товары[2];

// Удаляем её

ДокументОбъект.Товары.Удалить(2);

// Вставляем в начало (позиция 0)

ДокументОбъект.Товары.Вставить(0, Строка);

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

Используйте цикл по строкам источника:

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

НоваяСтрока = Приемник.Товары.Добавить();

НоваяСтрока.ЗаполнитьЗначенияСвойств(Строка);

КонецЦикла;

Для копирования со сбросом некоторых полей:

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

НоваяСтрока = Приемник.Товары.Добавить();

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

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

// Поле "Цена" не копируем - оно будет заполнено по прайсу

КонецЦикла;

Почему после программного изменения табличной части не сохраняются суммы?

Это происходит потому, что:

  1. Не вызван метод ПересчитатьИтоги();
  2. Отключены события пересчёта (ОтключитьПересчетИтогов() без последующего ВключитьПересчетИтогов());
  3. В конфигурации отключены автоматические расчёты для этого документа.

Решение:

ДокументОбъект.ПересчитатьИтоги();

ДокументОбъект.Записать();

Как добавить строку в табличную часть с уникальным идентификатором?

Если вам нужно гарантировать уникальность строк (например, для обмена данными), используйте поле УникальныйИдентификатор:

НоваяСтрока = ДокументОбъект.Товары.Добавить();

НоваяСтрока.УникальныйИдентификатор = Новый УникальныйИдентификатор();

НоваяСтрока.Номенкла