gifts2017

Загрузка данных из табличного документа от 1C. Нет ODF. Добавляем.

Опубликовал Сергей Кудашкин (sikuda) в раздел Программирование - Практика программирования

Добавим документы ODF (OpenOffice/LibreOffice) в стандартную обработку Загрузки Табличного документа из 1С.

Доброго времени суток!

Обработку  ЗагрузкаданныхизТабличногоДокументаконечно должен знать каждый 1С-ник. И сколько бы обработок такого плана не появлялось, эта остается классикой. Даже претензии можно предъявлять если вы в ней что-то не понимаете к самой 1С. Хотя какие претензии, исходный код открыть - изучай, не хочу...

 Еще чем мне нравится эта обработка  - тем что вы читаете данные из внешнего источника, показываете их с помощью объекта табличное поле и только затем выбираете алгоритм загрузки в 1С. При чем загрузка у Вас происходит в среде 1С без привлечения дополнительных компонентов. Без всяких выпадов в неизвестный объект OLE, полей которые не прочитались в обработке загрузки. Если вы видете данные в табличном поле, то они и будут грузиться по вашему алгоритму.

Но что-то в ней не хватает. Конечно стандарта офисных документов ODF (Open Document Format и между прочим ГОСТ Р ИСО/МЭК 26300-2010). Как говаривал мой начальник - есть чем себя занять. Из всех внешних загрузок, которые сейчас есть к сожалению самыми распостраненными являются OLE(Com+) технологии. Возможно что-то еще появиться, но пока примемся за них.

Залезаем в код и видим несколько однотипных функуций

Функция мПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт

Функция мПрочитатьТабличныйДокументИзТекста(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт

 

Пора добавить свою:

// Функция считывает в табличный документ данные из файла в формате ODF Calc(ods)
//
// Параметры:
//  ТабличныйДокумент  - ТабличныйДокумент, в который необходимо прочитать данные
//  ИмяФайла           - имя файла в формате ODF, из которого необходимо прочитать данные
//  НомерЛистаCalc     - номер листа книги Calc, из которого необходимо прочитать данные
//
// Возвращаемое значение:
//  Истина, если файл прочитан, Ложь - иначе
//
Функция мПрочитатьТабличныйДокументИзCalc(ТабличныйДокумент, ИмяФайла, НомерЛистаCalc = 1) Экспорт

   
ВыбФайл = Новый Файл(ИмяФайла);
    Если НЕ
ВыбФайл.Существует() Тогда
       
Сообщить("Файл не существует!");
        Возврат Ложь;
    КонецЕсли;

    Попытка
       
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
       
Desktop = ServiceManager.CreateInstance("com.sun.star.frame.Desktop");
       
Desktop.getCurrentFrame().getContainerWindow().setVisible(Ложь);  //невидимым основное окно.

        //установим параметры - не показывать таблицу Calc
       
Параметры = Новый COMSafeArray("VT_DISPATCH", 1);
       
Свойство = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
       
Свойство.Name = "Hidden";
       
Свойство.Value = true;
       
Параметры.SetValue(0,Свойство);

       
Document = Desktop.LoadComponentFromURL("file:///" + ИмяФайла, "_blank", 0, Параметры);
       
Состояние("Обработка файла Office Calc ...");
       
Листы = Document.getSheets();
       
Лист = Листы.getByIndex(НомерЛистаCalc-1);
    Исключение
       
Сообщить("Ошибка загрузки данных. Возможно неверно указан номер листа книги Calc.");
        Возврат ложь;
    КонецПопытки;

   
ТабличныйДокумент.Очистить();

   
//Определение максимум ячейки с данными...
   
НульЯчейка = Лист.GetCellbyPosition(0,0);
   
НульКурсор = Лист.createCursorByRange(НульЯчейка);
   
НульКурсор.GotoEndOfUsedArea(1);
   
НульАдрес  = НульКурсор.RangeAddress;
   
ПослСтрока = НульАдрес.EndRow;
   
ПослКолонка = НульАдрес.EndColumn;

    
Для Row = 1 По ПослСтрока + Цикл     

      Если Лист.getCellByPosition(Column-1,Row-1).getType() = 0 Или Лист.getCellByPosition(Column-1,Row-1).getType() = 1 Тогда      

        ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = Лист.getCellByPosition(Column-1,Row-1).value;

      ИначеЕсли Лист.getCellByPosition(Column-1,Row-1).getType() = 2 Тогда

       
ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = Лист.getCellByPosition(Column-1,Row-1).string;

      КонецЕсли;

    КонецЦикла;

   
//ServiceManager.quit();
   
Document.Dispose();
   
Document = 0;
   
Параметры = 0;
   
Desktop = 0;
   
ServiceManager = 0;

    Возврат Истина;

КонецФункции

И добавим в форму выбора файла ods по тексту.

   ДиалогВыбораФайла.Фильтр    = "Табличный документ (*.mxl)|*.mxl|Лист Calc (*.ods)|*.ods|Лист Excel (*.xls)|*.xls|Текстовый документ (*.txt)|*.txt|dBase III (*.dbf)|*.dbf|";

И выбор функции для ods

   ИначеЕсли нРег(ФайлНаДиске.Расширение) = ".ods" Тогда
           
мПрочитатьТабличныйДокументИзCalc(ТабличныйДокумент,ДиалогВыбораФайла.ПолноеИмяФайла);

 

P.S. Сайт www.sikuda.ru

 

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Загрузка данных из табличного документа c ODF.
.epf 67,48Kb
18.04.13
122
.epf 67,48Kb 122 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Fomix (fomix) 09.11.12 09:40
Все хорошо. Зачет! Только последние 2 картинки "по ходу не из той оперы"... Достаточно было одной первой обойтись. :-)
2. Виктор Левченко (lvictor58) 25.12.12 11:34
Ну тогда уж и в процедуре КоманднаяПанельТабличногоДокументаСохранить(Кнопка)
надо было тоже указать
ДиалогВыбораФайла.Фильтр    = "Табличный документ (*.mxl)|*.mxl|Лист Calc (*.ods)|*.ods|Лист Excel (*.xls)|*.xls|Текстовый документ (*.txt)|*.txt|";
3. Kom-off (Kom-off) 29.12.12 16:11
Для автора и тех кто будет этим делом пользоваться. Не знаю как в версиях Open Office 2.x, но в версиях 3.x значения в ячейках таблицы Calc отличаются по типам хранимых в них значений и, соответственно, методам их получения. Реализация функции чтения данных Calc в этой статье читает только числовые значения и не читает текстовые. Для добавления возможности чтения тестовых данных необходимо строку:
ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = Лист.getCellByPosition(Column-1,Row-1).value;

