Преобразование EXCEL в таблицу значений без COM и других извращений


Получение таблицы значений из excel в 1С v8, без COM, внешних источников данных и т.д.
EXCELВТаблицуЗначений() — За 10 строчек кода!
Реализация протестирована на 1С 8.3.12.1714 (x64).

WARNING

Данная статья не претендует на оригинальность и не является конечным решением.

Подходы решения задач и примеры программного кода несут исключительно обучающий характер.

 

 

 

 

Существует масса подходов загрузки данных из EXCEL в 1С. Большинство решений основаны на COM или еще более сложных возможностях платформы.

Для себя разработал наиболее оптимальный вариант:
EXCEL -> Табличный документ -> Построитель запроса -> Таблица значений

Итак, приступим:

  1. Прочитать Excel файл на клиенте, для передачи на сервер: 
    &НаКлиенте
    Процедура ЗагрузитьEXCEL(Команда)
    
    Файл = Новый Файл(ПутьКEXCEL);
    Если НЕ Файл.Существует() Тогда
    Возврат;
    КонецЕсли;
    ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКEXCEL);
    ДокументРезультат = EXCELВТаблицуЗначений(ДвоичныеДанные, Файл.Расширение);
    ДокументРезультат.Показать();
    
    КонецПроцедуры

     

  1. Выполнить чтение Excel в таблицу значений: 
    &НаСервере
    Функция EXCELВТаблицуЗначений(ДвоичныеДанные, Расширение)
    
    ФайлEXCELНаСервере = ПолучитьИмяВременногоФайла(Расширение);
    ДвоичныеДанные.Записать(ФайлEXCELНаСервере);
    
    ТабличныйДокумент = Новый ТабличныйДокумент;
    ТабличныйДокумент.Прочитать(ФайлEXCELНаСервере);
    УдалитьФайлы(ФайлEXCELНаСервере);
    ОбластьТаблицы = ТабличныйДокумент.Область(8, 1, ТабличныйДокумент.ВысотаТаблицы, ТабличныйДокумент.ШиринаТаблицы);
    
    ПостроительЗапроса = Новый ПостроительЗапроса;
    ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьТаблицы);
    ПостроительЗапроса.Выполнить();
    ТаблицаДанных = ПостроительЗапроса.Результат.Выгрузить();
    
    // теперь поссмторим что в Таблице
    Возврат ТаблицаЗначенийВТабличныйДокумент(ТаблицаДанных);
    
    КонецФункции 

     

  2. Визуализировать таблицу значений: 

    &НаСервереБезКонтекста
    Функция ТаблицаЗначенийВТабличныйДокумент(ТаблицаДанных)
    
    ПостроительОтчета = Новый ПостроительОтчета;
    ПостроительОтчета.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаДанных);
    ДокументРезультат = Новый ТабличныйДокумент;
    Построительотчета.Вывести(ДокументРезультат);
    Возврат ДокументРезультат;
    
    КонецФункции

     

Описание преобразования данных:

  1. Получаем исходный файл на клиенте;
  2. На основании файла создаем двоичные данные и получаем расширение файла;
  3. Передаем двоичные данные на сервер;
  4. Создаем дубль файла excel на сервере;
  5. Читаем файл в новый табличный документ;
  6. Получаем область табличного документа, где находятся полезные данные (ТабличныйДокумент.Область(8, 1, ТабличныйДокумент.ВысотаТаблицы, ТабличныйДокумент.ШиринаТаблицы));
  7. Создаем новый построитель запроса и установим в качестве источника данных — область полезных данных;
  8. Выполним построитель и получим результат запроса;
  9. Результат запроса выгрузим в таблицу значений.

Плюсы реализации:

  • Скорость работы по сравнению с COM EXCEL
  • Возможно выполнять загрузку где EXCEL нет вообще (MAC | LINUX | etc…)
  • Простота реализации

