Экспорт из Calc в Writer с доп манипуляциями [решено]

Автор Феликс, 26 марта 2015, 14:09

0 Пользователи и 1 гость просматривают эту тему.

rami

Решил переписать макрос по-нормальному и выкинуть лишнее:
Sub exp   Dim oData, sURL, oDoc
oData=ThisComponent.Sheets(0).getCellRangeByName("A2:G61").DataArray
sURL="file:///C:/xsw/is/Отчет психиатра крон.ott"
oDoc=StarDesktop.loadComponentFromURL(sURL,"_blank",0,Array())
oDoc.TextTables(1).DataArray=oData
oDoc.Title="Отчет психиатра крон " & Date()
Dim args(0) as new com.sun.star.beans.PropertyValue
args(0).Name="FilterName"
args(0).Value="writer8"
oDoc.storeAsURL("file:///C:/Users/Ресепшн_2/Desktop/комиссии/" & oDoc.Title & ".odt",args())
End Sub

Обязательно замените старый шаблон "Отчет психиатра крон.ott" на новый (из предыдущего моего ответа)

Феликс

#16
Круто) немного отполирую шаблон, и будет идеально)))
И последний штрих
есть еще большая последовательность действий. После этого макроса надо кучу документов переместить, переименовать, отправить по почте.. С этим прекрасно справляется xStarter (виндосовский автокликер). Тем более эти задачи он выполняет в фоновом режиме (этот экспорт раньше тоже делал он, но при этом прыгал курсор, имитировал клики, что часто приводило к образованию кружев)). Я могу скомпилировать свой макрос из xStartera в программу .exe. Я правильно понимаю, что для запуска его из вашего макроса, надо добавить строчку

Shell "C:\тратата.exe"
или логичнее дописать ваш макрос?
Если дописывать ваш, то я так понимаю для архивации надо писать
FileCopy("C:/Users/Ресепшн_2/Desktop/психиатр.ods", "C:/xsw/arh/психиатр &Date()&.ods")
для удаления временного отчета
Kill("C:/Users/Ресепшн_2/Desktop/психиатр.ods")
но сначала надо закрыть все открытые документы офиса. Вроде для этого надо писать Close (что в общем то логично), но что писать после команды - адрес документа ("C:/Users/Ресепшн_2/Desktop/психиатр.ods"), или только его название в трее (психиатр.ods). или есть какая то гениальная команда что бы закрыть все открытые документы опенофиса?

