Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

7 Декабрь 2021, 19:07 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Здесь можно поблагодарить участников форума Улыбка
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1   Вниз
  Печать  
Автор Тема: Использование запросов для импорта данных из нескольких TXT файлов  (Прочитано 1041 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ВикторAK
Новичок
*
Offline Offline

Сообщений: 4


« Стартовое сообщение: 15 Октябрь 2021, 22:22 »

Здравствуйте! Помогите разобраться.
Казалось бы, не сложная задача, но не могу победить ее с помощью Либры.

Есть несколько ТХТ файлов, содержимое которых периодически пополняется.
В MS Excel задуманное делается просто - получить даные из файла (рис.1) - открывается редактор power query (рис.2) - закрываем/сохраняем и всё.
Если потом открыть сохраненный xlsx файл и нажать Обновить всё (рис.3) то со всех подключенных ТХТ файлов подгружаются данные.

Как, и можно ли в принципе, подобное реализовать в Calc'e?

* forumooo.zip (258.95 Кб - загружено 8 раз.)

* 1.jpg (334.35 Кб, 1150x822 - просмотрено 23 раз.)

* 2.jpg (307.27 Кб, 1148x822 - просмотрено 16 раз.)

* 3.jpg (171.95 Кб, 773x487 - просмотрено 18 раз.)
Записан
eeigor
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 752



« Ответ #1: 15 Октябрь 2021, 22:55 »

Подключите ваши файлы через Base и импортируйте в Calc в диапазоны базы данных. Обновление - небольшим макросом. Как-то так... @economist Вам лучше подскажет.
Записан

Ubuntu 18.04 LTS • LO 7.2.2.2 Community
ВикторAK
Новичок
*
Offline Offline

Сообщений: 4


« Ответ #2: 15 Октябрь 2021, 22:57 »

Надеялся что смогу обойтись без Base и макросов Смеющийся Спасибо за наводку
Записан
eeigor
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 752



« Ответ #3: 15 Октябрь 2021, 23:07 »

Да нет, это просто достаточно и надёжно. Ну, нет здесь Power Query и языка программирования "M".

Updated: Сравнение Excel и Calc в данном случае не уместно. Один Excel по объему тянет больше, чем весь LibreOffice.
« Последнее редактирование: 15 Октябрь 2021, 23:15 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.2.2.2 Community
ВикторAK
Новичок
*
Offline Offline

Сообщений: 4


« Ответ #4: 17 Октябрь 2021, 16:18 »

Подключите ваши файлы через Base
Уже на данном этапе возникает заминка.
Может не правильный запрос в гугле задаю, но получается только через Calc открыть ТХТ файл, потом скопировать его содержимое и вставить в Base...
Через диалог "Мастер источников даных" добавил папку с файлами ТХТ, но далее можно работать только с одним файлом...
Подскажите куда копать дальше, чувствую себя слепым котенком, гайды с созданием таблиц с учениками или покупателями не помогают.
« Последнее редактирование: 17 Октябрь 2021, 16:30 от ВикторAK » Записан
eeigor
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 752



« Ответ #5: 17 Октябрь 2021, 17:35 »

Текстовые файлы (csv) обновляются, как вы сказали, из внешней программы. Base (файл data.odb) подключен к папке с этими файлами. Таблицы Base методом Drag&Drop я перенес в файл Calc (файл data.ods), в результате чего были созданы два диапазона базы данных с именами "Import1" и "Import2". Если исходные данные изменились, то их можно обновить макросом ниже. Макрос можно подвесить на открытие файла.

Код:
Sub RefreshAllDBRanges
Dim oDBRanges As Object, oDBRange As Object

oDBRanges = ThisComponent.DatabaseRanges
For Each oDBRange In oDBRanges
oDBRange.refresh
Next
End Sub

UPD:
Base подключен к папке с файлами через относительный путь, работает. А вот файл Calc data.ods - через абсолютный путь. Эту проблемку надо решить, чтобы не проводить импорт заново.

UPD:
См. ниже: Edit Database Link

* database.zip (11.54 Кб - загружено 8 раз.)

* Снимок экрана от 2021-10-17 17-31-37.png (214.97 Кб, 1920x1080 - просмотрено 17 раз.)

* Снимок экрана от 2021-10-17 17-33-02.png (51.95 Кб, 691x328 - просмотрено 15 раз.)

* Снимок экрана от 2021-10-17 17-33-16.png (44.05 Кб, 691x328 - просмотрено 16 раз.)
« Последнее редактирование: 17 Октябрь 2021, 22:00 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.2.2.2 Community
eeigor
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 752



« Ответ #6: 17 Октябрь 2021, 18:51 »

Я не очень разбираюсь в Base. Вам лучше подскажет @economist.
Ctrl+Shift+F4  Shows or Hides the Database explorer


* Снимок экрана от 2021-10-17 18-50-17.png (80.76 Кб, 707x716 - просмотрено 17 раз.)

* Снимок экрана от 2021-10-17 21-55-25.png (83.81 Кб, 1195x648 - просмотрено 11 раз.)
« Последнее редактирование: 17 Октябрь 2021, 21:56 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.2.2.2 Community
ВикторAK
Новичок
*
Offline Offline

Сообщений: 4


« Ответ #7: 17 Октябрь 2021, 19:48 »

Спасибо, буду пробовать по вашему примеру
Записан
eeigor
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 752



« Ответ #8: 18 Октябрь 2021, 00:52 »

Выполните макрос "ImportDatabaseTables". Будет создан новый файл ODS, и каждая таблица в источнике данных (зд. под именем "data", см. скриншот, а сам источник связан с конкретной базой данных - зд. "data.odb") будет импортирована на отдельный лист. Источник данных надо предварительно зарегистрировать.

Код:
REM  *****  BASIC  *****

Rem Replace with your actual data source name.
Const REGISTERED_DATABASE$ = "data"  'registered name of database link

Sub ImportDatabaseTables()
Dim oDBCtx As Object, oDataSource As Object, oConnection As Object
Dim aTableNames$()

oDBCtx = createUnoService("com.sun.star.sdb.DatabaseContext")
oDataSource = oDBCtx.getByName(REGISTERED_DATABASE)
oConnection = oDataSource.getConnection("", "")
' NOTE: .getConnection("user", "password") for a real database log-in.
aTableNames() = oConnection.Tables.ElementNames

Dim oDoc As Object, oSheets As Object, oDBRanges As Object, oDBRange As Object
Dim oCellRange As Object, oAddr As Object  'New com.sun.star.table.CellRangeAddress
Dim sTableName$, sDBRangeName$

oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_default", 0, Array())
oSheets = oDoc.Sheets
oDBRanges = oDoc.DatabaseRanges
' Add additional sheets as needed according to the number of tables in oDataSource.
For i = oSheets.Count To UBound(aTableNames())
oSheets.insertNewByName("Sheet" & i + 1, i + 1)
Next

Dim aDescriptor(3) As New com.sun.star.beans.PropertyValue  'import descriptor
' Import source tables.
For i = 0 To UBound(aTableNames())  'oSheets.Count - 1
sTableName = aTableNames(i)
sDBRangeName = "Import" & i + 1
oSheets(i).Name = sTableName

oAddr = createUnoStruct("com.sun.star.table.CellRangeAddress")
oAddr.Sheet = i
If Not oDBRanges.hasByName(sDBRangeName) Then
oDBRanges.addNewByName(sDBRangeName, oAddr)
End If
Rem oDBRange = oDBRanges(sDBRangeName)  '#Err!
oDBRange = oDBRanges.getByName(sDBRangeName)  'oDBRanges(i)
With oDBRange
' .ContainsHeader = True  'Contains column labels (default is True)
' .TotalsRow = False  'Contains totals row (default is False)
.MoveCells = True  'Insert or delete cells (default is False)
.KeepFormats = True 'Keep formatting (default is False)
' .StripData  = False  'Don't save imported data (default is False)
End With
oCellRange = oDBRange.ReferredCells

' Set the import descriptor properties.
aDescriptor(0).Name = "DatabaseName"  'registered name of database link
aDescriptor(0).Value = REGISTERED_DATABASE
aDescriptor(1).Name = "SourceType"
aDescriptor(1).Value = com.sun.star.sheet.DataImportMode.TABLE  '2=TABLE
' Set the source import descriptor table.
aDescriptor(2).Name = "SourceObject"
aDescriptor(2).Value = sTableName
'aDescriptor(3).Name = "IsNative"  'specifies whether the SQL statement is given…
'aDescriptor(3).Value = False      '…directly to the database or is parsed before

oCellRange.doImport(aDescriptor)

' Unlink the database range if you like.
'oDBRanges.removeByName(sDBRangeName)
Next
oConnection.close()
End Sub

Процедура "RefreshAllDBRanges" обновит все диапазоны базы данных в электронной таблице (должна находиться в созданном файле с уже импортированными таблицами). Повесьте её на событие "Open Document", чтобы данные обновлялись при открытии автоматически.
Код:
Sub RefreshAllDBRanges()
''' Called from "Open Document" event.
'''
Dim oDBRangesEnum As Object, oDBRange As Object

oDBRangesEnum = ThisComponent.DatabaseRanges.createEnumeration()
Do While oDBRangesEnum.hasMoreElements()
oDBRange = oDBRangesEnum.nextElement()
oDBRange.refresh()
Loop

' For Each oDBRange In ThisComponent.DatabaseRanges
' oDBRange.refresh()
' Next
End Sub


UPD:
В ходе работы замечена ошибка при вызове метода getByName() неявным способом:
 oDBRange = oDBRanges.getByName(sDBRangeName)  'работает верно
 oDBRange = oDBRanges(sDBRangeName)  '#Err! Неверно получает ссылку на диапазон базы данных
 BUG: при смене в цикле имени таблицы на следующую объект oDBRange по-прежнему указывает на первую таблицу.

Или:
 oDBRange = oDBRanges.getByIndex(i)  'работает верно
 oDBRange = oDBRanges(i)  'работает верно


* Снимок экрана от 2021-10-18 09-49-04.png (47.4 Кб, 377x622 - просмотрено 13 раз.)

* Снимок экрана от 2021-10-18 09-51-50.png (35.01 Кб, 640x516 - просмотрено 12 раз.)
« Последнее редактирование: 18 Октябрь 2021, 21:14 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.2.2.2 Community
economist
Форумчанин
***
Offline Offline

Сообщений: 1 568


« Ответ #9: 18 Октябрь 2021, 12:34 »

После языка M - Python+Pandas для самой быстрой из всех возможных загрузок кучки TXT в Calc - окажутся лучшим решением: https://forumooo.ru/index.php/topic,8696.0.html  Но лучшее обычно оставляют на потом.

А если "по классике", с TXT из папки через Base - по Ctrl+Shift+F4 в Calc вы увидите каждый файл в виде отдельной таблицы. Перетащите каждую (за серый прямогольник слева) на разные листы Calc - и вы получили самообновляемые диапазоны в листах, по числу файлов, без к-либо макросов. Обновление при открытии или ручное - настраивается.  

Для обновления (перезаписи поверх) TXT-шек из вашего прикладного ПО (условно 1С) по время активного подключения Calc к TXT - нужно чтобы файлы имели атрибут read only - тогда их перезапись Calc не заблокирует. Атрибуты можно присвоить простым bat-скриптом, или еще более простым python-скриптом. Питон "родной", из папки LO.  

UPD:

все  TXT д.б. в одной кодировке, с одним разделителем тысяч и дробной части, с одним форматом даты, с одним (с или без) заголовком столбцов в 1-й строке итд. Для 1С - это почти нереальная ситуация. Если у вас "разнобой" TXT-форматов  - можно попытать счастья с ISAM-драйвером и файлом описания схемы schema.ini - это просто и надежно работает под Windows. Вообще читать стопку TXT как базу данных под Windows можно 5-ю способами, и все из коробки. Другое дело что дальнейшая обработка данных - определяет то, чем лучше было бы делать импорт "разношерстных" данных. Но это по ситуации.  
« Последнее редактирование: 18 Октябрь 2021, 12:44 от economist » Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
Страниц: 1   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!