41 Comments

  1. A_Max

    Не нужно плодить временные сущностифайлы!

    ФайлEXCELНаСервере = ПолучитьИмяВременногоФайла(Расширение);
    ДвоичныеДанные.Записать(ФайлEXCELНаСервере);
    ТабличныйДокумент.Прочитать(ФайлEXCELНаСервере);
    УдалитьФайлы(ФайлEXCELНаСервере);

    Заменить на одну строку:

    ТабличныйДокумент.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения())
    Reply
  2. hillsnake

    ни фига себе , я тут сидел изучал Адо , как преобразовать xlsx в xml … все тлен ..

    Автор гений Спасибо.

    Reply
  3. nikita0832

    (2)через поток читает только ods и mxl, к сожалению.

    Reply
  4. nikita0832
    Reply
  5. nikita0832

    (5)поясню: листы перечислены в областях документа, сортировать их можно по признаку «Верх» , т.е. где он начинается. Есть так же многоэтажные шапки, которые часто делают Экселеводы, для них сделал отдельную функцию. Ещё метод прочитать может читать как ячейки как строку, а может с теми типами, которые указаны в экселе(но это рисково, надо контролировать, особенно если надо использовать эту таблицу в запросе).

    Reply
  6. Lapitskiy

    Это работает только для xlsx

    К сожалению, xls не прочитает.

    Вот здесь человек проделал огромный труд, читайте: https://infostart.ru/public/120961/

    Reply
  7. logarifm

    (0) О Боже автор наконец-то освоил уже устаревший метод Прочитать!

    Reply
  8. logarifm

    (7) С какого это перепуга не сработает. Все прекрасно там работает!

    Reply
  9. ksnik

    Метод1С «Прочитать эксель в табличный документ» намертво на несколько часов виснет если на одном из листов >30000 строк, в этом случае весь документ не доступен и работать не возможно, поэтому «прочитать» можно использовать только для маленьких файлов. А для больших — можно делать на основе быстрого парсера https://infostart.ru/public/139556/

    (7) при условии если не хотим убить сутки на разбирательство с https://infostart.ru/public/120961/ которую рядовые пользователи не смогут осилить

    Reply
  10. Crazy_Max

    Ну что за грязь! Назвать функцию «EXCELВТаблицуЗначений», а возвращать из неё «ТабличныйДокумент»…

    Тем более, что статья писана для начинающих, и это обязательно будет вводить их в ступор и/или приучать к бардаку в коде.

    Ну раз уж выложили свою статью на всеобщий суд, так хоть немного причешите код, что ли…

    Reply
  11. Lapitskiy

    вот тут всё давно разобрано: https://infostart.ru/public/341855/

    Reply
  12. 1Cappldev

    (12) Добрый день! Сухая критика автора ни к чему не приведёт. Вот что действительно поможет комьюнити, напишете как сделали бы Вы, или поделитесь полезными ссылочками дабы предотвратить бардак в коде.

    Reply
  13. qwinter

    (8) Больше поражает сколько плюсов статья получила))

    Reply
  14. batsy66

    (11) Если количество листов в документе больше 20, то так же виснет намертво

    Reply
  15. ksnik

    (13) она универсальная, а не заточенная под конкретную задачу, если и удастся самому приложив усилия импортировать конкретный документ и все сопутствующие справочники и регистры сведений, то никак не получится заставить ей пользоваться рядовых пользователей в ежедневной рутинной работе.

    Reply
  16. Crazy_Max

    (14) А как мне еще «размочить» критику? Я указал на конкретную, грубую ошибку, заключающуюся в том, что наименование основной функции описывает один ТИП возвращаемого значения, а по факту возвращает ДРУГОЙ ТИП значения. Исполняться такой код будет, но ведь исполнение кода не является единственным критерием оценки его качества.

    Как в том афоризме: «он — начинающий программист, и пока еще кодит под себя»…

    Reply
  17. veri123

    (9) А что плохого в построителе?

    Reply
  18. kembrik

    (9) Отнюдь, удобней способа выгрузить табличный документ в ТЗ и наоборот ещё поискать

    Reply
  19. Serg O.

    А как насчет метода копипаста? Почему то никто тут про него не вспоминает…. Самый быстрый способ, под winwows так точно. через Буфер обмена можно под wsShell отправкой ctrl+C потом в своей таблице ctrl + V или «стандартными» методами Excel — select — copy. Потом в 1с из буфера вставить… Так независимо от версии 1с… Хоть с 8.1 и то работает…

    Есть минус… Excel. Или хотя бы OpenOffice должен быть установлен.… 2) должно быть открыто, моргает при открытии 3) при многократной (более 20) вставке… Exсel умирает… ошибка завершения, а процесс остаётся висеть

    Reply
  20. DanDy

    Почему нельзя вынести работу с файлом на клиент? А уже полученный Табличный документ передать на сервер? Тогда временный файл вроде как не нужен

    Reply
  21. Rustig

    (21)

    Есть минус… Excel. Или хотя бы OpenOffice должен быть установлен.…

    я на платформе 8.3.13 из 1с просто открыл файл эксель (через меню Файл-Открыть) — открылся табличный документ mxl.

    при этом эксель не был установлен на компе.

    а так как я не использую чтение эксель, а использую для обработки информации mxl, то мне этого достаточно (можете мои загрузки из эксель поизучать)

    Reply
  22. Rustig

    (9) 1. в защиту ПостроителяЗапроса — вот моя разработка https://infostart.ru/public/933060/ — которая использует ПостроительЗапроса — реализовал полгода назад — считаю объект ПостроительЗапроса — очень интересным и малоизученным программистами

    2.

    В 8.3 использовать построитель это уже

    8.3 — это платформа — у меня все программы на обычных формах работают на 8.3 — ут 10.3, бп 2.0.

    в ут 10.3 до сих пор многие механизмы на ПостроителеЗапроса — к примеру, отчеты или отборы в документе Инвентаризация товаров.

    Reply
  23. Rustig

    (11) спасибо за информацию! значит используем предложенный способ для небольших списков товаров — к примеру, при загрузке приходных накладных — к примеру в небольшом магазине игрушек…

    Reply
  24. Rustig

    (14) критика обидна, поскольку в такой критикующей форме идет общение, но раз другой нет — то приходится учиться принимать ее в таком виде — в результате, если автор услышит суть, уберет эмоции критикующего, то ему будет полезно.

    Reply
  25. Rustig

    (15) загрузка из Эксель одна из самых популярных задач — не зря же 1С развивает эту тему….поэтому любые нововведения встречают на «ура»

    Reply
  26. pbabincev

    ОбластьТаблицы = ТабличныйДокумент.Область(8, 1, ТабличныйДокумент.ВысотаТаблицы, ТабличныйДокумент.ШиринаТаблицы);



    ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьТаблицы);

    А что, так можно было?)

    Не знал, спасибо, автор)

    Reply
  27. pbabincev

    (22)

    Это уже детали.

    Автор хотел донести общую суть самого простого способа загрузки из Excel.

    Reply
  28. d.zhukov

    — Старые форматы excel не прочитает.

    — Открытый файл не прочитает.

    — Ну и на а 8.2, разумеется, не заработает.

    Reply
  29. DanDy

    (29)

    Когда однажды столкнешься с проблемой доступа к файлу на сервере, по пути выбранном на клиенте, тогда поймешь что «детали» и работоспособность на файловом и клиент-серверном варианте это разные вещи

    Reply
  30. ksnik

    Данное решение не пригодно для больших таблиц потому что платформа 1С8 пока не умеет работать с табличными документами так же быстро как это делает Эксель. Данное решение пригодно исключительно для мелких файлов.

    Reply
  31. Yashazz

    (15) Ну дык примитив всегда поражает воображение: «всего N строчек и вау-вау!». А про нормальную работу через ADO итд автор не знает, да и специфику внутренних преобразований эксельных таблиц внутри платформы никто не знает точно. Зато вау.

    Reply
  32. Yashazz

    (9) Это ещё автор не в курсе, какие у построителя ограничения по производительности, да как он обойдётся с ячейками сложных форматов, да что будет делать с объединёнными областями… Гы, много автору суждено открытий чудных. И тем, кто повёлся на этот способ, тоже)

    Reply
  33. Yashazz

    (24) Соглашусь. Построитель иногда очень эффективен. И я в своё время его много изучал, и сейчас использую. Любой инструмент должен быть адекватен своему контексту применения.

    Reply
  34. Yashazz

    Попиарюсь: https://infostart.ru/public/312528/

    Reply
  35. skv_79

    Отличная реализация частой задачи!

    Reply
  36. kuzyara

    Можно читать и через ТабДок, но есть ньюансы.

    Reply
  37. AllexSoft

    (9) Построитель запроса (не путать с построителем отчета!!) очень даже хороший инструмент, незаслуженно обделенный вниманием. Позволяет по сути уйти от всеми нами «любимых» СтрЗаменить или склеек условий. Построитель запроса это младший брат СКД, никто не ругается же на СКД в 1С.

    Reply
  38. Yashazz

    (38) а про нюансы люди сами узнают, когда попытаются это применить))) плюсов, смотрю, вообще уже запредельное количество. Как и желающих с размаху встать на грабли)

    Reply
  39. AllexSoft

    Плюсанул только за функцию ТаблицаЗначенийВТабличныйДокумент, как то запамятовал что построитель отчета может по таблице значений выводить табличный документ. Иногда нужно вывести какую нибудь простенькую таблицу ошибок обработки например или какую нибудь отладочную инфу пользователю, а городить макет и вывод в табдок не хочется.. вот тут то эта функция будет самое оно. Кстати функция прокатит и для РезультатаЗапроса, а не только для ТаблицыЗначений.

    А по поводу загрузки из экселя функция увы совсем не универсальная будет из за построителя запроса, он совсем не все подряд кушает, но если есть простенькая четко структурированная табличка, то вполне прокатит.

    Reply
  40. Yashazz

    (41) Алекс, а если люди ещё почитают про ОписаниеИсточникаДанных, а потом сравнят, что в СП написано про «ИсточникДанных» и что про конструктор описания, будет ещё много открытий)

    Ну раз подобное теперь «выбор экспертов», то у меня уже просто нет слов…

    Reply
  41. AllexSoft

    (42) это да, хотя с другой стороны каждую неделю какую нибудь годноту типа перфоленты никто выкладывать не сможет, а выбор экспертов надо чем-то наполнять…

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *