Загрузка данных из Excel — это одна из самых частых задач, с которыми сталкивается разработчик 1С. Традиционно это решается либо написанием уникальной обработки под каждый файл, либо использованием переусложненных универсальных инструментов. В этой статье мы проанализируем новый подход: разделение общего движка загрузки и прикладного кода. Это позволит вам создать гибкий инструмент, который легко адаптировать под разные задачи, сохраняя при этом общую надежную базу.
Основная проблема большинства самописных загрузок заключается в том, что код чтения файла перемешан с логикой поиска контрагентов, номенклатуры или создания документов. Рассмотрим концепцию, основанную на принципах ООП (объектно-ориентированного программирования), где мы выделяем две независимые части:
ТабличныйДокумент или через COM-соединение, формировать промежуточную таблицу значений (ТЗ), сопоставлять имена колонок из файла с ожидаемыми идентификаторами и предоставлять пользователю интерфейс для настройки.Проанализируем преимущества такого подхода: при изменении формата файла Excel (например, добавилась новая колонка или изменилось имя листа) вам не нужно переписывать алгоритм создания объектов. Вы просто меняете настройки в движке.
Выясним причину, по которой выбор метода чтения критически важен. В современных реалиях 1С (работа в облаках, Linux-серверы, веб-клиент) использование COM-объекта Excel.Application становится проблематичным. Рассмотрим наиболее универсальный способ — использование встроенного метода 1С ТабДок.Прочитать().
Преимущество этого метода в том, что он работает на стороне сервера без установленного Microsoft Office. Однако, проанализируем ситуацию, когда данные в Excel имеют сложную структуру. В таких случаях движок должен уметь:
Разберем по шагам пример кода, который может лежать в основе вашего движка. Мы создаем абстрактный «Читатель», который переводит данные из файла во внутреннюю таблицу значений 1С:
Процедура ЗагрузитьДанныеИзФайла(ИмяФайла)
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяФайла);
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Движок формирует ТЗ на основе сопоставления колонок
ТЗ_Данных = СформироватьТЗПоНастройкам(ТабДок);
// Передаем управление прикладному коду
ВыполнитьПрикладнуюЗагрузку(ТЗ_Данных);
КонецПроцедуры
Одной из ключевых функций «умного» движка является возможность дать пользователю самому выбрать названия и номера колонок, если они не совпали автоматически. Проанализируем, какие опции стоит внедрить в интерфейс:
Чтобы не заставлять пользователя каждый раз настраивать колонки, настройки нужно хранить во внешних файлах или в справочнике. Рассмотрим формат хранения. Хотя JSON является стандартом, в простых случаях можно использовать текстовый формат с разделителями (например, TAB), что упрощает ручное редактирование настроек в блокноте.
Пример структуры настроек для сопоставления:
Поле: Номенклатура
Колонка: А1
Обязательное: Да
Поле: Количество
Колонка: B2
Поле: Цена
Колонка: C3
Когда движок подготовил ТЗ_Данных, прикладной код занимается только бизнес-логикой. Посмотрим на пример функции, которая обрабатывает одну строку данных:
Процедура ОбработатьСтрокуЗагрузки(СтрокаТЗ)
// Поиск номенклатуры по артикулу
СсылкаНоменклатура = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", СтрокаТЗ.Артикул);
Если СсылкаНоменклатура.Пустая() Тогда
// Логика создания, если разрешено настройками движка
НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НовыйОбъект.Наименование = СтрокаТЗ.Наименование;
НовыйОбъект.Записать();
СсылкаНоменклатура = НовыйОбъект.Ссылка;
КонецЕсли;
// Дальнейшая логика (заполнение доп. реквизитов, цен и т.д.)
КонецПроцедуры
Проанализируем ситуацию с ошибками в типовых конфигурациях. Например, в 1С:УНФ при загрузке из табличного документа иногда возникают ошибки определения типов в колонках (особенно с числами и строками). Решением в движке будет принудительное приведение типов при чтении каждой ячейки:
Используйте Строка(Ячейка.Текст) для получения строковых данных без форматирования и очищайте числа от неразрывных пробелов (символ 160), которые Excel часто добавляет в качестве разделителя разрядов.
Разделение движка и прикладного кода позволяет перестать «изобретать велосипед» при каждой новой задаче по импорту. Написав один раз качественный движок, вы сможете добавлять новые виды загрузок за считанные минуты, просто описывая логику поиска объектов в компактном прикладном модуле. Это повышает надежность системы и делает инструмент понятным не только для программиста, но и для конечного пользователя.