Строки табличных частей: ввод вручную, подбор и из кода

· 9 мин

Содержание

Строку табличной части документа в 1С добавляют одной командой: клавиша Ins в самой таблице или кнопка «Добавить» в её командной панели. Дальше заполняете колонки — номенклатуру, количество, цену; сумма чаще всего считается сама. Это для пары строк. Когда позиций десятки или сотни, ручной ввод строки за строкой уже не вариант.

Способов заполнить строки на самом деле четыре, и выбор зависит от задачи. Несколько позиций с остатками и ценами — подбор. Повторяющийся набор — копирование строки. Данные из внешней системы — загрузка из Excel . А если заполнение идёт внутри обработки или при проведении — только код. Ниже разберём каждый способ: куда нажимать в «Такси», какие методички объекта использовать в коде и как не посадить производительность на большой таблице.

Речь про 1С 8.3 (платформа 8.3.2x и новее, интерфейс «Такси»). Конкретные кнопки показаны на примере типовых конфигураций — «Бухгалтерия предприятия» 3.0 и «Управление торговлей» 11, но принцип один для любой конфигурации на управляемых формах.

Ввод и правка строк в форме документа

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

  • ➕ Добавить — новая пустая строка в конце. Горячая клавиша Ins.
  • 📋 Скопировать — дублирует текущую строку вместе со значениями. Клавиша F9. Удобно, когда позиции отличаются одним-двумя полями.
  • ❌ Удалить — убирает выделенную строку. Клавиша Del. Чтобы снести сразу несколько — выделите их с зажатым Ctrl или Shift.
  • ↕️ Переместить вверх / вниз — меняет порядок строк. Порядок в документе сохраняется и влияет на печать.

Переход между колонками — Tab (вперёд) и Shift+Tab (назад). Enter в последней колонке строки обычно открывает новую строку — это ускоряет набор с клавиатуры без мыши.

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

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

Подбор номенклатуры: быстрый ввод многих строк сразу

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

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

  • остатки на складе на дату документа;
  • цена из выбранного типа цен (в УТ — вид цен);
  • ранее набранные в этот документ позиции.

Вы отмечаете нужные товары, задаёте количество и цену прямо в форме подбора и переносите всё в документ одной кнопкой. Это и есть «алгоритм автоматического подбора»: программа сама тянет остаток и цену, а вам остаётся количество.

Ещё два механизма быстрого наполнения строк:

  1. Ввод на основании. Из заказа покупателя создаёте реализацию — табличная часть переносится целиком. Команда «Создать на основании» в панели документа-источника.
  2. Заполнить → По поступлению / по заказу. Кнопка «Заполнить» в документе подтягивает строки из связанного документа по заданному правилу.

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

Подбор берёт цену на момент открытия формы. Если цены в базе поменялись после того, как вы начали подбор, перепроверьте колонку «Цена» перед проведением.

Заполнение строк табличной части из кода

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

НоваяСтрока = Документ.Товары.Добавить();
НоваяСтрока.Номенклатура = ВыбраннаяНоменклатура;
НоваяСтрока.Количество   = 10;
НоваяСтрока.Цена         = 150;
НоваяСтрока.Сумма        = НоваяСтрока.Количество * НоваяСтрока.Цена;

Чтобы вставить строку не в конец, а в определённую позицию, используйте Вставить(Индекс):

ПерваяСтрока = Документ.Товары.Вставить(0); // станет первой

Если у вас есть объект-источник с такими же именами реквизитов (например, строка другого документа или элемент справочника), не присваивайте поля по одному — скопируйте совпадающие свойства одной командой:

НоваяСтрока = Документ.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);

ЗаполнитьЗначенияСвойств переносит все реквизиты с одинаковыми именами. Это и короче, и надёжнее: при добавлении новой колонки в обе таблицы код менять не придётся.

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

// ТаблицаТоваров — ТаблицаЗначений с колонками как в табличной части
Документ.Товары.Загрузить(ТаблицаТоваров);

// обратно — выгрузить строки для обработки
ТЗ = Документ.Товары.Выгрузить();

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

Если строки заполняются в коде формы, а не в обработке, обращайтесь к табличной части через реквизит Объект: на управляемой форме сам документ доступен как Объект, и строки добавляют именно к нему — Объект.Товары.Добавить(). Правки сразу отражаются в таблице на экране. Коллекция Элементы — это элементы формы (сама таблица, поля), а не данные; через неё строки не заполняют.

Порядок заполнения строк из кода
Выполнено: 0 / 6

Загрузка строк из Excel и внешних таблиц

Данные от поставщика или из другой программы чаще всего приходят таблицей Excel. Переносить их вручную бессмысленно. Варианты:

Встроенная загрузка в конфигурации. В ряде документов «Бухгалтерии» 3.0 у табличной части есть кнопка «Заполнить → Загрузить из файла» (или «Подобрать из файла»): выбираете .xlsx, сопоставляете колонки файла с реквизитами строки, загружаете. Если в вашем документе такой кнопки нет, смотрите следующий пункт.

