Приветствую Вас ГостьВоскресенье, 05.05.2024, 14:38

Каталог статей


Загрузить таблицу Excel через табличный документ

Есть задача - загрузить содержимое таблицы Excel в таблицу значений. Можно скопировать данные в буфер и заполнить таблицу значений из буфера. Это просто, но есть один недостаток - я не уверен, что это будет работать на Linux, так как для обращения к буферу используется Com-технология.

Чтобы метод работал одинаково как на Windows, так и на Linux, решил сделать загрузку таблицы через табличный документ.

Общий принцип: так как таблица значений доступна только на сервере, то надо передать файл с клиента на сервер и там прочитать в табличный документ (ДанныеФайла). При загрузке таблицы в табличный документ используем способ чтения по значениям, т.е. если в ячейке занесена дата, то в этом случае мы можем получить данные в формате Дата. Есть и другой способ - получаем текстовые представления значения ячеек. 

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

1. Загружаем файл:

&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
    
    ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
    ПараметрыДиалога.МножественныйВыбор = Ложь;
    ПараметрыДиалога.Заголовок = НСтр("ru = 'Выберите файл'");
    ПараметрыДиалога.Фильтр = "Таблица Excel (*.xlsx)|*.xlsx|Таблица Excel (*.xls)|*.xls";
    
    ОписаниеЗавершения = Новый ОписаниеОповещения("ОкончаниеЗагрузки",ЭтаФорма);
    НачатьПомещениеФайлаНаСервер(ОписаниеЗавершения,,,,ПараметрыДиалога,ЭтаФорма.УникальныйИдентификатор); // открывается диалог выбора файла и файл передаем на сервер
    
КонецПроцедуры

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

 

&НаСервере
Процедура ЗагрузитьФайлНаСервере(АдресФайлаВоВременномХранилище, РасширениеФайла) 
    
    ПутьКФайлу = ПолучитьИмяВременногоФайла(РасширениеФайла);
    
    ДанныеИзХранилища = ПолучитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);
    Если ТипЗнч(ДанныеИзХранилища) = Тип("ДвоичныеДанные") Тогда
        
        ДанныеИзХранилища.Записать(ПутьКФайлу);
        ДанныеФайла.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);    //Загрузили в табличный документ
        ЗаполнитьТаблицуДанныхНаСервере(); // вызываем процедуру переноса данных табличного документа в таблицу значений

    Иначе
        Сообщить("Ошибка при загрузке файла. Попробуйте повторить загрузку.");
    КонецЕсли;     
        
КонецПроцедуры

2. Переносим данные в таблицу значений. Таблица значений имеет имя ТаблицаДанных и имеет фиксированную структуру. Есть так же таблица, содержащая данные Название колонки и Номер колонки, по которой мы определяем соответствие между колонкой таблицы значений и номером колонки в табличной документе. Перед тем, как добавить строку в таблицу значений, определяем заполнение контрольного столбца "ЛицевойСчет". Если это значение заполнено, то добавляем строку и заполняем её данными:

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

        Для НомКолонки = 1 По ДанныеФайла.ШиринаТаблицы Цикл
            
            Область = ДанныеФайла.Область("R" + Строка(НомерСтроки) + "C" + Строка(НомКолонки));
            
            Если Область.СодержитЗначение Тогда      // если какая-то ячейка содержит значение, то считаем что в ней должны быть данные                        
                ДобавитьЗаписьВТаблицуДанных(НомерСтроки);
                Прервать;     // прерываем цикл обхода колонок, чтобы перейти на следующую строку               
            КонецЕсли;
            
        КонецЦикла;         
    КонецЦикла;     
    
КонецПроцедуры 

&НаСервере
Процедура ДобавитьЗаписьВТаблицуДанных(НомерСтроки)
    
    СтруктураДанных = ПолучитьСтруктуруДанных();
    Для Каждого РеквизитСтукрутры Из СтруктураДанных Цикл  
        
        НомерКолонки = ОпределитьНомерКолонки(РеквизитСтукрутры.Ключ); // функция, которая определяем номер колонки по названию колонки реквизита таблицы значений. Текст не приводится.
        Если НомерКолонки = Неопределено Тогда
            Продолжить;
        КонецЕсли;
        
        Область =  ДанныеФайла.Область("R" + Строка(НомерСтроки) + "C" + Строка(НомерКолонки));    
        Если Область.СодержитЗначение Тогда
            СтруктураДанных[РеквизитСтукрутры.Ключ] = Область.Значение;
        Иначе                                                
           // на случай, если в таблице Excel значения были введены в виде текста, то пытаемся преобразовать строку в дату или число. 
            ЗначениеРеквизита = Область.Текст; 
            Если  РеквизитСтукрутры.Ключ = "ДатаЗаявления" Тогда
                ЗначениеРеквизита = ПолучитьДатуИзСтроки(ЗначениеРеквизита);  
            ИначеЕсли  РеквизитСтукрутры.Ключ = "Сумма" Тогда
                ЗначениеРеквизита = ПолучитьЧислоИзСтроки(ЗначениеРеквизита);
            КонецЕсли;
                
            СтруктураДанных[РеквизитСтукрутры.Ключ] = ЗначениеРеквизита;
        КонецЕсли;
        
    КонецЦикла;
        
    Если ЗначениеЗаполнено(СтруктураДанных.ЛицевойСчет) Тогда //если контрольное поле заполнено, то добавляем строку в таблицу
        ЗаполнитьЗначенияСвойств(ТаблицаДанных.Добавить(),СтруктураДанных);
    КонецЕсли;
        
КонецПроцедуры

 

Служебные функции:

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

&НаСервереБезКонтекста
Функция ПолучитьДатуИзСтроки(ЗначениеСтрокой)
    Перем Результат;    
    
    Попытка
        Результат = Дата(Сред(ЗначениеСтрокой, 7, 4)+Сред(ЗначениеСтрокой, 4, 2)+Лев(ЗначениеСтрокой, 2));
    Исключение
        Результат = Дата(1,1,1);
    КонецПопытки;
    
    Возврат Результат;
    
КонецФункции

&НаСервереБезКонтекста
Функция ПолучитьЧислоИзСтроки(ЗначениеСтрокой)  
    
    Перем Результат;    
    
    ЗначениеСтрокой = СтрЗаменить(ЗначениеСтрокой," ","");

    Попытка
        Результат = Число(ЗначениеСтрокой);
    Исключение
        Результат = 0;
    КонецПопытки;
    
    Возврат Результат;
    
КонецФункции

 

Если заголовки столбцов в таблице Excel заданы в первой строке и они установлены адекватно, то есть способ загрузить данные через построитель запроса:

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

Название колонок получаемой таблицы значений автоматически преобразовывается системой (убираются пробелы и т.д.). 

 

 

Категория: Программирование | Добавил: leshic (19.10.2023)
Просмотров: 232 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Вход на сайт
Поиск
Категории раздела
СКД [48]
Регистры [7]
Формы [40]
Администрирование [34]
Запросы [10]
Объекты конфигурации и типы данных [20]
Взаимодействие с другими базами, приложениями и источниками данных [16]
Программирование [29]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0