Работа с табличными частями в 1С:Предприятие — одна из самых частых задач для разработчиков.hether вы создаёте документ, редактируете справочник или обрабатываете данные в регистре, умение программно добавлять строки в табличные части экономит часы рутинной работы. Но даже опытные специалисты иногда сталкиваются с нюансами: почему новая строка не сохраняется? Как избежать дублирования? Или как массово заполнить данные из внешнего источника?

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

Особое внимание уделим типичной ошибке начинающих — попытке добавить строку в табличную часть без предварительной проверки на существование документа или справочника. Это приводит к падению с сообщением «Объект не найден», и мы покажем, как её избежать.

📊 Как часто вы работаете с табличными частями в 1С?
Ежедневно
Несколько раз в неделю
Редко
Никогда

1. Базовый метод: Добавление строки через Добавить()

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

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

Док = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

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

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

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

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

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

Ключевые моменты:

  • 🔹 Метод Добавить() возвращает ссылку на новую строку, которую можно сразу заполнить.
  • 🔹 Если табличная часть привязана к справочнику (например, Номенклатура), используйте методы поиска (НайтиПоНаименованию, НайтиПоКоду).
  • 🔹 Для вычисляемых полей (например, Сумма) можно задать формулу или рассчитать значение вручную.
⚠️ Внимание: Если документ или справочник ещё не записан в базу, добавленные строки сохранятся только после вызова метода Записать(). В противном случае изменения будут потеряны при закрытии сеанса.

☑️ Проверка перед добавлением строки

Выполнено: 0 / 4

2. Массовое добавление строк: оптимизация производительности

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

Пример оптимизированного кода для добавления 100 строк:

Док = Документы.ПоступлениеТоваров.СоздатьДокумент();

// Отключаем контроль заполнения для ускорения

Док.ОбменДанными.Загрузка = Истина;

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

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

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

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

КонецЦикла;

// Включаем контроль обратно и сохраняем

Док.ОбменДанными.Загрузка = Ложь;

Док.Записать();

Преимущества пакетного режима:

  • 🚀 Ускорение в 5–10 раз за счёт отключения проверок.
  • 🔄 Возможность отката при ошибке (если использовать НачатьТранзакцию()).
  • 📊 Подходит для интеграции с внешними системами (например, 1С:EDI).
Метод добавления Скорость (строк/сек) Подходит для Ограничения
Добавить() в цикле 10–50 Единичные строки Медленно при большом объёме
Пакетный режим 200–500 Массовая загрузка Требует отключения контроля
Запрос ВЫБРАТЬ... ПОМЕСТИТЬ 1000+ Очень большие объёмы Сложный синтаксис
⚠️ Внимание: При пакетном добавлении отключается автоматическая проверка заполнения обязательных реквизитов. Убедитесь, что все критичные поля (например, Номенклатура или Количество) заполнены корректно, иначе документ не проведётся.
💡

Для ускорения массовой загрузки предварительно индексируйте справочники, к которым обращаетесь в цикле. Например, создайте коллекцию СоответствиеКодовНоменклатуры до начала добавления строк.

3. Добавление строки с проверкой на дубли

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

Пример кода с проверкой по полю Номенклатура:

Функция ДобавитьСтрокуБезДублей(Документ, Номенклатура, Количество)

// Ищем существующую строку

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

Если ТекСтрока.Номенклатура = Номенклатура Тогда

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

Возврат Ложь; // Строка уже существовала

КонецЕсли;

КонецЦикла;

// Если не нашли — добавляем новую

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

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

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

Возврат Истина;

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

Где это применимо:

  • 🛒 В документах Заказ клиента или Реализация, где один товар может встречаться несколько раз.
  • 📦 При инвентаризации, когда один и тот же артикул сканируется несколько раз.
  • 🔄 В обменах данными, где возможны повторные записи.
Как проверить дубли по нескольким полям?

Если нужно проверять уникальность по комбинации полей (например, Номенклатура + Характеристика + Серия), модифицируйте условие в цикле: Если ТекСтрока.Номенклатура = Номенклатура И ТекСтрока.Характеристика = Характеристика И ТекСтрока.Серия = Серия Тогда

4. Добавление строк через запрос (для опытных)

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

Пример: добавление строк в табличную часть Товары документа ПоступлениеТоваров на основе остатков на складе:

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

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

"ВЫБРАТЬ

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

| ОстаткиНоменклатуры.КоличествоОстаток КАК Количество

|ИЗ

| РегистрНакопления.ОстаткиНоменклатуры.Остатки КАК ОстаткиНоменклатуры

|ГДЕ

| ОстаткиНоменклатуры.Склад = &Склад

| И ОстаткиНоменклатуры.КоличествоОстаток > 0";

