Замена модулей макросов *.xml в файлах *.ods

Автор timal1234, Вчера в 14:40

timal1234 и 1 гость просматривают эту тему.

timal1234

Всем привет!

Имеется файл-первоисточник с макросами (назовём его Source.ods).
Также имеется порядка 20 шт. файлов *.ods с такими же макросами, но с разными данными.

Допустим поменялся текст нескольких макросов в Source.ods ....

Задача:
быстро заменить текст макросов в файлах *.ods из источника Source.ods (без открывания каждого файла и ручной правки макросов).

Обычно делаю так:
Переименовываю все файлы *.ods в *.zip,
Source.zip распаковываю, захожу в папку *\Source\Basic\Standard\ ,
Открываю в "7zip" каждый файл *.zip (в котором надо заменить макросы), спускаюсь на уровень \Basic\Standard\ и кидаю туда новую версию файлов *.xml из окна *\Source\Basic\Standard\
Далее обратно переименовываю в *.ods
------------
Проблема в том, что иногда после таких манипуляций файлы перестают открываться.
-----------
Может есть какой-то другой способ ?
или что я делаю не так?

sokol92

В замечательной книге Питоньяка "OpenOffice.org Macros Explained" (OOME_4_1.odt) есть макрос AddOneLib, позволяющий копировать библиотеки.
Кроме того, изучите возможности диалогового окна
Меню / Сервис / Макросы / Управление макросами / Basic , кнопка "Управление", вкладки "Модули" и "Библиотеки".
Владимир.

timal1234

Цитата: sokol92 от Вчера в 15:13Кроме того, изучите возможности диалогового окна
Меню / Сервис / Макросы / Управление макросами / Basic , кнопка "Управление", вкладки "Модули" и "Библиотеки".

при попытке импорта пишет:
невозможно импортировать

timal1234

Цитата: sokol92 от Вчера в 15:13В замечательной книге Питоньяка "OpenOffice.org Macros Explained" (OOME_4_1.odt) есть макрос AddOneLib, позволяющий копировать библиотеки.

посмотрю

sokol92

Для библиотеки "Standard" можно использовать копирование модулей.
Владимир.

timal1234

Цитата: sokol92 от Вчера в 16:16Для библиотеки "Standard" можно использовать копирование модулей.

Цитироватькопирование модулей

это где ?  :roll:

sokol92

Цитата: sokol92 от Вчера в 15:13Меню / Сервис / Макросы / Управление макросами / Basic , кнопка "Управление", вкладки "Модули" и "Библиотеки".
Владимир.

timal1234

Цитата: sokol92 от Вчера в 16:27
Цитата: sokol92 от Вчера в 15:13Меню / Сервис / Макросы / Управление макросами / Basic , кнопка "Управление", вкладки "Модули" и "Библиотеки".


так выше это и была картинка при попытке импорта через  Управление макросами / Basic , кнопка "Управление", вкладка  "Библиотеки".

sokol92

До этого момента я считал, что "Модули" и "Библиотеки" - разные слова.
Владимир.

timal1234

Цитата: sokol92 от Вчера в 17:42До этого момента я считал, что "Модули" и "Библиотеки" - разные слова.
У меня нет кнопки копировать на вкладке Модули

Есть импорт , экспорт на вкладке Библиотеки

sokol92

Можно перетаскивать модули мышью (хотя это сомнительное удовольствие). Это проще, чем метод, описанный в стартовом сообщении.

Можно написать макрос на основе макроса AddOneLib Питоньяка.

Из собственного опыта: мы модули содержим в отдельных библиотеках (нe "Standard"). Исключение - функции, которые вызываются из ячеек листов документов Calc (UDF).
Владимир.

timal1234

Цитата: sokol92 от Вчера в 19:28Можно перетаскивать модули мышью (хотя это сомнительное удовольствие). Это проще, чем метод, описанный в стартовом сообщении.

Вот сомневаюсь, что это будет быстрее... Я за 5 минут (или меньше ) меняю 20 файлов. А мышкой всё это двигать , да , так себе удовольствие...

ЦитироватьМожно написать макрос на основе макроса AddOneLib Питоньяка.
Склоняюсь к этому.

ЦитироватьИз собственного опыта: мы модули содержим в отдельных библиотеках (нe "Standard"). Исключение - функции, которые вызываются из ячеек листов документов Calc (UDF).
Об этом не знал. И даже не задумывался, что мне нужно в отдельную библиотеку макросы класть.

Спасибо за ответы!
Буду пробовать макрос сделать.

timal1234

#12
Цитата: timal1234 от Вчера в 19:47Буду пробовать макрос сделать.

так будет работать?
макрос Copy_Library запускаю из файла-источника Source.ods

Sub Copy_Library

Dim oSourceLibs
oSourceLibs = ThisComponent.BasicLibraries


Dim oURL        'путь к файлу

'---------------------------------------------------------------------------
' ------ вызываем диалог открытия файла  -----------
GET_FILE(oURL)        '    возвращает путь к выбраному файлу в URL формате
'-----------------------------------------------------------------------------

If oURL = "" or IsNull(oURL) or IsEmpty(oURL) then
    MsgBox("Пустой путь !" & CHR(13) & "Выход из макроса.")
    Exit Sub
end if

'------------------------------------------------------------------------------
'    ---------------  открываем файл по URL ------------------
Dim oDocDestination As Object
oDocDestination = starDeskTop.loadComponentFromURL(oURL, "_blank", 0, Array() )    'файл куда копировать
'---------------------------------------------------------------
'------------------------------------------------------------------------------

Dim oDestinationLibs
oDestinationLibs = oDocDestination.BasicLibraries

