1с загрузка из excel УФ
Решил для себя сделать обработку-шаблон по загрузке данных из excel (управляемые формы), так как надоело каждый раз лезть в поисковые системы и искать готовые решения, которые либо-требуют регистрации, либо денег (старт мани). Собрал из всевозможных статей интернета более или менее универсальное решение, которое вы бесплатно и без регистрации можете скачать в конце статьи! А так же не забыть поставить палец вверх!.
Итак, для начала, используя диалог выбора файла, отметим путь, по которому мы будем загружать файл:
Далее, используя методы и свойства объекта ‘COMОбъект(“Excel.Application”)‘, зададим алгоритм подключения к файлу и отключения от него (по команде ‘ЗагрузитьИзЕксель‘):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
&НаКлиенте Процедура ПутьКФайлуНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); Диалог.Заголовок = "Выберите файл: "; Диалог.Фильтр = "Ексль(*.xls;*.xlsx)|*.xls;*.xlsx"; Диалог.ИндексФильтра = 0; Диалог.ПредварительныйПросмотр = Ложь; Диалог.ПроверятьСуществованиеФайла = Истина; Диалог.МножественныйВыбор = Ложь; Диалог.ПолноеИмяФайла = ПутьКФайлу; Если Диалог.Выбрать() Тогда ПутьКФайлу = Диалог.ПолноеИмяФайла; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ОтключатьсяОтExcel(Соответстие) Попытка Соответстие["Соединение"].DisplayAlerts = 0; Соответстие["ExcelФайл"].Close(); Соответстие["Соединение"].DisplayAlerts = 1; Соответстие["Соединение"].Quit(); Соответстие["Соединение"] = Неопределено; Исключение Сообщить("Не удалось отключиться от Excel - "+ОписаниеОшибки()); КонецПопытки; КонецПроцедуры &НаКлиенте функция ПоключитьсяКExcel(п_Файл) ПараметрыЕксель = Новый Соответствие; Попытка Excel = Новый COMОбъект("Excel.Application"); ПараметрыЕксель.Вставить("Соединение", Excel); Листы = Новый Массив; ExcelФайл = Excel.WorkBooks.Open (п_Файл); ПараметрыЕксель.Вставить("ExcelФайл", ExcelФайл); Для Сч = 1 По ExcelФайл.Sheets.Count Цикл Листы.Добавить(ExcelФайл.Sheets(Сч)); КонецЦикла; ПараметрыЕксель.Вставить("Листы", Листы); фРезультат = ПараметрыЕксель; Исключение Сообщить("Ошибка создания обьекта Microsoft Excel" + ОписаниеОшибки()); фРезультат = Неопределено; КонецПопытки; Возврат фРезультат; КонецФункции &НаКлиенте Процедура ЗагрузитьИзЕксель(Команда) Если ПутьКФайлу = "" Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Укажите файл загрузки"; Сообщение.Поле = "Объект.ПутьКФайлу"; Сообщение.Сообщить(); Возврат; КонецЕсли; Соединение = ПоключитьсяКExcel(ПутьКФайлу); Если Соединение = Неопределено Тогда Возврат; КонецЕсли; ОтключатьсяОтExcel(Соединение); КонецПроцедуры |
Отлично, теперь у нас есть параметры подключения к нашему файлу ‘Excel‘, в том числе и массив всех его страниц! Имея эти данные мы теперь можем начать загружать данные из екселя любым из доступных способов. Рассмотрим первый вариант – загрузка данных их екселя через массив структур:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
&НаКлиенте Процедура ЗагрузитьИзЕксель(Команда) Если ПутьКФайлу = "" Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Укажите файл загрузки"; Сообщение.Поле = "Объект.ПутьКФайлу"; Сообщение.Сообщить(); Возврат; КонецЕсли; Соединение = ПоключитьсяКExcel(ПутьКФайлу); //в массив структур Если ВариантЗагрузки = "МассивСтруктур" Тогда Лист = Соединение["Листы"][0]; // берем нужные нам листы: можем перебирать все их в цикле, либо указывать определенные. ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; МассивДанных = Новый Массив; Для Сч = 1 по ВсегоСтрок Цикл Строка = Новый Структура; Для Сч2 = 1 по ВсегоКолонок Цикл Строка.Вставить("Колонка" + Строка(Сч2), Лист.Cells(Сч, Сч2).Value); КонецЦикла; МассивДанных.Добавить(Строка); КонецЦикла; КонецЕсли; Если Соединение = Неопределено Тогда Возврат; КонецЕсли; ОтключатьсяОтExcel(Соединение); КонецПроцедуры |
На выходе получаем массив, элементы которого являются структурой. По идее мы считали данные из екселя, и теперь можем уже с ними строить свои алгоритмы – обрабатывать, приводить типы, загружать в таблицу значений и так далее (все данные в массиве):
Можно загрузить данные и без перебора всех строк. Используя свойство ‘Range‘ и метод ‘Выгрузить‘ мы можем получить двумерный массив с данными (COMSafeArray) – количество колонок в данном случае будет соответствовать количеству элементов в массиве:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
&НаКлиенте Процедура ЗагрузитьИзЕксель(Команда) Если ПутьКФайлу = "" Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Укажите файл загрузки"; Сообщение.Поле = "Объект.ПутьКФайлу"; Сообщение.Сообщить(); Возврат; КонецЕсли; Соединение = ПоключитьсяКExcel(ПутьКФайлу); //в массив структур Если ВариантЗагрузки = "МассивСтруктур" Тогда Лист = Соединение["Листы"][0]; // берем нужные нам листы: можем перебирать все их в цикле, либо указывать определенные. ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; МассивДанных = Новый Массив; Для Сч = 1 по ВсегоСтрок Цикл Строка = Новый Структура; Для Сч2 = 1 по ВсегоКолонок Цикл Строка.Вставить("Колонка" + Строка(Сч2), Лист.Cells(Сч, Сч2).Value); КонецЦикла; МассивДанных.Добавить(Строка); КонецЦикла; //в двумерный массив ИначеЕсли ВариантЗагрузки = "ДвумерныйМассив" Тогда Лист = Соединение["Листы"][0]; ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; Область = Лист.Range(Лист.Cells(1,1), Лист.Cells(ВсегоСтрок,ВсегоКолонок)); Данные = Область.Value.Выгрузить(); КонецЕсли; Если Соединение = Неопределено Тогда Возврат; КонецЕсли; ОтключатьсяОтExcel(Соединение); КонецПроцедуры |
Этих двух способов мне вполне хватает, что бы вытащить любые данные из екселя и затем их обработать.
Так же данные из екселя можно вытащить в табличный документ. Для этого нам в серверной процедуре необходимо его прочитать (метод ‘Прочитать‘ табличного документа) и затем его уже вернуть в клиент на форму. В этом нам помогут следующие методы ‘ПоместитьВоВременноеХранилище‘, ‘ПолучитьИзВременногоХранилища‘, ‘ПолучитьИмяВременногоФайла‘ и реквизит форма с адресом в хранилище ‘АдресВХранилище‘ / ‘Строка‘:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
&НаСервере Функция ПрочитатьТабличныйДокумент() Файл = ПолучитьИмяВременногоФайла("xlsx"); лДвоичДанные = ПолучитьИзВременногоХранилища(АдресВХранилище); лДвоичДанные.Записать(Файл); ТабДок = Новый ТабличныйДокумент; Попытка ТабДок.Прочитать(Файл, СпособЧтенияЗначенийТабличногоДокумента.Значение); Исключение Сообщение = Новый СообщениеПользователю; Сообщение.Текст = ОписаниеОшибки(); Сообщение.Сообщить(); КонецПопытки; Возврат ТабДок; КонецФункции &НаКлиенте Процедура ПоказатьТабличныйДокумент(Команда) ДвоичДанные = Новый ДвоичныеДанные(ПутьКФайлу); АдресВХранилище = ПоместитьВоВременноеХранилище(ДвоичДанные); ТабдДок = ПрочитатьТабличныйДокумент(); КонецПроцедуры |
А из табличного документа мы уже легко сможет данные преобразовать в таблицу значений, используя построитель отчета:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
&НаКлиенте Процедура ТабличныйДокументВТЗ(Команда) ПреобразоватьТабличныйДокументВТаблицуЗначений(); КонецПроцедуры Функция ПреобразоватьТабличныйДокументВТаблицуЗначений() ПоследняяСтрока = ТабДок.ВысотаТаблицы; ПоследняяКолонка = ТабДок.ШиринаТаблицы; ОбластьЯчеек = ТабДок.Область(1, 1, ПоследняяСтрока, ПоследняяКолонка); ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек); ПостроительОтчета = Новый ПостроительОтчета; ПостроительОтчета.ИсточникДанных = ИсточникДанных; ПостроительОтчета.Выполнить(); ТабЗначений = ПостроительОтчета.Результат.Выгрузить(); КонецФункции |
Имея такой нехитрый шаблон под рукой, любую загрузку из ексель можно сделать в считанные сроки. Качаем обработку! Ставим палец вверх на статью! Все просто!
Скачать файлыcraft1c_ShablonZagruzkiIzEksel.epf
Стоит упомянуть что COM ведь только на Виндовс.
Да верно, стоило бы об этом упомянуть! Еще так же хочу добавить вариант получения количество строк и колонок на листе:
– ВсегоСтрок = Лист.UsedRange.Rows.Count;
– ВсегоКолонок = Лист.UsedRange.Columns.Count;
Если в процессе работы с ексель мы вносим в него изменения и затем хотим их сохранить, стоит добавить в процедуру отключения соединения метод ‘SaveAs’:
Соответстие["Соединение"].DisplayAlerts = 0;
Соответстие["ExcelФайл"].SaveAs(ПутьКФайлу);
Соответстие["ExcelФайл"].Close();
Здравствуйте, у меня проблемы при работе с вашей обработкой.
1-я проблема (при нажатии на кнопку “ПоказатьТабличныйДокумент”):
{ВнешняяОбработка.craft1c_ШаблонЗагрузкиИзЕксель.Форма.Форма.Форма(157)}: Ошибка при вызове метода контекста (Прочитать): Ошибка при выполнении файловой операции ‘C:\Users\Admin\AppData\Local\Temp\v8_6E12_15.xlsx’. Формат файла не поддерживается.
2-я проблема (при нажатии на кнопку Табличный документ в таблицу значений): ожидает выражение выбрать, видимо это про запрос.
Привет! Это всего лишь шаблон для работы с загрузкой. У тебя скорее всего вот какие проблемы:
1: у тебя скорее всего не стоит офис , который поддерживает формат – xlsx / “Файл = ПолучитьИмяВременногоФайла(“xlsx”);”. Попробуй работать с форматом: “xls”
2: У тебя скорее всего не заполнен макет на форме. Сначала загружаешь данные из ексель. Затем жмешь “ПоказатьТабличныйДокумент”. А уже затем “ТабличныйДокументВТЗ”.
И все должно работать!