Как создать внешнюю обработку для вывода остатков товаров на основе данных из Excel

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

В практике разработчика 1С часто возникает задача интеграции внешних данных с учетной системой. Одной из классических задач является создание обработки, которая считывает список номенклатуры из файла Excel и сопоставляет его с текущими остатками в базе данных на определенную дату. Рассмотрим, как реализовать такую обработку с нуля, разберем методы чтения файлов и научимся выводить результат в структурированный макет.

Постановка задачи и проектирование интерфейса

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

  1. Позволяет пользователю выбрать файл *.xls или *.xlsx.
  2. Принимает дату, на которую нужно получить остатки.
  3. Считывает коды товаров из первой колонки файла.
  4. Находит эти товары в справочнике Номенклатура.
  5. Получает остатки и счета учета для найденных позиций.
  6. Выводит результат в табличный документ через заранее подготовленный макет.

Для реализации интерфейса (если мы работаем в обычных формах, как в примере автора) нам потребуются следующие реквизиты формы:

Реализация выбора файла

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


Процедура ИмяФайлаНачалоВыбора(Элемент, СтандартнаяОбработка)
    
    ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогВыбора.Заголовок = "Выберите файл Excel";
    ДиалогВыбора.Фильтр = "Файлы Excel (*.xls;*.xlsx)|*.xls;*.xlsx";
    
    Если ДиалогВыбора.Выбрать() Тогда
        ИмяФайла = ДиалогВыбора.ПолноеИмяФайла;
    КонецЕсли;
    
КонецПроцедуры

Здесь мы используем объект ДиалогВыбораФайла, устанавливаем фильтр, чтобы пользователь не мог выбрать файлы других форматов, и записываем полный путь в реквизит формы.

Чтение данных из Excel: COM-объект против Табличного документа

Рассмотрим основной этап — получение данных из файла. Автор темы предложил использовать COMОбъект("Excel.Application"). Это мощный инструмент, но он требует установленного Microsoft Excel на компьютере. Выясним преимущества и недостатки этого метода, а также разберем альтернативу.

Способ 1: Использование COM-объекта

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


Функция ПрочитатьExcelЧерезCOM(ПутьКФайлу)
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.Workbooks.Open(ПутьКФайлу);
        Состояние("Обработка файла...");
    Исключение
        Сообщить("Ошибка при открытии Excel: " + ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;

    Лист = Excel.Sheets(1); // Работаем с первым листом
    ВсегоСтрок = Лист.UsedRange.Rows.Count;
    
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("КодТовара", Новый ОписаниеТипов("Строка"));

    Для НомерСтроки = 1 По ВсегоСтрок Цикл
        Код = СокрЛП(Лист.Cells(НомерСтроки, 1).Text);
        Если ЗначениеЗаполнено(Код) Тогда
            НоваяСтрока = ТЗ.Добавить();
            НоваяСтрока.КодТовара = Код;
        КонецЕсли;
    КонецЦикла;

    Excel.Quit();
    Возврат ТЗ;
КонецФункции

Способ 2: Чтение через Табличный документ (рекомендуемый)

В современных конфигурациях 1С 8.3 лучше использовать встроенный метод Прочитать объекта ТабличныйДокумент. Он работает быстрее и не требует наличия стороннего ПО.


ТабДок = Новый ТабличныйДокумент;
Попытка
    ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначений.Значение);
Исключение
    Сообщить("Не удалось прочитать файл!");
    Возврат;
КонецПопытки;

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

Связь данных с объектами 1С и получение остатков

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

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


Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

// Загружаем коды во временную таблицу
Запрос.Текст = 
"ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Коды ИЗ &ТЗ_Кодов КАК ТЗ_Кодов";
Запрос.УстановитьПараметр("ТЗ_Кодов", ТЗ_ПрочитанныхКодов);
Запрос.Выполнить();

// Основной запрос к остаткам
Запрос.Текст = 
"ВЫБРАТЬ
|   ВТ.КодТовара КАК КодИзФайла,
|   Номенклатура.Ссылка КАК Товар,
|   ХозрасчетныйОстатки.Счет КАК СчетУчета,
|   ЕСТЬNULL(ХозрасчетныйОстатки.КоличествоОстаток, 0) КАК Остаток
|ИЗ
|   ВТ_Коды КАК ВТ
|   ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
|       ПО ВТ.КодТовара = Номенклатура.Код
|   ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаОстатков, , , ) КАК ХозрасчетныйОстатки
|       ПО Номенклатура.Ссылка = ХозрасчетныйОстатки.Субконто1";

Запрос.УстановитьПараметр("ДатаОстатков", Новый Граница(КонецДня(Дата), ВидГраницы.Включая));
РезультатЗапроса = Запрос.Выполнить();

Важно помнить: при поиске по коду из Excel могут возникнуть проблемы с типами данных (число или строка). Рекомендуется всегда приводить значения к строке и удалять лишние пробелы с помощью СокрЛП.

Вывод данных в макет

Разберем, как связать результат запроса с визуальным представлением. Создадим в обработке Макет типа "Табличный документ". В нем выделим три области:

  1. Шапка — с заголовком и датой.
  2. Строка — с параметрами: Код, Номенклатура, Счет, Остаток.
  3. Подвал — для итоговых значений.

Рассмотрим пошагово процедуру вывода:


Процедура ВывестиРезультат(РезультатЗапроса)
    
    Макет = ПолучитьМакет("Макет");
    ТабДок = ЭлементыФормы.ПолеТабличногоДокумента; // Или новый документ
    ТабДок.Очистить();
    
    // Выводим шапку
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьШапка.Параметры.ДатаОтчета = Формат(Дата, "ДЛФ=D");
    ТабДок.Вывести(ОбластьШапка);
    
    // Выводим строки
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        ОбластьСтрока.Параметры.Заполнить(Выборка);
        
        Если Выборка.Товар = Неопределено Тогда
            ОбластьСтрока.Параметры.Номенклатура = "ТОВАР НЕ НАЙДЕН";
        КонецЕсли;
        
        ТабДок.Вывести(ОбластьСтрока);
    КонецЦикла;
    
    ТабДок.Показать();
    
КонецПроцедуры

Важные уточнения по оптимизации

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

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

← На главную