Есть задача - загрузить содержимое таблицы 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 заданы в первой строке и они установлены адекватно, то есть способ загрузить данные через построитель запроса:
ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличныйДокумент.Область());
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();
ТаблицаЗначений = ПЗ.Результат.Выгрузить();
Название колонок получаемой таблицы значений автоматически преобразовывается системой (убираются пробелы и т.д.).
|