В практике разработчика 1С часто возникает задача интеграции внешних данных с учетной системой. Одной из классических задач является создание обработки, которая считывает список номенклатуры из файла Excel и сопоставляет его с текущими остатками в базе данных на определенную дату. Рассмотрим, как реализовать такую обработку с нуля, разберем методы чтения файлов и научимся выводить результат в структурированный макет.
Прежде чем приступать к написанию кода, проанализируем требования. Нам необходимо создать внешнюю обработку, которая:
Номенклатура.Для реализации интерфейса (если мы работаем в обычных формах, как в примере автора) нам потребуются следующие реквизиты формы:
ИмяФайла (тип: Строка) — для хранения пути к выбранному документу.ДатаОстатков (тип: Дата) — дата, на которую будет строиться отчет.ТаблицаДанных (тип: ТаблицаЗначений) — для промежуточного хранения прочитанных из Excel данных.Для того чтобы пользователь мог комфортно выбрать файл, разберем использование стандартного диалога выбора. Проанализируем следующий код:
Процедура ИмяФайлаНачалоВыбора(Элемент, СтандартнаяОбработка)
ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбора.Заголовок = "Выберите файл Excel";
ДиалогВыбора.Фильтр = "Файлы Excel (*.xls;*.xlsx)|*.xls;*.xlsx";
Если ДиалогВыбора.Выбрать() Тогда
ИмяФайла = ДиалогВыбора.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
Здесь мы используем объект ДиалогВыбораФайла, устанавливаем фильтр, чтобы пользователь не мог выбрать файлы других форматов, и записываем полный путь в реквизит формы.
Рассмотрим основной этап — получение данных из файла. Автор темы предложил использовать 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).Текст;
// ... логика обработки
КонецЦикла;
После того как коды загружены в таблицу значений, нам нужно найти ссылки на номенклатуру и получить остатки. Разберем ситуацию на примере бухгалтерского учета, так как в задании упоминается "счет". Проанализируем использование запроса с временными таблицами — это самый эффективный способ.
Выясним, как работает запрос. Сначала мы помещаем список кодов во временную таблицу, затем соединяем ее со справочником и виртуальной таблицей остатков.
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
// Загружаем коды во временную таблицу
Запрос.Текст =
"ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Коды ИЗ &ТЗ_Кодов КАК ТЗ_Кодов";
Запрос.УстановитьПараметр("ТЗ_Кодов", ТЗ_ПрочитанныхКодов);
Запрос.Выполнить();
// Основной запрос к остаткам
Запрос.Текст =
"ВЫБРАТЬ
| ВТ.КодТовара КАК КодИзФайла,
| Номенклатура.Ссылка КАК Товар,
| ХозрасчетныйОстатки.Счет КАК СчетУчета,
| ЕСТЬNULL(ХозрасчетныйОстатки.КоличествоОстаток, 0) КАК Остаток
|ИЗ
| ВТ_Коды КАК ВТ
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО ВТ.КодТовара = Номенклатура.Код
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаОстатков, , , ) КАК ХозрасчетныйОстатки
| ПО Номенклатура.Ссылка = ХозрасчетныйОстатки.Субконто1";
Запрос.УстановитьПараметр("ДатаОстатков", Новый Граница(КонецДня(Дата), ВидГраницы.Включая));
РезультатЗапроса = Запрос.Выполнить();
Важно помнить: при поиске по коду из Excel могут возникнуть проблемы с типами данных (число или строка). Рекомендуется всегда приводить значения к строке и удалять лишние пробелы с помощью СокрЛП.
Разберем, как связать результат запроса с визуальным представлением. Создадим в обработке Макет типа "Табличный документ". В нем выделим три области:
Код, Номенклатура, Счет, Остаток.Рассмотрим пошагово процедуру вывода:
Процедура ВывестиРезультат(РезультатЗапроса)
Макет = ПолучитьМакет("Макет");
ТабДок = ЭлементыФормы.ПолеТабличногоДокумента; // Или новый документ
ТабДок.Очистить();
// Выводим шапку
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.ДатаОтчета = Формат(Дата, "ДЛФ=D");
ТабДок.Вывести(ОбластьШапка);
// Выводим строки
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
ОбластьСтрока.Параметры.Заполнить(Выборка);
Если Выборка.Товар = Неопределено Тогда
ОбластьСтрока.Параметры.Номенклатура = "ТОВАР НЕ НАЙДЕН";
КонецЕсли;
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
ТабДок.Показать();
КонецПроцедуры
Проанализируем несколько моментов, которые сделают вашу обработку профессиональной:
ОбработкаПрерыванияПользователя() внутри циклов, чтобы 1С не "зависала".Исключение или в конце процедуры вы вызываете Excel.Quit(). В противном случае в диспетчере задач будут копиться процессы excel.exe, потребляющие память сервера..Text, а не .Value.Таким образом, мы рассмотрели полный цикл создания обработки: от выбора файла до формирования печатной формы. Этот алгоритм является универсальным и может быть адаптирован для любых задач по загрузке данных из внешних источников в систему 1С:Предприятие.