Access to Macro in Another File

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
Koosha
Posts: 7
Joined: Sat Feb 18, 2017 9:56 pm

Access to Macro in Another File

Post by Koosha »

How can I access to a macro which is in another file? I need to write the Macro once and use it in several Open Office Calc files.
OpenOffice 4, Windows 10
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Access to Macro in Another File

Post by Zizi64 »

I need to write the Macro once and use it in several Open Office Calc files.
In this case you must to put the macro code into Mymacros Standard library (located in the user profile of the office suite) instead od the Standard library of the document file. The macro will be available for all of the ODF files on you PC.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
Koosha
Posts: 7
Joined: Sat Feb 18, 2017 9:56 pm

Re: Access to Macro in Another File

Post by Koosha »

Thank you for your comment. Currently I am using this method, but the problem is the programs I wrote are not accessible on others computer in the office. I need to copy the code to all computers every time.
OpenOffice 4, Windows 10
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Access to Macro in Another File

Post by Zizi64 »

If those computers are in same LAN, then you can copy the code automatically with a batch file.

Our computers refresh the macro library of the LibreOffice suite at every starting (after the user switching on the PC) from a central storing computer (It is not a "server" really, but it is always switched on).
The batch file is located in the Launchpad of the Windows on the User's PC, and it contains one copy command only with the source and target paths.

If the "central computer" is not the your computer, the you can copy the macro library from your computer to the central computer by a similar batch file. Launch it manually, when you finishaed the macro editing in the office suite.

The phisycal location of the My Macros Standard Library is in the User profile on the AOO or LO.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Access to Macro in Another File

Post by Zizi64 »

...or you can transfer the Standard library by a document, and a special macro:

viewtopic.php?f=45&t=37459&p=172097

Just sent the document by e-mail, or other way, and the user need open it, and then just one click: the Standard macro library will refresh with the macros stored in the document.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
ElFlamencoLoco
Posts: 20
Joined: Mon Dec 28, 2015 8:45 pm

Re: Access to Macro in Another File

Post by ElFlamencoLoco »

Since I've written several OOBASIC-applications (.ott-templates), that nevertheless use a lot of common subroutines, I've put those common subroutines into a kind of "service module" (itself also a .ott-template).

Each application starts opening the common service module (if not allready open) - macros enabled of course. The common service module has no startup macro.

Each application has a library (named "Interface") that "doubles" the routines in the service module, so you can call them with ease. The hearth of that Interface-library is the routine "CallExtern"

Code: Select all

function CallExtern(byval macroname as string, _
  optional arg1 as variant, _
  optional arg2 as variant, _
  optional arg3 as variant) _
  as variant
  dim oSp as object,oScript as object,oModule as object

  'Find the component of the service module
  oModule = getModuleFile(URL_of_servicemodule)

  'Find the script
  oSp = oModule.getScriptProvider()
  oScript = oSp.getScript("vnd.sun.star.script:"+ _
    macroname+"?language=Basic&location=document")

  'Run script without parameters
  IF isMissing(arg1) THEN
    CallExtern=oScript.invoke(Array(),Array(),Array())

  'Run script with parameters by value, but no parameters by reference
  ELSEIF isMissing(arg2) THEN
    CallExtern=oScript.invoke(arg1,Array(),Array())

  'Run script with at least 1 parameter by reference
  ELSE
    CallExtern=oScript.invoke(arg1,arg2,arg3)
  END IF
END FUNCTION
Now, for each routine in the service module, write (in the application's library "Interface") a routine, calling the routine with the same name in the service module. Here some examples.

A sub without parameters, closing all open Writer documents (exept the application and the service module). (The actual sub is implemented in service module's library "Public", module "FileHandling".)

Code: Select all

sub CloseAllDocuments
  CallExtern("Public.FileHandling.CloseAllDocuments")
END SUB
A function without parameters, returning the current date and time in format "YYYYMMDDhhmmss". (The actual function is implemented in the service module's library "Public", module "DateTime".)

Code: Select all

function getCurrentDateTime as string
  getCurrentDateTime=CallExtern("Public.DateTime.getCurrentDateTime"
END FUNCTION
A function result (and a parameter by reference) should be of type STRING, INTEGER or OBJECT. BYTE and DATE might cause problems! For instance, a function that returns a date, stored somewhere in a document. Both the calling application ánd the service module have a function, declared as:

Code: Select all

function getEditionDate(byval path as string) _
  as date
The actual implementation in the service module is beyond the purpose of this posting. Our attention is needed how to pass DATE-values. So the calling routine in the application looks like this:

Code: Select all

function getEditionDate(byval path as string) _
  as date
  dim args_in(2) as variant, _
      args_outorder(2) as integer, _
      args_out(3) as variant

  'Sets parameter "path"
  args_in(0)=path

  'Call to service module
  CallExtern("Public.DateTime.Pass_getEditionDate", _
             args_in, _
             argsoutorder, _
             args_out)

  'Reassemble the date
  getEditionDate=DateSerial(args_out(0),args_out(1),args_out(2))
END FUNCTION
I remark that the called function has the prefix "Pass_". In the service module, this "Pass_"-routine is implemented as:

Code: Select all

sub Pass_getEditionDate(byval path as string, _
                        byref YearValue as integer, _
                        byref MonthValue as integer, _
                        byref DayValue as integer)
  dim DateValue as date
  
  'Call to the "real" routine
  DateValue=getEditionDate(path)
  
  'Return parameters by reference by "disassembling" the DATE-value
  YearValue=Year(DateValue)
  MonthValue=Month(DateValue)
  DayValue=Day(DateValue)
END SUB
In short:
  1. In the calling routine, disassemble or convert other types than INTEGER,
    STRING or OBJECT.
  2. Call the "Pass_" routine that reassembles the values...
  3. ... calls the "real" routine and...
  4. ... disassembles other types than INTEGER, STRING or OBJECT.
  5. The calling routine reassembles everything, in order to maintain the same syntax.
Design the application's "interface" routine with exactly the same parameter syntax (and/or function result type) as the "real" routine in the service module. Much easier when programming, since you can use the same syntax in the application ánd in the service module.
Windows 10
OpenOffice 4.1.2
Post Reply