При работе с платформой «1С:Предприятие» программисты часто сталкиваются с необходимостью быстрого импорта данных из внешних файлов, таких как Excel. Стандартным инструментом для этого является обработка «Загрузка данных из табличного документа», однако в некоторых случаях эффективнее использовать готовый инструмент для импорта данных, поддерживающий форматы xls, xlsx, ods и другие. При работе с регистрами сведений пользователи часто обнаруживают неприятные особенности: необходимость наличия хотя бы одного измерения и автоматическое упорядочивание записей, которое может нарушить исходную структуру данных из файла. Рассмотрим, как решить эту проблему, сохранив порядок «как в Excel», и разберем альтернативные способы загрузки.
Для начала проанализируем ситуацию с точки зрения теории платформы. Регистр сведений — это прикладной объект, предназначенный для хранения многомерных данных. В отличие от справочников, у него нет стандартных полей Код или Наименование, а его уникальность определяется набором измерений.
Выясним причину, почему типовая обработка ведет себя именно так:
Если перед нами стоит задача разовой загрузки в рамках проекта со строгими сроками, и мы не хотим тратить время на написание собственного кода, можно воспользоваться методом, предложенным в ходе обсуждения. Для регистров же суть заключается в том, чтобы привести структуру Excel-файла в соответствие с требованиями объектной модели 1С.
Разберем этот метод по шагам:
НомерСтроки.=СТРОКА(). Это позволит нам пронумеровать все позиции «как есть».НомерСтроки и типом Число.НомерСтроки с соответствующим измерением регистра.Таким образом, мы решаем сразу две задачи: удовлетворяем требование обработки о наличии измерения и фиксируем порядок строк. При извлечении данных из регистра нам достаточно будет просто установить сортировку по полю НомерСтроки.
Если типовая обработка не подходит по функционалу или требуется автоматизировать процесс для регулярного использования, наиболее эффективным решением будет написание собственной небольшой процедуры. В качестве отправной точки можно использовать шаблон простой обработки загрузки из excel, который легко адаптировать под свои нужды.
Проанализируем ситуацию: для экономии времени можно скопировать содержимое Excel прямо в макет обработки или прочитать файл в объект ТабличныйДокумент. Посмотрим на пример реализации:
Процедура ЗагрузитьДанныеИзExcel(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу);
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
ВысотаТаблицы = ТабДок.ВысотаТаблицы;
// Начинаем со второй строки, предполагая, что первая - заголовок
Для Инд = 2 По ВысотаТаблицы Цикл
// Создаем менеджер записи для каждой строки
МенеджерЗаписи = РегистрыСведений.ИмяВашегоРегистра.СоздатьМенеджерЗаписи();
// Читаем данные из колонок ТабДока
МенеджерЗаписи.Измерение1 = СокрЛП(ТабДок.Область(Инд, 1).Текст);
МенеджерЗаписи.Ресурс1 = ТабДок.Область(Инд, 2).Текст;
// Если мы добавили искусственное измерение НомерСтроки:
МенеджерЗаписи.НомерСтроки = Инд;
Попытка
МенеджерЗаписи.Записать(Истина); // Истина - замещать существующую запись
Исключение
Сообщить("Ошибка в строке " + Инд + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Сообщить("Загрузка завершена!");
КонецПроцедуры
Использование метода СоздатьМенеджерЗаписи() удобно для простых случаев, когда объем данных невелик. Если же строк десятки тысяч, использование менеджера записи в цикле будет работать медленно.
Для ускорения процесса загрузки в проектах, где важна производительность, рекомендуется использовать РегистрСведенийНаборЗаписей. Это позволит записать данные «порциями» или одним махом. Для предварительного анализа данных перед записью может пригодиться портативная обработка чтения файла в таблицу, позволяющая манипулировать данными прямо в консоли кода.
Рассмотрим подробнее, как применить этот механизм. В режиме загрузки данных из внешнего источника крайне важно использовать свойство ОбменДанными.Загрузка = Истина. Это отключает проверки в модуле набора записей, ускоряя процесс и помогая избежать блокировок.
Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
// Если нужно полностью заменить данные, фильтр не ставим,
// но вызываем Набор.Записать() в конце.
Для Инд = 2 По ВысотаТаблицы Цикл
НоваяЗапись = Набор.Добавить();
НоваяЗапись.Измерение1 = ТабДок.Область(Инд, 1).Текст;
НоваяЗапись.Ресурс1 = ТабДок.Область(Инд, 2).Текст;
НоваяЗапись.НомерСтроки = Инд;
КонецЦикла;
Набор.ОбменДанными.Загрузка = Истина;
Набор.Записать();
Начиная с версии платформы 8.3.6, у разработчиков появились мощные встроенные инструменты для работы с файлами .xlsx. Если вам требуется поддержка нескольких листов или работа с CSV, рекомендуем обратить внимание на универсальную загрузку файлов Excel и CSV, которая возвращает коллекцию листов в виде таблиц значений — для этого подойдёт универсальная загрузка данных из Excel и CSV.
Рассмотрим, какие методы чтения наиболее актуальны сегодня:
ТабличныйДокумент.Прочитать(). Это самый современный и безопасный способ. Он не требует установленного Microsoft Office на сервере или клиенте, работает очень быстро и стабильно.SELECT * FROM [Лист1$] можно сразу отфильтровать пустые строки или выбрать конкретные колонки. Этот метод требует наличия установленных драйверов доступа к данным (ACE OLEDB).Проанализировав проблему, мы выяснили, что «непредсказуемое» поведение штатной обработки при загрузке в регистр сведений продиктовано самой архитектурой этого объекта в 1С. Чтобы успешно выполнить задачу, мы можем:
Помните, что регистр сведений — это не просто таблица, а ключ-значение, где ключом является совокупность измерений. Грамотное проектирование структуры регистра на этапе разработки избавит вас от проблем с загрузкой в будущем.