Update
Путем экспериментов разобрался с командами Shell  и  Kill.
Не получается с FileCopy, и с закрытием документов.
Зато вместо связки FileCopy -> Kill  работает Name "C:/Users/Ресепшн_2/Desktop/психиатр.ods" As "C:/xsw/arh/психиатр.ods"
Но если задать название конечного документа как психиатр &Date()&.ods, дату он не присваивает(

rami

#17
Цитата: Феликс от 30 марта 2015, 09:52FileCopy("C:/Users/Ресепшн_2/Desktop/психиатр.ods", "C:/xsw/arh/психиатр &Date()&.ods")
Для перемещения файла C:/Users/Ресепшн_2/Desktop/психиатр.ods в папку C:/xsw/arh/ с переименованием в психиатр &Date()&.ods
попробуйте:
Name "C:/Users/Ресепшн_2/Desktop/психиатр.ods" As "C:/xsw/arh/психиатр" & Date() & ".ods"

Феликс

Попробовал. Он как то излишне буквально принимает команду. В папке арх, вместо "психиатр30.03.15", появляется файл "психиатр &Date()&"

rami

Цитата: Феликс от 30 марта 2015, 11:09Попробовал. Он как то излишне буквально принимает команду. В папке арх, вместо "психиатр30.03.15", появляется файл "психиатр &Date()&"
Команда выполняется правильно, но она сама неправильная.
Из-за того что у нас разные фаиловые системы, я у себя сделал правильно, а для вас неправильно. Исправил в предыдущем ответе. Переменную Date() нельзя включать в строку. Имя файла в этом случае собирается из трёх частей: ="строка" & переменная() & "строка".

Феликс

Ааа. тогда всё понятно. Работает.
А как закрыть документ?
Команда Close как я понял закрывает не файл, а канал файла, и его еще надо определить.
Функция Reset мне вроде не подойдет, поскольку она, как я понял, закроет и интернет браузер.

rami

Цитата: Феликс от 30 марта 2015, 11:50Команда Close как я понял закрывает не файл, а канал файла, и его еще надо определить.
Нужно пользоваться не командой Close, а методом документа, например oDoc.close(true) закроет "отчёт психиатра....", а для закрытия "психиатр.ods" нужно немного переписать макрос, а именно сохранить этот документ в его собственной переменной например oDokum.
Sub exp   Dim oData, sURL, oDoc   'для Феликса окончательно
oDokum=ThisComponent
oData=oDokum.Sheets(0).getCellRangeByName("A2:G61").DataArray
sURL= "file:///C:/xsw/is/Отчет психиатра крон.ott"
oDoc=StarDesktop.loadComponentFromURL(sURL,"_blank",0,Array())
oDoc.TextTables(1).DataArray=oData
oDoc.Title="Отчет психиатра крон " & Date()
Dim args(0) as new com.sun.star.beans.PropertyValue
args(0).Name = "FilterName"
args(0).Value = "writer8"
oDoc.storeAsURL("file:///C:/Users/Ресепшн_2/Desktop/комиссии/" & oDoc.Title & ".odt",args())
Name"C:/Users/Ресепшн_2/Desktop/психиатр.ods" As "C:/xsw/arh/психиатр" & Date() & ".ods"
oDokum.close(true)
oDoc.close(true)
End Sub

(Надеюсь сейчас ничего не перепутал :roll:)

Феликс

Класс))) переложил на свою операционку (исходя из ответа #19) - то что надо))
Больше пытать не буду, дальше сам допетрю) а то превращаюсь в старуху из золотой рыбки) - начал с корыта, и раскатываю губу дальше)
Спасибо большущее)

luu

Здравствуйте. по опыту и на примерах из этой темы пытаюсь соорудить то что мне нужно.
Возникли вопросы:
1. А как мне переносить данные из конкретных ячеек (Номер заявки, дата заявки) в текстовый документ. Подразумеваю, что в шаблоне должны быть какие-то поля, в которые будут записываться значения из ячеек, но как их там сделать?
2. Сейчас для переноса данных в таблицу, размерности указанного диапазона ячеек и подготовленной таблицы в шаблоне должны совпадать, иначе ругается на несоответствие количества строк. Поэтому сейчас выбираю диапазон на 60 строк, как в шаблоне. А что если заявка будет из 1 строки, 10 строк (как в примере), 20 строк и т.д.? Как сделать чтобы в шаблоне была таблица на одну строку и автоматически расширялась на размер диапазона ячеек в Calc?

Рабочие файлы и код макроса прилагаю:
Sub exp   

GlobalScope.BasicLibraries.LoadLibrary("Tools")
Dim oData, sURL, oDoc
searchDir = DirectoryNameoutofPath(ThisComponent.URL, "/")
FolderName = convertFromURL(SearchDir)

oDokum=ThisComponent
oData = oDokum.Sheets(0).getCellRangeByName("A5:D64").DataArray
ZDate = oDokum.Sheets(0).getCellRangeByName("B1").string
ZNumber = oDokum.Sheets(0).getCellRangeByName("B2").string
sURL= FolderName & "/Заявка_шаблон.ott"
oDoc=StarDesktop.loadComponentFromURL(convertToURL(sURL),"_blank",0,Array())
oDoc.TextTables(1).DataArray=oData
oDoc.Title="Заявка_" & ZDate & "_" & ZNumber
Dim args(0) as new com.sun.star.beans.PropertyValue
args(0).Name = "FilterName"
args(0).Value = "writer8"
oDoc.storeAsURL("file://"&FolderName &"/"& oDoc.Title & ".odt",args())
' Name"C:/Users/Ресепшн_2/Desktop/психиатр.ods" As "C:/xsw/arh/психиатр" & Date() & ".ods"
'oDokum.close(true)
oDoc.close(true)
End Sub

economist

Изучите Слияние, Рассылку и DDE. Макросы тут излишни, есть штатный механизм, описанный в доках и на Форуме.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

luu