Универсальная обработка «Загрузка данных из табличного документа». Это типовая обработка с диска ИТС: открывает Excel как табличный документ, вы вручную задаёте, какая колонка файла в какой реквизит ложится, и выгружаете хоть в справочник, хоть в табличную часть. Один из самых живучих инструментов — работает там, где встроенной кнопки нет.

Программно. Платформа читает .xlsx напрямую через табличный документ:

ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать("C:\Обмен\Товары.xlsx");

Для Строка = 2 По ТабДок.ВысотаТаблицы Цикл   // со 2-й строки, 1-я — шапка
    НоваяСтрока = Документ.Товары.Добавить();
    НоваяСтрока.Номенклатура = НайтиНоменклатуру(ТабДок.Область(Строка, 1).Текст);
    НоваяСтрока.Количество   = Число(ТабДок.Область(Строка, 2).Текст);
КонецЦикла;

Чтение .xlsx напрямую доступно не во всех релизах платформы — в старых работало только с .mxl и .xls (через COM-объект Excel). Если Прочитать падает на вашем сервере, проверьте номер платформы или читайте через COM.

Перед загрузкой подготовьте сам файл, иначе разбор строк собьётся:

  • один лист с данными, без лишних вкладок;
  • одна строка-шапка, без объединённых ячеек над таблицей;
  • колонки в фиксированном порядке — программа читает их по номеру;
  • числовые колонки в числовом формате, без текста и единиц измерения в ячейке.

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

Проверка заполнения реквизитов строк

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

Пустое значение. Функция ЗначениеЗаполнено() возвращает Ложь для пустой ссылки, нуля, пустой даты и пустой строки:

Для Каждого СтрокаТЧ Из Документ.Товары Цикл
    Если НЕ ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
        Сообщить("В строке не заполнена номенклатура");
    КонецЕсли;
КонецЦикла;

Штатная проверка заполнения. У обязательных реквизитов стоит флаг «Проверка заполнения». При интерактивной записи платформа сама проверит их и подсветит проблемные ячейки. В коде это запускается методом ПроверитьЗаполнение() объекта — он собирает ошибки в стандартный механизм сообщений, привязанных к полям формы.

Типичные ошибки заполнения строк и что за ними стоит:

Диагностика: выберите симптом

Не присваивайте «Сумму» на форме напрямую — её считает обработчик события «ПриИзменении» количества и цены. Правильнее менять количество или цену, а сумму пусть считает механизм формы.

Скорость работы с большими табличными частями

На пяти строках разницы нет. На нескольких тысячах неудачный код заполняет таблицу минутами вместо секунд. Что реально ускоряет.

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

// ПЛОХО: запрос в цикле
Для Каждого Стр Из Товары Цикл
    Стр.Цена = ПолучитьЦену(Стр.Номенклатура); // обращение к базе на каждой строке
КонецЦикла;

// ХОРОШО: один запрос, дальше — из соответствия
ЦеныПоТоварам = ПолучитьЦеныОднимЗапросом(СписокНоменклатуры);
Для Каждого Стр Из Товары Цикл
    Стр.Цена = ЦеныПоТоварам[Стр.Номенклатура];
КонецЦикла;

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

Удаляйте строки обратным циклом. При удалении по индексу прямой цикл «ломается»: после удаления строки индексы смещаются. Идите с конца:

Индекс = Товары.Количество() - 1;
Пока Индекс >= 0 Цикл
    Если НЕ ЗначениеЗаполнено(Товары[Индекс].Номенклатура) Тогда
        Товары.Удалить(Индекс);
    КонецЕсли;
    Индекс = Индекс - 1;
КонецЦикла;

Обратите внимание: в 1С оператор Для ... По ... Цикл всегда идёт с шагом +1, перебрать коллекцию в обратную сторону он не умеет — поэтому здесь цикл Пока.

Работайте с колонками, а не со строками, где это уместно. Методы ВыгрузитьКолонку("Номенклатура") и ЗагрузитьКолонку(Массив, "Цена") быстрее поэлементного обхода, когда нужно обработать одно поле по всем строкам.

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

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

Чем «Подбор» отличается от «Добавить»?
«Добавить» создаёт одну пустую строку, значения вводите сами. «Подбор» открывает форму со справочником, остатками и ценами и позволяет перенести сразу много позиций с уже подставленными данными.
Как скопировать всю табличную часть из одного документа в другой в коде?
Выгрузите строки источника в таблицу значений и загрузите в приёмник: Приёмник.Товары.Загрузить(Источник.Товары.Выгрузить()). Колонки должны совпадать по именам.
Почему после загрузки из Excel часть строк без номенклатуры?
Текст из файла не нашёл элемент справочника — чаще всего из-за опечаток, лишних пробелов или разного регистра. Привязывайте поиск к коду, артикулу или штрихкоду и обрезайте пробелы перед сравнением.
Можно ли заполнить строки, не открывая документ на форме?
Да. Получите объект документа по ссылке методом ПолучитьОбъект(), заполните табличную часть в коде и запишите. Форма при этом не нужна — так работают фоновые обработки загрузки.
Как пересчитать сумму по всем строкам после массового изменения цены?
Пройдите по строкам циклом и присвойте Сумма = Количество * Цена для каждой. На форме для этого лучше вызвать штатную процедуру пересчёта, а не присваивать сумму напрямую в обход обработчиков.