[Solved] .getScriptProvider() without "ThisComponent"?

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
joesch
Posts: 53
Joined: Mon Apr 20, 2020 9:49 am
Location: Germany, near Berlin

[Solved] .getScriptProvider() without "ThisComponent"?

Post by joesch »

Hello,

I want to start a Python script from LO and use:

Code: Select all

Dim oScriptProvider, oScript, RS_Python
	oScriptProvider = ThisComponent.getScriptProvider()
	'oScriptProvider = StarDesktop.CurrentComponent.getScriptProvider()
	oScript = oScriptProvider.getScript("vnd.sun.star.script:mysqlgetdata.py$resultx?language=Python&location=user")
	RS_Python = oScript.invoke(array(), array(), array())
This code fails if "ThisComponent" is not available (or Stardesktop.CurrentComponent is not a matching object). To work around this I use:

Code: Select all

Dim oScriptProvider, oScript, RS_Python, tmp_doc
	Dim par(0) As New com.sun.star.beans.PropertyValue
	
	par(0).Name = "Hidden"
	par(0).Value = True
	
	tmp_doc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, par())
	
	oScriptProvider = tmp_doc.getScriptProvider()
	'oScriptProvider = StarDesktop.CurrentComponent.getScriptProvider()
	oScript = oScriptProvider.getScript("vnd.sun.star.script:mysqlgetdata.py$resultx?language=Python&location=user")
	RS_Python = oScript.invoke(array(), array(), array())
	
	tmp_doc.Close(true)

Is there another way, which does without the hidden document trick?

Note: I have read viewtopic.php?f=20&t=79489 but this does not help me.


greetings,
joesch
Last edited by Hagar Delest on Tue Jul 13, 2021 7:55 am, edited 1 time in total.
Reason: tagged solved.
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: .getScriptProvider() without "ThisComponent"?

Post by Villeroy »

This is a module where I call 2 Python functions eval and soundex from StarBasic, so they are availlable as Basic functions without compiling a Python AddIn.

Code: Select all

REM  *****  BASIC  *****

REM Keep a global reference to the ScriptProvider, since this stuff may be called many times:
Global g_MasterScriptProvider

REM Specify location of Python script providing the cell functions:
Const URL_Main = "vnd.sun.star.script:pyCalc|SheetFunctions.py$"
Const URL_Args = "?language=Python&location=user"

Function getMasterScriptProvider()
   if NOT isObject(g_MasterScriptProvider) then
      oMasterScriptProviderFactory = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
      g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
   endif
   getMasterScriptProvider = g_MasterScriptProvider
End Function

Function SOUNDEX(s$, optional iLen%)
   sURL = URL_Main & "soundex" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   if isMissing(iLen) then
      i = 4
   else
      i = cInt(iLen)
   endif
   x = oScript.invoke(Array(s,i),Array(),Array())
   SOUNDEX = x
End Function

Function EVAL(s)
   sURL = URL_Main & "evaluate" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   x = oScript.invoke(Array(s),Array(),Array())
End Function
The 2 functions are stored in <user_profile>/Scripts/python/pyCalc/SheetFunctions.py

Code: Select all

import uno
import base64

def evaluate(s):
    try:
        r = eval(s)
    except:
        r = None
    return r
    
def soundex(name, len=4):
    """ soundex module conforming to Knuth's algorithm
        implementation 2000-12-24 by Gregory Jorgensen
        public domain
    """

    # digits holds the soundex values for the alphabet
    digits = '01230120022455012623010202'
    sndx = ''
    fc = ''

    # translate alpha chars in name to soundex digits
    for c in name.upper():
        if c.isalpha():
            if not fc: fc = c   # remember first letter
            d = digits[ord(c)-ord('A')]
            # duplicate consecutive soundex digits are skipped
            if not sndx or (d != sndx[-1]):
                sndx += d

    # replace first digit with first alpha character
    sndx = fc + sndx[1:]

    # remove all 0s from the soundex code
    sndx = sndx.replace('0','')

    # return soundex code padded to len characters
    return (sndx + (len * '0'))[:len]
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
joesch
Posts: 53
Joined: Mon Apr 20, 2020 9:49 am
Location: Germany, near Berlin

Re: .getScriptProvider() without "ThisComponent"?

Post by joesch »

Thank you, that works. I am now using:

Code: Select all

	oMasterScriptProviderFactory = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
	g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
	oScript = g_MasterScriptProvider.getScript("vnd.sun.star.script:mysqlgetdata.py$resultx?language=Python&location=user")
	RS_Python = oScript.invoke(Array(),Array(),Array())
The important things are the "" In:

Code: Select all

g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
that you can use this way, I didn't know from viewtopic.php?f=20&t=79489

greetings,
joesch
Post Reply