DDE, насколько я понимаю, немного не то, потому что мне не нужна динамическая связь с таблицей. Я выгружаю необходимые мне данные на отдельный лист, а с него уже формирую заявку по шаблону в Writer
MailMerge тоже не использую, потому что не понял как там можно реализовать перенос данных в таблицу при условии что ее размер всегда разный. И при этом меня отпугнула необходимость использования зарегистрированного источника данных, т.к. решение в моем случае должно работать для пользователя "из коробки", т.е. получил файл, открыл, нажал кнопу -> результат. Без дополнительных телодвижений в сторону "Источников данных"

Перенос отдельных полей реализовал через именованные Закладки (взял решение, подсказанное bigor)
А вопрос с таблицей решил таким образом: Изначально в форме, из которой выгружаю данные, указан диапазон на 1000 строк, в шаблоне тоже таблица с такой размерностью. После переноса данных макросом убираю лишние пустые строки таблицы в итоговом документе ODT. Отрабатывает такое решение не моментально, чувствуется что на перенос большого массива данных требуется время, но в моем случае это не критично.

В итоге получилось добиться желаемого. Всем спасибо. Код примерно такой:
'--------------------------------------------------------------------------
' Выгрузка заявки в Writer на основе шаблона
Sub Export_to_Writer

GlobalScope.BasicLibraries.LoadLibrary("Tools")
Dim oData, sURL, oDoc, oDokum, Sheet_zayavka As Object
Dim searchDir, FolderName As String
Dim ZDate, ZNumber As String
Dim oBookMark As Object
Dim r, n As Integer

searchDir = DirectoryNameoutofPath(ThisComponent.URL, "/")
FolderName = convertFromURL(SearchDir)

oDokum=ThisComponent
Sheet_zayavka = oDokum.Sheets.getByName("Заявка")
oData = Sheet_zayavka.getCellRangeByName("A5:J1005").DataArray
ZDate = Sheet_zayavka.getCellRangeByName("B1").string
ZNumber = Sheet_zayavka.getCellRangeByName("B2").string
sURL= FolderName & "/Заявка_шаблон.ott" 'В этом случае файл шаблона должен лежать в той же папке, где исходный файл

oDoc=StarDesktop.loadComponentFromURL(convertToURL(sURL),"_blank",0,Array())

oBookMark = oDoc.getBookmarks().getByName("BookmarkZNumber")
oBookMark.getAnchor.setString(ZNumber)
oBookMark = oDoc.getBookmarks().getByName("BookmarkZDate")
oBookMark.getAnchor.setString(ZDate)

oDoc.TextTables(0).DataArray=oData

' Удаление пустых строк в импортированной таблице
r = oDoc.TextTables(0).getRows().Count
for n = r to 1 step -1
if  oDoc.TextTables(0).getCellByName(A & n).getString() = "" then oDoc.TextTables(5).getRows().RemoveByIndex(n-1,1)
next

oDoc.Title="Заявка_" & ZNumber & "_" & ZDate
Dim args(0) as new com.sun.star.beans.PropertyValue
args(0).Name = "FilterName"
args(0).Value = "writer8"
oDoc.storeAsURL("file://"&FolderName &"/"& oDoc.Title & ".odt",args())

'oDokum.close(true)
'oDoc.close(true)
End Sub



bigor

Я когда то делал подобное, в меньших объемах строк. Вначале вычислял количество строк исходной таблицы, затем удалял строки в таблице шаблона до нужного количества и затем переносил данные
Поддержать наш форум можно здесь

economist

#27
Норм код, главное работает.

DDE делает главное - затаскивает инородные данные (таблицы в текст), причем с плюшками, например с повтором заголовков на каждом листе (сквозные строки). После экспорта в PDF разницы нет. Обновление многим нужно, и для табличных частей DDE незаменим.

Регистрировать БД необязательно, макросом можно обращаться, дополнив строку подключения парой параметров.

Или ещё проще - вешаем макрос на событие открытия файла ODB и регистрируем незаметно для пользователя. Код есть на Форуме.

Ну и Разделы - они тоже могут пригодиться. Там появляется формат TXT/CSV/HTML, что добавляет как бардака, так и возможностей для интеграции.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...