Запрос.УстановитьПараметр("Склад", Склад);

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

Док = Документы.ПоступлениеТоваров.СоздатьДокумент();

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

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

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

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

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

КонецЦикла;

Плюсы подхода:

  • 🔍 Гибкая фильтрация данных перед добавлением.
  • 📈 Возможность агрегировать данные (например, суммировать количество по номенклатуре).
  • 🔗 Удобно для интеграции с другими регистрами или документами.
⚠️ Внимание: Запросы выполняются медленнее, чем прямая работа с объектами, если выборка содержит тысячи строк. В таких случаях лучше использовать ПоместитьВоВременноеХранилище() или разбивать запрос на части.
💡

Запросы идеальны для сложных выборок, но для простого добавления 1–2 строк эффективнее использовать метод Добавить().

5. Работа с табличными частями в управляемых формах

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

Код в модуле формы:

&НаКлиенте

Процедура ДобавитьТовар(Команда)

// Открываем диалог выбора номенклатуры

ПараметрыВыбора = Новый Структура("ТолькоПапки, МножественныйВыбор", Ложь, Ложь);

ДиалогВыбора = Новый ДиалогВыбораНоменклатуры(ПараметрыВыбора);

Если ДиалогВыбора.Выбрать() Тогда

ВыбраннаяНоменклатура = ДиалогВыбора.ВыбранноеЗначение;

ДобавитьСтрокуНаСервере(ВыбраннаяНоменклатура);

КонецЕсли;

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

&НаСервере

Процедура ДобавитьСтрокуНаСервере(Номенклатура)

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

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

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

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

Особенности работы с формами:

  • 🖥️ Клиентские процедуры (&НаКлиенте) отвечают за взаимодействие с пользователем.
  • 🖧 Серверные (&НаСервере) — за манипуляцию данными.
  • 🔄 Для динамического обновления таблицы после добавления используйте ОбновитьФорму().

Если табличная часть отображается в динамическом списке, после добавления строки может потребоваться явное обновление:

Объект.Записать();

ЭлементыФормы.ТабличнаяЧастьТовары.Обновить();

💡

Чтобы избежать мерцания формы при добавлении строк, используйте метод ОтключитьОбработкуСобытий() перед массовым обновлением и ВключитьОбработкуСобытий() после.

6. Типичные ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с проблемами при работе с табличными частями. Вот самые распространённые ошибки и способы их решения:

Ошибка Причина Решение
Объект не найден (Object not found) Попытка добавить строку в несуществующую табличную часть или несохранённый документ. Проверьте, что объект создан (Документы.Имя.СоздатьДокумент()) и записан.
Дублирование строк Отсутствует проверка на существование строки перед добавлением. Используйте цикл проверки (см. раздел 3) или уникальные индексы.
Значение не является значением объекта справочника Попытка присвоить строке несуществующий элемент справочника. Проверяйте существование элемента через Справочник.НайтиПоНаименованию().
Медленная работа при добавлении 1000+ строк Используется Добавить() в цикле без оптимизации. Переходите на пакетный режим или запросы (разделы 2 и 4).

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

  • 💾 Автоматически сохраняйте документ после добавления критических строк (например, через событие ПриИзменении).
  • 🔄 Используйте Транзакция для групповых операций:
НачатьТранзакцию();

Попытка

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

Док.Записать();

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

Исключение

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

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

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

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

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

Принцип тот же, но вместо Документы.Имя.СоздатьДокумент() используйте:

Спр = Справочники.Номенклатура.СоздатьЭлемент();

НоваяСтрока = Спр.ЦеныНоменклатуры.Добавить();

НоваяСтрока.ТипЦены = Справочники.ТипыЦен.Розница;

Не забудьте вызвать Спр.Записать() после заполнения.

Можно ли добавить строку в табличную часть без указания всех реквизитов?

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

Ошибка при записи объекта:

Не заполнено обязательное поле "Номенклатура"

Чтобы временно отключить проверку, используйте:

Док.ОбменДанными.Загрузка = Истина;
Как скопировать строки из одной табличной части в другую?

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

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

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

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

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

КонецЦикла;

Для глубокого копирования (включая реквизиты строк) используйте Копировать():

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

СтрокаИз.Скопировать(НоваяСтрока);

Почему после добавления строки не обновляется форма?

В управляемых формах после изменения данных на сервере нужно явно обновить форму:

Объект.Записать();

ЭлементыФормы.ТабличнаяЧастьТовары.Обновить();

Если используете тонкий клиент, проверьте, что процедура добавления помечена как &НаСервере.

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

Если обработка подключена к документу, используйте:

Док = Документы.Имя.ПолучитьОбъект(СсылкаНаДокумент);

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

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

Процедура ДобавитьСтроку(Документ) Экспорт

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

// ...

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