'------------------------------------------------------------------------------
'------------ отправляем на копирование библиотеки ----------
    'AddOneLib(sSrcLib$, sDestLib$, oSrcLibs, oDestLibs, bClearDest As Boolean)
    'sSrcLib$ - это имя исходной библиотеки, содержащейся в oSrcLibs
    'sDestLib$ - это имя целевой библиотеки, содержащейся в oDestLibs
    'oSrcLibs - это контейнер исходной библиотеки
    'oDestLibs - это контейнер библиотеки назначения
    'если значение bClearDest равно True, то библиотека назначения очищается
AddOneLib("STANDARD", "STANDARD", oSourceLibs, oDestinationLibs, TRUE)
'---------------------------------------------------------------------
'------------------------------------------------------------------------------


Dim DestinationPath
DestinationPath = oDocDestination.getURL()    'путь к файлу назначения


''=================================================================
    ' Имя нового файла (в ту же директорию), добавляем ''(1)''
''====================================
Dim file 'As String  ' путь к входному файлу
file = ConvertFromURL(oDocDestination.URL) ' Получим URL документа и превратим его в строку
'или
'file = ConvertFromURL(DestinationPath) ' Получим URL документа и превратим его в строку

pos_cut = InStr(file, ".ods")   

Dim Cuted_Path
Cuted_Path = Left(file, pos_cut -1) ' обрезанный (без расширения) путь входного файла
                                               
Dim DestinationPath_NEW
DestinationPath_NEW = Cuted_Path &"(1)" & ".ods"    'новое имя выходного файла (полный путь с расширением)
''======================================
''=================================================


'---------------- сохраняем открытый файл назначения ---------------------
oDocDestination.storeAsURL( ConvertToURL( DestinationPath_NEW ) ) 'Save As'
'-------------------------------------------------------------------------

'---------------- закрываем открытый файл назначения ---------------------
oDocDestination.close(true)
'-------------------------------------------------------------------------

End Sub
'--------------------------------

'--------------------------------
Sub GET_FILE(Selected_File_Path)    ' возвращает путь к выбранному файлу в формате URL

Dim oFileDialog as Object        ' далог Открыть файл
Dim iOpenFile        ' результат выполнения диалога
Dim oFiles 'Возвращаемый диалогом выбора файла массив выбранных файлов

 
' задать, чтобы фильтр показывал только файлы ods '
oFileDialog = CreateUnoService("com.sun.star.ui.dialogs.FilePicker")
oFileDialog.appendFilter("Электронные таблицы (Calc)", "*.ods" )
iOpenFile = oFileDialog.Execute()
If iOpenFile = 0 Then
        MsgBox "Файлы не выбраны"
        Exit Sub
Else
    oFiles = oFileDialog.getFiles()
    IF UBound(oFiles) >= 0 THEN
        Selected_File_Path = oFiles(0)
    END IF
End If

End Sub
'--------------------------------

'--------------------------------
'Питоньяк "OpenOffice.org Macros Explained" (OOME_4_1.odt)
''Listing 527. Copy a library.
Sub AddOneLib(sSrcLib$, sDestLib$, oSrcLibs, oDestLibs, bClearDest As Boolean)
  Dim oSrcLib  'The source library to copy - это контейнер исходной библиотеки
  Dim oDestLib  'The destination library to receive the modules in oSrcLib - это контейнер библиотеки назначения
  Dim sNames
  Dim i%
 
  'If there is no destination library then simply return
  'Если целевой библиотеки нет, то просто вернитесь
  If IsNull(oDestLibs) OR IsEmpty(oDestLibs) Then
    Exit Sub
  End If

  'Clear the destination library if requested
  'Очистите целевую библиотеку, если потребуется
  If bClearDest AND oDestLibs.hasByName(sDestLib) Then
    oDestLibs.removeLibrary(sDestLib)
  End If

  'If there is no source library, then there is nothing else to do
  'Если исходной библиотеки нет, то делать больше нечего
  If IsNull(oSrcLibs) OR IsEmpty(oSrcLibs) Then
    Exit Sub
  End If

  'If the source library does not exist, then there is nothing else to do
  'Если исходная библиотека не существует, то больше ничего не остается делать
  If NOT oSrcLibs.hasByName(sSrcLib) Then
    Exit Sub
  End If

  'If the destination library does not exist, then create it
  'Если целевая библиотека не существует, то создайте ее
  If NOT oDestLibs.hasByName(sDestLib) Then
    oDestLibs.createLibrary(sDestLib)
  End If

  'the libraries must be loaded first.
  'Common mistake to not load the libraries first!
  'сначала должны быть загружены библиотеки.
  'Распространенная ошибка - не загружать библиотеки в первую очередь!
  oSrcLibs.loadLibrary(sSrcLib)
  oDestLibs.loadLibrary(sDestLib)

  'Get the source and destination libraries
  'Get all of the contained modules that should be copied
  'Получить исходную и целевую библиотеки
  'Получить все содержащиеся в них модули, которые необходимо скопировать
  oSrcLib = oSrcLibs.getByName(sSrcLib)
  oDestLib = oDestLibs.getByName(sDestLib)
  sNames = oSrcLib.getElementNames()

  'For each module, either add it or replace it
  'Для каждого модуля либо добавьте его, либо замените
  For i = LBound(sNames) To UBound(sNames)
    If oDestLib.hasByName(sNames(i)) Then
      oDestLib.replaceByName(sNames(i), oSrcLib.getByName(sNames(i)))
    Else
      oDestLib.insertByName(sNames(i), oSrcLib.getByName(sNames(i)))
    End If
  Next
End Sub