Приемы эффективной загрузки данных из Excel в 1С
Интеграция - Загрузка и выгрузка в Excel
Файлы
ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.
Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний
Оформите подписку на компанию для решения рабочих задач
Оформить подписку и скачать решение со скидкойВы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
В публикации показаны приемы по загрузке данных из файла Excel в таблицу значений..
Протестировано на версии платформы 1С:Предприятие 8.3 (8.3.9.1818).
В версии 8.3 для загрузки из Excel существует альтернатива COM объекту. У табличного документа есть метод Прочитать.
Особенно актуально для файлов больших объемов, т.к. табличный документ обрабатывается гораздо быстрее.
А табличный документ легко трансформируется в таблицу значений через построитель запроса.
Во вложении обработка - пример загрузки и вывода в табличный документ и таблицу значений.
Рабочий код занимает несколько строк:
//Вывод в табличный документ
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.Прочитать(Файл, СпособЧтенияЗначенийТабличногоДокумента.Значение);
//вывод в таблицу значений
ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличныйДокумент.Область());
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();
ТаблицаЗначений = ПЗ.Результат.Выгрузить();
P.S. При выводе в таблицу значений через построитель запроса, названия колонок в источнике данных должны быть первой строкой, иначе построитель не сможет получить и преобразовать их в колонки таблицы значений и выдаст ошибку.
Во внешней обработке демонстрация загрузки.
Вступайте в нашу телеграмм-группу Инфостарт
См. также
Загрузка и выгрузка в Excel Маркетплейсы Разработчик Бухгалтер Пользователь 1С:Предприятие 8 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Управленческий учет Платные (руб)
Реальный помощник, с помощью которого Вы преобразуете необходимые документы для Wildberries, OZON, ЯндексМаркет, ЛаМода, Мегамаркет, Aliexpress, Детский мир, Магнит Маркет (быв.МагнитЭкспресс), Лемана про, ЭНФАНТА (Акушерство), Летуаль, Твой дом, Золотое Яблоко, Каспи, Авито, Аптеки+, М.Видео,Тинькоф в документы "Отчет комиссионера (агента) о продажах" и другие. Работает в 1С:БП 3.0, 1С:БП 3.0 КОРП, 1С:УТ 11, 1С:УНФ, 1С:ERP.
5490 руб.
12.08.2021 48383 654 71
Загрузка и выгрузка в Excel Маркетплейсы Разработчик Бухгалтер Пользователь 1С:Предприятие 8 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Бухгалтерский учет Платные (руб)
Обработки загрузки данных о продажах WildBerries предназначены для следующих конфигураций: Бухгалтерия предприятия, редакция 3.0; Управление нашей фирмой, редакция 3.0; Розница, редакция 3.0; Управление торговлей, редакция 11; Управление торговлей, редакция 10.3
6000 руб.
11.12.2019 67986 1163 3
Загрузка и выгрузка в Excel Розничная торговля Логистика, склад и ТМЦ Ценообразование, анализ цен Прайсы Системный администратор Разработчик 1С:Предприятие 8 1С:Комплексная автоматизация 1.х 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)
Загрузка номенклатуры из файлов Excel (xls, xlsx, ods, csv, mxl) в УТ11, КА 2, ERP 2, Розница 2. Задействованы все возможности конфигурации - заполнение реквизитов номенклатуры, дополнительных реквизитов и сведений, характеристики, доп.реквизиты и сведения характеристик. Дополнительные обработки для расширения возможностей.
12444 руб.
29.10.2014 237818 777 544
Загрузка и выгрузка в Excel Маркетплейсы Разработчик Бухгалтер Пользователь 1С:Предприятие 8 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Бухгалтерский учет Управленческий учет Платные (руб)
Обработки загрузки данных о продажах Ozon предназначены для следующих конфигураций: Бухгалтерия предприятия, редакция 3.0; Управление нашей фирмой, редакция 3.0; Розница, редакция 3.0; Управление торговлей, редакция 11; Управление торговлей, редакция 10.3
6000 руб.
26.11.2020 51234 865 4
SALE! 30%
Загрузка и выгрузка в Excel Оптовая торговля Бухгалтер Пользователь 1С:Предприятие 8 1С 8.3 1С 8.5 1С:Бухгалтерия 2.0 1С:Бухгалтерия 3.0 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление холдингом 1С:Комплексная автоматизация 1.х 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 10 1С:Управление торговлей 11 1С:Розница 2 1С:Розница 3.0 Бухгалтерский учет Управленческий учет Платные (руб)
Загрузка данных из Excel в 1С одним кликом: документы, номенклатура, цены, прайсы и справочники без ручного ввода в УТ, КА, ERP, БП, УНФ и др. Попробуйте демо-версию бесплатно!
8000
7200 руб.
09.11.2016 286039 970 964
SALE! 35%
Загрузка и выгрузка в Excel Учет документов Распознавание документов и образов Бухгалтер Пользователь 1С:Предприятие 8 1С 8.3 1С 8.5 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Розница 2 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление холдингом 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Бухгалтерский учет Управленческий учет Платные (руб)
Программа для распознавания сканов или фотографий товарных документов в 1С. Просто выбираете файл (PDF, XML, JPG, DOC, XLS, HTML) и нажимаете кнопку "Распознать и загрузить".
8540
5551 руб.
04.06.2019 127908 384 183
Загрузка и выгрузка в Excel Разработчик Бухгалтер Пользователь 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Розничная и сетевая торговля (FMCG) Управленческий учет Платные (руб)
Загрузка данных отчета о реализации товаров из сервиса Lamoda «Ламода» для конфигурации: 1С:Бухгалтерия предприятия, редакция 3.0; 1C:Управление торговлей, редакция 11 и 1C:Управление нашей фирмой, редакция 3.0 в документ "Отчет комиссионера (агента) о продажах".
6000 руб.
01.03.2021 13413 88 0
Загрузка и выгрузка в Excel Логистика, склад и ТМЦ Ценообразование, анализ цен Файловый обмен (TXT, XML, DBF), FTP Бухгалтер Пользователь 1С:Предприятие 8 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)
Эволюция не стоит на месте - новая удобная версия функциональной обработки для Вашего бизнеса! Что же Вы получаете? Удобный и интуитивно понятный интерфейс с 3-мя этапами работы. 2 режима - автоматический и ручной. Чтение XLSX, XLSM, CSV, XML/YML форматов без офиса, на любом сервере! Визуальное связывание колонок файла и реквизитов простым перетаскиванием колонок. Создание или обновление номенклатуры с иерархией, характеристик, доп. реквизитов, упаковок, загрузка практически неограниченного количества картинок на одну номенклатуру (с возможностью загрузки в несколько потоков одновременно), с хранением в томах или в базе. Загрузка номенклатуры поставщиков или поиск по их данным номенклатуры. Загрузка доп. реквизитов в характеристики. Загрузка штрихкодов с генерацией новых. Создание элементов справочников и ПВХ "на лету" для выбранных реквизитов. (Обновление от 07.10.2026, версия 9.5.0 - 10.9.0)
20740 руб.
20.11.2015 179802 430 401
Недавно тоже вот перешел на этот способ с ADO.
Разбивать по листам, в принципе, несложно. В загруженном ТабДоке присутствует несколько областей с названиями листов.
В итоге, получилось вот так:
///////////////////////////////////
// Работа с Excel через ТабДок
// Функция - Прочитать excel
//
// Параметры:
// ФайлExcel - Файл, Строка - Объект Файл или полное имя файла.
// ФункцияОбработкиСтрок - Строка, Неопределено - Шаблон выражения для обработки строковых значений ячеек.
// В шаблоне производится подстановка - вместо символа ? будет подставляться обрабатываемое значение строки.
// Если передать Неопределено или пустую строку, то обработка производиться не будет.
// МаксШирина - Число - Максимальное кол-во колонок, просматриваемых при усечении таблицы по ширине.
// ОграничиватьСверху - Булево - Убирать пустые строки сверху
// ОграничиватьСлева - Булево - Убирать пустые строки слева
// ОграничиватьСнизу - Булево - Убирать пустые строки снизу
// ОграничиватьСправа - Булево - Убирать пустые строки справа
//
// Возвращаемое значение:
// СписокЗначений - Список значений содержимого. Элементы списка в поле Значение содержат ячейки листа (объект ОбластьЯчеекТабличногоДокумента), в поле Представление - имя листа
//
Функция ПрочитатьExcel(ФайлExcel, ФункцияОбработкиСтрок = "СокрЛП(?)",
ОграничиватьСверху = Истина, ОграничиватьСлева = Истина, ОграничиватьСнизу = Истина, ОграничиватьСправа = Истина) Экспорт
Ф = НовыйФайл(ФайлExcel);
ВесьТабДок = Новый ТабличныйДокумент();
ВесьТабДок.Прочитать(Ф.ПолноеИмя, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Результат = Новый СписокЗначений;
Области = ВесьТабДок.Области;
Если Области.Количество()=0 Тогда
ВызватьИсключение("В файле нет областей");
КонецЕсли;
Для Каждого Обл Из Области Цикл
ТекТабДок = Новый ТабличныйДокумент;
ОгрОбласть = ПолучитьОграниченнуюОбласть(ВесьТабДок, Обл);
// вставим область в табдок
ОгрОбласть.Имя = Обл.Имя;
ТекТабДок.ВставитьОбласть(ОгрОбласть,
ТекТабДок.Область(1, ОгрОбласть.Лево, ОгрОбласть.Низ - ОгрОбласть.Верх + 1, ОгрОбласть.Право)
);
СократитьСтроки(ТекТабДок, ФункцияОбработкиСтрок);
Результат.Добавить(ТекТабДок, Обл.Имя);
КонецЦикла;
// зачищаем исходный таб док. хз, может лишнее
ВесьТабДок.Очистить();
ВесьТабДок = Неопределено;
Возврат Результат;
КонецФункции
Процедура СократитьСтроки(ТабДок, ФункцияОбработкиСтрок = "СокрЛП(?)")
Если ПустаяСтрока(ФункцияОбработкиСтрок) Тогда
Возврат;
КонецЕсли;
Если Ложь Тогда ТабДок = Новый ТабличныйДокумент; КонецЕсли; // фейк
Для Стр = 1 По ТабДок.ВысотаТаблицы Цикл
Для Кол = 1 По ТабДок.ШиринаСтраницы Цикл
ТекОбласть = ТабДок.Область(Стр, Кол);
ТекстОбласти = ТекОбласть.Текст;
Если Не ТекОбласть.СодержитЗначение И Не ПустаяСтрока(ТекОбласть.Текст) Тогда
Выражение = СтрЗаменить(ФункцияОбработкиСтрок, "?", "ТекстОбласти");
ТекОбласть.Текст = Вычислить(Выражение);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьОграниченнуюОбласть(ТабДок, ОбластьЯчеек,
ОграничиватьСверху = Истина, ОграничиватьСлева = Истина, ОграничиватьСнизу = Истина, ОграничиватьСправа = Истина)
Если Не ОграничиватьСверху И Не ОграничиватьСлева И Не ОграничиватьСправа И Не ОграничиватьСнизу Тогда
Возврат ОбластьЯчеек;
КонецЕсли;
Если Ложь Тогда // фейк
ТабДок = Новый ТабличныйДокумент;
ОбластьЯчеек = ТабДок.Области[0];
КонецЕсли;
Лево = Неопределено; Право = Неопределено; Верх = Неопределено; Низ = Неопределено;
МаксШирина = ТабДок.ШиринаТаблицы;
Для Стр = ОбластьЯчеек.Верх По ОбластьЯчеек.Низ Цикл
Для Кол = 1 По МаксШирина Цикл
ТекОбласть = ТабДок.Область(Стр, Кол);
Если ЭтоЗначащаяОбласть(ТекОбласть) Тогда
Лево = ?(Лево=Неопределено, Кол, Мин(Лево, Кол));
Право = ?(Право=Неопределено, Кол, Макс(Право, Кол));
Верх = ?(Верх=Неопределено, Стр, Верх);
Низ = ?(Низ=Неопределено, Стр, Макс(Низ, Стр));
КонецЕсли;
КонецЦикла;
КонецЦикла;
Результат = ТабДок.Область(
?(ОграничиватьСверху, ?(Верх=Неопределено, ОбластьЯчеек.Верх, Верх), ОбластьЯчеек.Верх),
?(ОграничиватьСлева, ?(Лево=Неопределено, ОбластьЯчеек.Лево, Лево), ОбластьЯчеек.Лево),
?(ОграничиватьСнизу, ?(Низ=Неопределено, ОбластьЯчеек.Низ, Низ), ОбластьЯчеек.Низ),
?(ОграничиватьСправа, ?(Право=Неопределено, ОбластьЯчеек.Право, Право), ОбластьЯчеек.Право)
);
Возврат Результат;
КонецФункции
Функция ЭтоЗначащаяОбласть(ОбластьЯчеек)
Возврат Не ПустаяСтрока(ОбластьЯчеек.Текст)
Или ОбластьЯчеек.Гиперссылка
Или ОбластьЯчеек.СодержитЗначение
//Или ОбластьЯчеек.ГраницаСверху.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
//Или ОбластьЯчеек.ГраницаСнизу.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
Или ОбластьЯчеек.ГраницаСлева.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
Или ОбластьЯчеек.ГраницаСправа.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
;
КонецФункции
// Функция - Текст области листа
// Предполагаем, что имеем дело с ТабДоком, обрезанным по нужным размерам.
// Параметры:
// Лист - ЭлементСпискаЗначений, ТабличныйДокумент - Где искать текст.
// Верх - Число, Неопределено - Верхняя граница области
// Лево - Число, Неопределено - Левая граница области
// Низ - Число, Неопределено - Нижняя граница области
// Право - Число, Неопределено - Правая граница области
//
// Возвращаемое значение:
// Строка - Объединенный текст указанной области. Ячейки по горизонтали разделяются символом ТАБ, строки переносятся ВК
//
Функция ТекстОбластиЛиста(Лист, Знач Верх = Неопределено, Знач Лево = Неопределено, Знач Низ = Неопределено, Знач Право = Неопределено) Экспорт
ТипЗнчЛист = ТипЗнч(Лист);
Если ТипЗнчЛист=КэшФункции.ТипТабличныйДокумент() Тогда
ТабДок = Лист;
ИначеЕсли ТипЗнчЛист=КэшФункции.ТипЭлементСпискаЗначений() Тогда
ТабДок = Лист.Значение;
Иначе
ТабДок = Новый ТабличныйДокумент; // фейк
ВызватьИсключение("Неподдерживаемый тип параметра Лист " + ТипЗнчЛист);
КонецЕсли;
Область = ТабДок.Область(Верх, Лево, Низ, Право);
Результат = "";
ГорРазд = Символы.Таб;
ВертРазд = Символы.ВК;
ОблЛево = ?(Область.Лево=0, 1, Область.Лево);
ОблПраво = ?(Область.Право=0, ТабДок.ШиринаТаблицы, Мин(Область.Право, ТабДок.ШиринаТаблицы));
ОблВерх = ?(Область.Верх=0, 1, Область.Верх);
ОблНиз = ?(Область.Низ=0, ТабДок.ВысотаТаблицы, Мин(Область.Низ, ТабДок.ВысотаТаблицы));
Для Стр=ОблВерх По ОблНиз Цикл
Для Кол=ОблЛево По ОблПраво Цикл
ТекстЯчейки = ТабДок.Область(Стр, Кол).Текст;
ЭтоПустаяЯчейка = ПустаяСтрока(ТекстЯчейки);
Если ЭтоПустаяЯчейка Тогда
ТекстЯчейки = ГорРазд;
КонецЕсли;
Если Кол=ОблПраво И Стр=ОблНиз Тогда
Разделитель = "";
ИначеЕсли Кол=ОблПраво Тогда
Разделитель = ВертРазд;
Иначе
Разделитель = ?(ЭтоПустаяЯчейка, "", ГорРазд);
КонецЕсли;
Результат = Результат + ТекстЯчейки + Разделитель;
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции
Показатьвот так
НаименованиеТовара
Кол_во
ДатаДокумента
Если "123", "124" и т.п., то приемы эффективной загрузки данных из Excel в 1С разбиваются о реальность ))
и еще есть один нюанс. У метода Прочитать есть второй параметр СпособЧтенияЗначений.
<СпособЧтенияЗначений> (необязательный)
Тип: СпособЧтенияЗначенийТабличногоДокумента.
Определяет, каким образом нужно интерпретировать значения, считываемые из исходного документа XLS, XLSX или ODS.
При загрузке табличного документа из формата Excel 97 - 2010 и OpenOffice Calc, в случае если в ячейке исходного документа содержалось значение типа Дата или Число, то в ячейку результирующего табличного документа это значение попадает в зависимости от значения этого параметра.
Значение по умолчанию: Текст.
Время начала чтения табличного документа: 14.12.2017 13:52:46
Время окончания чтения табличного документа: 14.12.2017 13:52:48
Количество секунд чтения: 2
Время начала выгрузки табличного документа в ТЗ: 14.12.2017 13:52:48
Время окончания выгрузки табличного документа в ТЗ: 14.12.2017 13:52:49
Количество строк таблицы значений: 11 874
Количество секунд выгрузки: 1
Если ЛистЭксель = Неопределено Тогда
ЛистЭксель = ПолучитьCOMОбъект(,"Excel.Application");
КонецЕсли;
Если ВсегоСтрок = 0 Тогда
ВсегоСтрок = ЛистЭксель.Cells.SpecialCells(11).Row;
КонецЕсли;
Если ВсегоКолонок = 0 Тогда
ВсегоКолонок = ЛистЭксель.Cells.SpecialCells(11).Column;
КонецЕсли;
Если ТЗ = Неопределено Тогда
ТЗ = Новый ТаблицаЗначений;
Для Счетчик = 1 По ВсегоКолонок Цикл
ТЗ.Колонки.Добавить("Колонка"+Счетчик, Новый ОписаниеТипов("Строка"));
КонецЦикла;
КонецЕсли;
Для Счетчик = НомерПервойСтроки По ВсегоСтрок Цикл
НоваяСтрока = ТЗ.Добавить();
КонецЦикла;
Область = ЛистЭксель.Range(ЛистЭксель.Cells(НомерПервойСтроки,НомерПервойКолонки), ЛистЭксель.Cells(ВсегоСтрок,ВсегоКолонок));
Данные = Область.Value.Выгрузить();
Для Счетчик = 0 По ВсегоКолонок-1 Цикл
ТЗ.ЗагрузитьКолонку(Данные[Счетчик], Счетчик);
КонецЦикла;
ЛистЭксель = Неопределено;
Возврат ТЗ;
КонецФункции
Время начала чтения табличного документа: 14.12.2017 10:24:40
Время окончания чтения табличного документа: 14.12.2017 10:26:31
Количество секунд чтения: 111
Время начала выгрузки табличного документа в ТЗ: 14.12.2017 10:26:37
Время окончания выгрузки табличного документа в ТЗ: 14.12.2017 10:26:49
Количество строк таблицы значений: 1 000 000
Количество секунд выгрузки: 12
Рассмотреть все возможные варианты работы с Excel не являлось целью публикации. Я просто хотел показать как можно с наменьшими затратами, используя код в несколько строк выполнить задачу.
Когда попытался обработать через "прочитать" сохраненную контрагентом печатную форму с графическими объектами, все это дело просто повесилось. Пока что ADO и COM-объекты в таких случаях надежнее.
Насколько я понял, он не требует наличия на компьютере Microsoft Excel или OpenOffice Calc для чтения соответствующих таблиц?
Метод Табличного Документа "Записать" точно не требует, проверено)
Недавно тоже вот перешел на этот способ с ADO.
Разбивать по листам, в принципе, несложно. В загруженном ТабДоке присутствует несколько областей с названиями листов.
В итоге, получилось вот так:
///////////////////////////////////
// Работа с Excel через ТабДок
// Функция - Прочитать excel
//
// Параметры:
// ФайлExcel - Файл, Строка - Объект Файл или полное имя файла.
// ФункцияОбработкиСтрок - Строка, Неопределено - Шаблон выражения для обработки строковых значений ячеек.
// В шаблоне производится подстановка - вместо символа ? будет подставляться обрабатываемое значение строки.
// Если передать Неопределено или пустую строку, то обработка производиться не будет.
// МаксШирина - Число - Максимальное кол-во колонок, просматриваемых при усечении таблицы по ширине.
// ОграничиватьСверху - Булево - Убирать пустые строки сверху
// ОграничиватьСлева - Булево - Убирать пустые строки слева
// ОграничиватьСнизу - Булево - Убирать пустые строки снизу
// ОграничиватьСправа - Булево - Убирать пустые строки справа
//
// Возвращаемое значение:
// СписокЗначений - Список значений содержимого. Элементы списка в поле Значение содержат ячейки листа (объект ОбластьЯчеекТабличногоДокумента), в поле Представление - имя листа
//
Функция ПрочитатьExcel(ФайлExcel, ФункцияОбработкиСтрок = "СокрЛП(?)",
ОграничиватьСверху = Истина, ОграничиватьСлева = Истина, ОграничиватьСнизу = Истина, ОграничиватьСправа = Истина) Экспорт
Ф = НовыйФайл(ФайлExcel);
ВесьТабДок = Новый ТабличныйДокумент();
ВесьТабДок.Прочитать(Ф.ПолноеИмя, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Результат = Новый СписокЗначений;
Области = ВесьТабДок.Области;
Если Области.Количество()=0 Тогда
ВызватьИсключение("В файле нет областей");
КонецЕсли;
Для Каждого Обл Из Области Цикл
ТекТабДок = Новый ТабличныйДокумент;
ОгрОбласть = ПолучитьОграниченнуюОбласть(ВесьТабДок, Обл);
// вставим область в табдок
ОгрОбласть.Имя = Обл.Имя;
ТекТабДок.ВставитьОбласть(ОгрОбласть,
ТекТабДок.Область(1, ОгрОбласть.Лево, ОгрОбласть.Низ - ОгрОбласть.Верх + 1, ОгрОбласть.Право)
);
СократитьСтроки(ТекТабДок, ФункцияОбработкиСтрок);
Результат.Добавить(ТекТабДок, Обл.Имя);
КонецЦикла;
// зачищаем исходный таб док. хз, может лишнее
ВесьТабДок.Очистить();
ВесьТабДок = Неопределено;
Возврат Результат;
КонецФункции
Процедура СократитьСтроки(ТабДок, ФункцияОбработкиСтрок = "СокрЛП(?)")
Если ПустаяСтрока(ФункцияОбработкиСтрок) Тогда
Возврат;
КонецЕсли;
Если Ложь Тогда ТабДок = Новый ТабличныйДокумент; КонецЕсли; // фейк
Для Стр = 1 По ТабДок.ВысотаТаблицы Цикл
Для Кол = 1 По ТабДок.ШиринаСтраницы Цикл
ТекОбласть = ТабДок.Область(Стр, Кол);
ТекстОбласти = ТекОбласть.Текст;
Если Не ТекОбласть.СодержитЗначение И Не ПустаяСтрока(ТекОбласть.Текст) Тогда
Выражение = СтрЗаменить(ФункцияОбработкиСтрок, "?", "ТекстОбласти");
ТекОбласть.Текст = Вычислить(Выражение);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьОграниченнуюОбласть(ТабДок, ОбластьЯчеек,
ОграничиватьСверху = Истина, ОграничиватьСлева = Истина, ОграничиватьСнизу = Истина, ОграничиватьСправа = Истина)
Если Не ОграничиватьСверху И Не ОграничиватьСлева И Не ОграничиватьСправа И Не ОграничиватьСнизу Тогда
Возврат ОбластьЯчеек;
КонецЕсли;
Если Ложь Тогда // фейк
ТабДок = Новый ТабличныйДокумент;
ОбластьЯчеек = ТабДок.Области[0];
КонецЕсли;
Лево = Неопределено; Право = Неопределено; Верх = Неопределено; Низ = Неопределено;
МаксШирина = ТабДок.ШиринаТаблицы;
Для Стр = ОбластьЯчеек.Верх По ОбластьЯчеек.Низ Цикл
Для Кол = 1 По МаксШирина Цикл
ТекОбласть = ТабДок.Область(Стр, Кол);
Если ЭтоЗначащаяОбласть(ТекОбласть) Тогда
Лево = ?(Лево=Неопределено, Кол, Мин(Лево, Кол));
Право = ?(Право=Неопределено, Кол, Макс(Право, Кол));
Верх = ?(Верх=Неопределено, Стр, Верх);
Низ = ?(Низ=Неопределено, Стр, Макс(Низ, Стр));
КонецЕсли;
КонецЦикла;
КонецЦикла;
Результат = ТабДок.Область(
?(ОграничиватьСверху, ?(Верх=Неопределено, ОбластьЯчеек.Верх, Верх), ОбластьЯчеек.Верх),
?(ОграничиватьСлева, ?(Лево=Неопределено, ОбластьЯчеек.Лево, Лево), ОбластьЯчеек.Лево),
?(ОграничиватьСнизу, ?(Низ=Неопределено, ОбластьЯчеек.Низ, Низ), ОбластьЯчеек.Низ),
?(ОграничиватьСправа, ?(Право=Неопределено, ОбластьЯчеек.Право, Право), ОбластьЯчеек.Право)
);
Возврат Результат;
КонецФункции
Функция ЭтоЗначащаяОбласть(ОбластьЯчеек)
Возврат Не ПустаяСтрока(ОбластьЯчеек.Текст)
Или ОбластьЯчеек.Гиперссылка
Или ОбластьЯчеек.СодержитЗначение
//Или ОбластьЯчеек.ГраницаСверху.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
//Или ОбластьЯчеек.ГраницаСнизу.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
Или ОбластьЯчеек.ГраницаСлева.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
Или ОбластьЯчеек.ГраницаСправа.ТипЛинии<>ТипЛинииЯчейкиТабличногоДокумента.НетЛинии
;
КонецФункции
// Функция - Текст области листа
// Предполагаем, что имеем дело с ТабДоком, обрезанным по нужным размерам.
// Параметры:
// Лист - ЭлементСпискаЗначений, ТабличныйДокумент - Где искать текст.
// Верх - Число, Неопределено - Верхняя граница области
// Лево - Число, Неопределено - Левая граница области
// Низ - Число, Неопределено - Нижняя граница области
// Право - Число, Неопределено - Правая граница области
//
// Возвращаемое значение:
// Строка - Объединенный текст указанной области. Ячейки по горизонтали разделяются символом ТАБ, строки переносятся ВК
//
Функция ТекстОбластиЛиста(Лист, Знач Верх = Неопределено, Знач Лево = Неопределено, Знач Низ = Неопределено, Знач Право = Неопределено) Экспорт
ТипЗнчЛист = ТипЗнч(Лист);
Если ТипЗнчЛист=КэшФункции.ТипТабличныйДокумент() Тогда
ТабДок = Лист;
ИначеЕсли ТипЗнчЛист=КэшФункции.ТипЭлементСпискаЗначений() Тогда
ТабДок = Лист.Значение;
Иначе
ТабДок = Новый ТабличныйДокумент; // фейк
ВызватьИсключение("Неподдерживаемый тип параметра Лист " + ТипЗнчЛист);
КонецЕсли;
Область = ТабДок.Область(Верх, Лево, Низ, Право);
Результат = "";
ГорРазд = Символы.Таб;
ВертРазд = Символы.ВК;
ОблЛево = ?(Область.Лево=0, 1, Область.Лево);
ОблПраво = ?(Область.Право=0, ТабДок.ШиринаТаблицы, Мин(Область.Право, ТабДок.ШиринаТаблицы));
ОблВерх = ?(Область.Верх=0, 1, Область.Верх);
ОблНиз = ?(Область.Низ=0, ТабДок.ВысотаТаблицы, Мин(Область.Низ, ТабДок.ВысотаТаблицы));
Для Стр=ОблВерх По ОблНиз Цикл
Для Кол=ОблЛево По ОблПраво Цикл
ТекстЯчейки = ТабДок.Область(Стр, Кол).Текст;
ЭтоПустаяЯчейка = ПустаяСтрока(ТекстЯчейки);
Если ЭтоПустаяЯчейка Тогда
ТекстЯчейки = ГорРазд;
КонецЕсли;
Если Кол=ОблПраво И Стр=ОблНиз Тогда
Разделитель = "";
ИначеЕсли Кол=ОблПраво Тогда
Разделитель = ВертРазд;
Иначе
Разделитель = ?(ЭтоПустаяЯчейка, "", ГорРазд);
КонецЕсли;
Результат = Результат + ТекстЯчейки + Разделитель;
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции
ПоказатьОбласть = ЛистЭксель.Range(...);
Данные = Область.Value.Выгрузить();
Получилось, что второй метод быстрее ADO где то на 25%
Вы не сравнивали метод Range с вашим методом загрузки ? Что быстрее и насколько. Может сравните для полноты ощущений ...?
Тут же в модуле
// Функция - Новый файл
// Создает или переиспользует объект Файл. Для сокращения кол-ва кода. Заодно можно делать проверку существования файла.
// Параметры:
// Файл - Файл, Строка - Если передается объект Файл, то он же и возвращается.
// Если передается Строка (путь), то создается Файл по переданному пути
// ПроверятьСуществование - Булево - Проверять ли существование файла. Если не существует, то идет вызов исключения.
//
// Возвращаемое значение:
// Файл - Созданный или переиспользованный файл
//
Функция НовыйФайл(Файл, ПроверятьСуществование = Истина)
ТипЗнчФайл = ТипЗнч(Файл);
Результат = Неопределено;
Если ТипЗнчФайл=КэшФункции.ТипФайл() Тогда
Результат = Файл;
ИначеЕсли ТипЗнчФайл=КэшФункции.ТипСтрока() Тогда
Результат = Новый Файл(Файл);
Иначе
ВызватьИсключение("Непредусмотренный тип параметра Файл " + ТипЗнчФайл);
КонецЕсли;
Если ПроверятьСуществование=Истина И Не Результат.Существует() Тогда
ВызватьИсключение("Файл не существует");
КонецЕсли;
Возврат Результат;
КонецФункции
ПоказатьА КэшФункции - это модуль, закешированный на сеанс. Там, в том числе, закешированы типы данных:
Функция ТипСтрока() Экспорт
Возврат Тип("Строка");
КонецФункции
Функция ТипДата() Экспорт
Возврат Тип("Дата");
КонецФункции
Функция ТипФайл() Экспорт
Возврат Тип("Файл");
КонецФункции
Функция ТипСтруктура() Экспорт
Возврат Тип("Структура");
КонецФункции
Функция ТипНеопределено() Экспорт
Возврат Тип("Неопределено");
КонецФункции
Функция ТипУникальныйИдентификатор() Экспорт
Возврат Тип("УникальныйИдентификатор");
КонецФункции
Функция ТипЭлементСпискаЗначений() Экспорт
Возврат Тип("ЭлементСпискаЗначений");
КонецФункции
Функция ТипСписокЗначений() Экспорт
Возврат Тип("СписокЗначений");
КонецФункции
Функция ТипТабличныйДокумент() Экспорт
Возврат Тип("ТабличныйДокумент");
КонецФункции
Функция ТипМассив() Экспорт
Возврат Тип("Массив");
КонецФункции
ПоказатьВ общем-то, это вам позор, если вы этого не понимаете.
Твоя функция 5 минут у меня отрабатывает, хотя у меня мощный пк и довольно простой файл (100 колонок 10000 строк) без формул и всякого условного оформления, картинок и прочей лабуды. Файлик менее 1 мегабайта - 5 минут :D
Боюсь представить, как оно будет работать на файле посложнее.
Обмен через Excel вообще был выбран по глупости (да и не мной).
Достаточно чтения в 2 строчки, а СокрП() уже на этапе обработки. Работает, разумеется, в тысячу раз быстрее.
Вообще, чтение Excel через ТабДок уже воспринимаю, как мазохизм. В последних версиях того механизма, для которого все задумывалось, читаем через парсинг XLSX. Если вдруг xls приходит, то сначала конвертируем в xlsx.
Если говорить про загрузку ТабДоком, то ведь и получилось разбить по листам.
С конвертацией (xls в xlsx) сравнительно недавно пришлось заморочиться. Ранее xls читали ado-провайдером. Но недавно начал и он сбоить. Деталей уже не помню... В общем, пришлось и от него отказаться. Ну а конвертацию сделали, чтобы конечное чтение работало только одним механизмом, через парсинг XLSX.
Как-то даже загорелся и начал писать компоненту для прямого чтения XLS/XLSX - есть библиотека от какого-то японца. Но тоже не покатило. Библиотека достаточно старая, выяснилось, что не все формулы (функции) поддерживает. Допиливать еще и формулы уже не влазило во временные рамки.
// Функция - Получить таблицу значений excel
//
// Параметры:
// Лист - ЭлементСпискаЗначений, ТабличныйДокумент - Где искать текст.
// ПоляТолькоПоДокументу - Булево - Если Истина, то создаются поля по верхней строке ТабДока. Если Ложь, то создаются авто-поля Поле[N] по всей ширине ТабДока.
//
// Возвращаемое значение:
// ТаблицаЗначений - ТЗ с данными ТабДока
//
Функция ПолучитьТаблицуЗначенийExcel(Лист, ПоляТолькоПоДокументу = Ложь) Экспорт
Если Истина Тогда
ТабДок = ПолучитьТабДок(Лист);
Иначе
ТабДок = Новый ТабличныйДокумент;
КонецЕсли;
Если ТабДок.ВысотаТаблицы=0 Тогда
Возврат Неопределено;
КонецЕсли;
// вставим заголовки
Если ПоляТолькоПоДокументу=Ложь Тогда
ВерхняяСтрока = ТабДок.Область("R1");
ТабДок.ВставитьОбласть(ВерхняяСтрока, ВерхняяСтрока, ТипСмещенияТабличногоДокумента.ПоВертикали, Ложь);
ВерхняяСтрока = ТабДок.Область("R1");
ВерхняяСтрока.Очистить();
Для Кол=1 По ТабДок.ШиринаТаблицы Цикл
ТабДок.Область(1, Кол).Текст = "Поле" + Формат(Кол, "ЧГ=");
КонецЦикла;
КонецЕсли;
ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();
ТаблицаЗначений = ПЗ.Результат.Выгрузить();
// вставим заголовки
Если ПоляТолькоПоДокументу=Ложь Тогда
ВерхняяСтрока = ТабДок.Область("R1");
ТабДок.УдалитьОбласть(ВерхняяСтрока, ТипСмещенияТабличногоДокумента.ПоВертикали);
КонецЕсли;
Возврат ТаблицаЗначений;
КонецФункции
Функция ПолучитьТабДок(Лист)
ТипЗнчЛист = ТипЗнч(Лист);
Если ТипЗнчЛист=КэшФункции.ТипТабличныйДокумент() Тогда
ТабДок = Лист;
ИначеЕсли ТипЗнчЛист=КэшФункции.ТипЭлементСпискаЗначений() Тогда
ТабДок = Лист.Значение;
Иначе
ВызватьИсключение("Неподдерживаемый тип параметра Лист " + ТипЗнчЛист);
КонецЕсли;
Возврат ТабДок;
КонецФункции
ПоказатьЕсть метод:
Область = ЛистЭксель.Range(...);
Данные = Область.Value.Выгрузить(); Вы не сравнивали метод Range с вашим методом загрузки ? Что быстрее и насколько ?
Данные = Область.Value.Выгрузить();
Попробовал на 1 млн. строк.
Время выполнения чтения файла вашим методом 36 сек. Время выполнения методом описанным в моей публикации 193 сек. Разница в 5 раз :) Но ваш метод возвращает массивы значений, надо попробовать их разобрать.
Так-то COMSAfeArray, создаваемый в OLE.Value, вообще размером 2,5 млн строк на 100 тыс исходных в эксель (возьмем 25 колонок в исходном файле).
А это уже - серьезные объемы для 1С, а у вас - никаких проблем, все грузится, утечек, вылетов по памяти - нет, OLE.Value.Выгрузить() - грузит миллионы строк...
Что-то слишком у вас все радужно, что даже становится сомнительно по поводу проводимых измерений, и реальных прогружаемых объемов.
Гиперссылка представляет из себя URL на картинку на сайте (прилагаю для примера кусочек такого файла).
Кому-нибудь удалось получить URL гиперссылки из подобного файла?
Я думаю, что построитель некорректно обработает такую шапку. Лучше чтобы шапка была в одну строку.
Построитель положу в копилочку решений с простыми шапками, для этой попробую COM или ТабличныйДокумент =)
справка из СП
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
И чтобы первая строка с названиями колонок это были не названия колонок а первая строка таблицы значений?
Надо для совместимости функционала загрузки из табличного документа.
Спасибо.
ТабДок.ВставитьОбласть(ТабДок.Область("R1"), ТабДок.Область("R2"),
ТипСмещенияТабличногоДокумента.ПоВертикали);
ТабДок.Область("R1C1").Текст = "Артикул";
ТабДок.Область("R1C2").СодержитЗначение = Ложь;
ТабДок.Область("R1C2").Текст = "Количество";
Артикул Количество
Арт1 5
Арт2 5
Арт3 4
ТабДок = Новый ТабличныйДокумент;
Ф=Файл;
ТабДок.Прочитать(Ф, СпособЧтенияЗначенийТабличногоДокумента.Значение);
ТабДок.ВставитьОбласть(ТабДок.Область("R1"), ТабДок.Область("R2"),
ТипСмещенияТабличногоДокумента.ПоВертикали);
ТабДок.Область("R1C1").Текст = "Артикул";
ТабДок.Область("R1C2").СодержитЗначение = Ложь;
ТабДок.Область("R1C2").Текст = "Количество";
ПоказатьВы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 714988
Создание 13.12.17 11:36
Обновление 13.12.17 11:36
Просмотры 143894
Загрузки 251
Рейтинг
278
Комментарии 111
Код открыт Да
Рубрики Загрузка и выгрузка в Excel
Кому Разработчик
Тип файла Внешняя обработка (ert,epf)
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Не имеет значения
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Абонемент ($m)