заменить на конструкцию:
			Если Лист.getCellByPosition(Column-1,Row-1).getType() = 0 Или  Лист.getCellByPosition(Column-1,Row-1).getType() = 1 Тогда
				ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = Лист.getCellByPosition(Column-1,Row-1).value;
			ИначеЕсли Лист.getCellByPosition(Column-1,Row-1).getType() = 2 Тогда
				ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = Лист.getCellByPosition(Column-1,Row-1).string;
			КонецЕсли;
...Показать Скрыть
teflon; sikuda; Lukich66; +3 Ответить 2
4. Сергей Кудашкин (sikuda) 27.01.13 15:47
(3) Спасибо. Изменил по указанному.

Обнаружил странное поведение обработки на последнем LibreOffice 3.6. Если он не загружен, выдается ошибка типа неизвестный синтаксис -embeded. Единственное решения загрузить LibreOffice (открыть любой документ).
5. Сергей Кудашкин (sikuda) 13.02.13 11:26
Заходите на сайт sikuda.ru. Комментируйте статью.
6. Серый Серов (user012) 13.02.13 12:40
8. Ламия 02.10.13 18:41
Здравствуйте, стоит LibreOffice 4.1, выдает
Ошибка загрузки данных. Возможно неверно указан номер листа книги Calc.
Не пойму что не так, помочь можете?
9. Капитан Немо (capitan) 29.01.15 19:10
Не знаю как в 2013 году, а в 2015 если сделать копипаст с описания - не взлетает.
Надо как водится допилить напильником :)
Поэтому плюс не поставил. А идея хорошая.
10. Дмитрий Тарасов (tarassov) 02.06.15 13:57
(9) capitan,
Аналогично.
Поэтому добавлю сюда свой вариант "допиливания"
Прикрепленные файлы:
ЗагрузкаДанныхИзТабличногоДокумента_УФ_БезМодальности.epf
11. Иван Иванов (everest12345) 01.09.15 16:52
Переменная Column не определена. Где она задается?
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа