Загрузка данных из внешних источников, таких как файлы Microsoft Excel, является одной из самых востребованных задач при автоматизации торговых предприятий. В этой статье мы подробно разберем процесс создания обработки для загрузки прайс-листа в конфигурацию на обычных формах (например, "Управление торговлей 10.3" или "Бухгалтерия предприятия 2.0"). Мы пройдем путь от выбора файла до автоматического создания номенклатуры и регистрации цен.
Прежде чем приступать к написанию кода, определим необходимые элементы управления на форме обработки. Нам понадобятся:
ТипаЦен (ссылка на справочник "Типы цен номенклатуры").СоздаватьНоменклатуру — если товар не найден, программа должна решить, создавать его или игнорировать.Для начала нам нужно позволить пользователю выбрать файл на диске. Рассмотрим правильную реализацию обработчика события НачалоВыбора для поля ввода пути к файлу. Проанализируем типичную ошибку: часто забывают присвоить выбранный путь реквизиту формы, из-за чего в дальнейшем система выдает ошибку "Файл не существует".
Процедура ПутьКФайлуНачалоВыбора(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отключаем стандартный выбор
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл Excel";
Диалог.ПолноеИмяФайла = ПутьКФайлу;
Диалог.Фильтр = "Файлы Microsoft Excel (*.xls;*.xlsx)|*.xls;*.xlsx";
Если Диалог.Выбрать() Тогда
ПутьКФайлу = Диалог.ПолноеИмяФайла; // Сохраняем путь в реквизит формы
КонецЕсли;
КонецПроцедуры
Существует несколько способов прочитать данные. Самый гибкий для обычных форм — использование COM-объекта. Этот метод позволяет обращаться к приложению Excel напрямую, однако он требует наличия установленного Microsoft Office на компьютере пользователя. Рассмотрим функцию, которая открывает книгу и считывает данные с первого листа.
Функция ПрочитатьExcelЧерезCOM(ИмяФайла)
Попытка
Excel = Новый COMОбъект("Excel.Application");
Книга = Excel.WorkBooks.Open(ИмяФайла);
Лист = Книга.Sheets(1); // Работаем с первым листом
Исключение
Сообщить("Не удалось открыть Excel: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
// Определяем границы данных
ВсегоСтрок = Лист.Cells.SpecialCells(11).Row;
ВсегоКолонок = Лист.Cells.SpecialCells(11).Column;
// Создадим таблицу значений для хранения данных в памяти 1С
ТаблицаДанных = Новый ТаблицаЗначений;
Для Кол = 1 По ВсегоКолонок Цикл
ТаблицаДанных.Колонки.Добавить("Колонка" + Кол);
КонецЦикла;
// Читаем строки
Для НомерСтроки = 1 По ВсегоСтрок Цикл
НоваяСтрока = ТаблицаДанных.Добавить();
Для НомерКолонки = 1 По ВсегоКолонок Цикл
Значение = Лист.Cells(НомерСтроки, НомерКолонки).Value;
НоваяСтрока["Колонка" + НомерКолонки] = Значение;
КонецЦикла;
КонецЦикла;
Книга.Close(Ложь);
Excel.Quit();
Возврат ТаблицаДанных;
КонецФункции
Важный совет: Чтение каждой ячейки в цикле может быть медленным на больших файлах. Для оптимизации лучше считывать весь диапазон в массив одним обращением: МассивДанных = Лист.UsedRange.Value. Это значительно ускорит загрузку тысяч строк.
Теперь выясним, как превратить сырые данные из таблицы в реальные объекты 1С. Основная логика заключается в поиске номенклатуры (например, по артикулу или наименованию) и последующем заполнении документа УстановкаЦенНоменклатуры.
Рассмотрим пошаговый алгоритм:
ТипЦен и текущую дату.Справочники.Номенклатура.НайтиПоНаименованию().Товары и заполняем цену.
Процедура ВыполнитьЗагрузку()
ДанныеExcel = ПрочитатьExcelЧерезCOM(ПутьКФайлу);
Если ДанныеExcel = Неопределено Тогда Возврат; КонецЕсли;
ДокОбъект = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
ДокОбъект.Дата = ТекущаяДата();
// В типовых решениях (УТ 10.3) типы цен могут храниться в ТЧ или реквизитах
// Для примера добавим одну строку типа цен
НоваяСтрокаТипа = ДокОбъект.ТипыЦен.Добавить();
НоваяСтрокаТипа.ТипЦен = ВыбранныйТипЦен;
Для Каждого СтрокаТаблицы Из ДанныеExcel Цикл
Артикул = СокрЛП(СтрокаТаблицы.Колонка1);
Наименование = СокрЛП(СтрокаТаблицы.Колонка2);
Цена = Число(СтрокаТаблицы.Колонка3);
Если ПустаяСтрока(Артикул) И ПустаяСтрока(Наименование) Тогда Продолжить; КонецЕсли;
// Поиск номенклатуры
СсылкаНоменклатура = Справочники.Номенклатура.НайтиПоНаименованию(Наименование);
Если СсылкаНоменклатура.Пустая() И СоздаватьНоменклатуру Тогда
НовЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовЭлемент.Наименование = Наименование;
НовЭлемент.Артикул = Артикул;
// Важно заполнить базовые реквизиты: ЕдиницаХраненияОстатков, СтавкаНДС и т.д.
НовЭлемент.Записать();
СсылкаНоменклатура = НовЭлемент.Ссылка;
КонецЕсли;
Если НЕ СсылкаНоменклатура.Пустая() Тогда
НоваяСтрокаТовара = ДокОбъект.Товары.Добавить();
НоваяСтрокаТовара.Номенклатура = СсылкаНоменклатура;
НоваяСтрокаТовара.Цена = Цена;
НоваяСтрокаТовара.ТипЦен = ВыбранныйТипЦен;
КонецЕсли;
КонецЦикла;
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Документ создан: " + ДокОбъект.Ссылка);
КонецПроцедуры
Проанализируем ситуацию, когда на компьютере нет Excel. Платформа 1С 8.3 позволяет прочитать файл напрямую в объект ТабличныйДокумент. Это работает быстрее и стабильнее в многопользовательской среде. Мы можем использовать метод Прочитать(), указав тип файла.
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
Сообщить("Ошибка чтения файла: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Теперь перебираем области табличного документа
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
ТекстЯчейки = ТабДок.Область(НомерСтроки, 1).Текст;
// ... логика обработки ...
КонецЦикла;
При работе с внешними данными важно помнить о "чистоте" входящей информации. Разберем основные моменты, которые могут сломать загрузку:
СтрЗаменить(Текст, Символ(160), " ") перед поиском.Число() внутри блока Попытка...Исключение.Попытка...Исключение, где в блоке Исключение прописано Excel.Quit().НайтиПоНаименованию создаст огромную нагрузку на базу. В таком случае эффективнее сначала выгрузить все артикулы из файла в массив, а затем одним запросом к базе 1С получить все существующие ссылки.Следуя этим шагам, мы создали надежный инструмент для автоматизации рутинной работы. Подобные обработки экономят часы работы менеджеров по закупкам и минимизируют ошибки ручного ввода.