Как загрузить данные из Excel в табличную часть документа в 1С:Управление торговлей 10.3

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

Загрузка данных из внешних файлов Excel — одна из самых частых задач, с которыми сталкивается начинающий программист 1С. Особенно это актуально для конфигурации «Управление торговлей 10.3», работающей на обычных формах. В процессе реализации этой задачи новички часто наступают на одни и те же «грабли»: данные перезаписываются, номенклатура не находится, а строки в документе не создаются. В этой статье мы подробно разберем, как правильно организовать чтение файла Excel и перенос данных в табличную часть документа, проанализируем ошибки и оптимизируем код.

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

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

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


// НЕПРАВИЛЬНО:
НоваяСтрока = ТЗ.Добавить(); 
Для Стр = 1 ПО 10 Цикл
    НоваяСтрока.Номенклатура = Эксель.Cells(Стр, 1).Value;
КонецЦикла;

// ПРАВИЛЬНО:
Для Стр = 1 ПО 10 Цикл
    НоваяСтрока = ТЗ.Добавить(); // Строка создается на каждой итерации
    НоваяСтрока.Номенклатура = Эксель.Cells(Стр, 1).Value;
КонецЦикла;

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

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

Разберем, как сделать это правильно через объект документа. В обычных формах (УТ 10.3) мы обращаемся к коллекции табличной части напрямую через ЭтотОбъект или просто по имени табличной части, если код пишется в модуле формы. Рассмотрим по шагам:

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

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

Работа со справочником «Номенклатура»: поиск объектов

Важно понимать, что в Excel хранятся текстовые названия или артикулы, а в табличной части документа 1С поле Номенклатура имеет тип СправочникСсылка.Номенклатура. Мы не можем просто присвоить текстовую строку ссылочному полю. Если мы так сделаем, поле останется пустым или возникнет ошибка типа.

Рассмотрим, как правильно искать номенклатуру по наименованию, которое мы получили из Excel. Для этого используем метод НайтиПоНаименованию(). Также крайне желательно использовать функцию СокрЛП(), чтобы убрать лишние пробелы, которые часто копируются из таблиц.


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

Если НайденнаяСсылка.Пустая() Тогда
    Сообщить("Товар не найден: " + НазваниеИзФайла);
Иначе
    НоваяСтрока.Номенклатура = НайденнаяСсылка;
КонецЕсли;

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

Дополнительные настройки для УТ 10.3 (единицы измерения и НДС)

В конфигурации «Управление торговлей 10.3» простого заполнения номенклатуры и количества недостаточно для корректного проведения документа. У каждой номенклатуры есть базовая единица измерения и ставка НДС. Рассмотрим, что еще нужно добавить в код для полноценной работы:

Проанализируем пример заполнения сопутствующих реквизитов:


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

// Заполняем единицу измерения из карточки номенклатуры
НоваяСтрокаДокумента.ЕдиницаИзмерения = СтрокаТЗ.Номенклатура.ЕдиницаХраненияОстатков;
НоваяСтрокаДокумента.Коэффициент = НоваяСтрокаДокумента.ЕдиницаИзмерения.Коэффициент;

// Подтягиваем ставку НДС
НоваяСтрокаДокумента.СтавкаНДС = СтрокаТЗ.Номенклатура.СтавкаНДС;

НоваяСтрокаДокумента.Количество = СтрокаТЗ.Количество;
НоваяСтрокаДокумента.Цена = СтрокаТЗ.Цена;
// Сумму можно рассчитать программно, чтобы не полагаться только на файл
НоваяСтрокаДокумента.Сумма = НоваяСтрокаДокумента.Количество * НоваяСтрокаДокумента.Цена;

Оптимизация: правильное завершение работы с Excel

При работе через COMОбъект("Excel.Application") часто возникает проблема "висящих" процессов в диспетчере задач. Если процесс не закрыть правильно, файл может оказаться заблокированным для других пользователей, а оперативная память сервера будет переполнена. Выясним, как гарантированно закрыть приложение.

Недостаточно просто вызвать Quit(). Профессиональный подход подразумевает закрытие книги без сохранения изменений и обнуление переменной 1С.


// Закрываем книгу без вопросов о сохранении
Excel.ActiveWorkbook.Close(Ложь);
// Выходим из приложения
Excel.Quit();
// Очищаем переменную для освобождения памяти
Excel = Неопределено;

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

Если в вашем файле Excel не 10 строк, а 1000 или более, обращение к каждой ячейке через Cells(Стр, Кол).Value будет работать крайне медленно. Каждое такое обращение — это вызов через медленный интерфейс COM. Рассмотрим способ ускорения в десятки раз: чтение всего диапазона в массив за один вызов.


// Получаем данные всего листа в двумерный массив 1С
// Предположим, у нас 4 колонки и 1000 строк
ДанныеМассива = Excel.Range(Excel.Cells(1, 1), Excel.Cells(1000, 4)).Value;

// Теперь работаем с обычным массивом, это мгновенно
Для Стр = 1 По 1000 Цикл
    ТекНоменклатура = ДанныеМассива.GetValue(Стр, 1);
    ТекКоличество = ДанныеМассива.GetValue(Стр, 2);
    // ... дальнейшая логика
КонецЦикла;

Подводя итог, скажем, что успешная загрузка данных из Excel в 1С требует внимательного отношения к типам данных и структуре циклов. Всегда проверяйте, создается ли новая строка внутри цикла, очищайте строки от пробелов и не забывайте закрывать COM-объекты после завершения работы. Следуя этим правилам, вы создадите надежный и быстрый инструмент для импорта данных.

← На главную