Can a user instantiate a built-in object? (com.sun.star.*)

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
octomancer
Posts: 6
Joined: Sat Apr 23, 2016 7:25 pm

Can a user instantiate a built-in object? (com.sun.star.*)

Post by octomancer »

Hi all,

I have a spreadsheet that I've constructed by hand, making it more and more functional and complex over time. I'm now trying to write Basic macros to build it from scratch.

I was trying to do a particular job and it occurred to me that it would be much easier if I could create an object which inherited the XNameAccess interface so I could use hasByName and getByName methods on it (I was actually on the point of writing my own module to implement what I needed). I've done a lot of googling, I've searched Andrew Pitonyak's book, I have the Xray tool installed ... I can't find what I need.

The best I have come up with so far is to create an array of com.sun.star.beans.PropertyValue objects and assign that array to the value property of a parent PropertyValue object. Then I can write some functions to implement similar methods to hasByName etc. This all seems horrendous!

I've worked with objects in Perl and JavaScript before and they're pretty nice to work with because both languages have first-class functions and a flexible object model. As far as I'm aware, OO Basic lacks both first class functions and the facility for user-created classes/objects. Does OO JS retain these features of other JS implementations?

Thanks in advance for any and all suggestions :-)
Rich
LibreOffice 4.4.3.2 on Linux Mint 17.2
JeJe
Volunteer
Posts: 2756
Joined: Wed Mar 09, 2016 2:40 pm

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by JeJe »

This place has stuff on classes etc

http://cereusapis.com/classes-and-objec ... ice-basic/
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Villeroy
Volunteer
Posts: 31264
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by Villeroy »

ComponentContext.ServiceManager.getAvailableServiceNames() => 1000 services (objects) from scratch.
newObj = ServiceManager.createInstance(srvName)
StarBasic: createUnoService(srvName)

someObject.SupportedServiceNames => service names that are included in this service (subclasses)

someObject.AvailableServiceNames => names of services that can be derived from this service by someObject.createInstance(srvName)

There is an interesting innovation in LO 5.1 regarding the Python bridge:
https://wiki.documentfoundation.org/Rel ... Francis.29
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
octomancer
Posts: 6
Joined: Sat Apr 23, 2016 7:25 pm

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by octomancer »

Thank you both for the suggestions. They both seem promising! I will try to figure out what I need tomorrow and report back :-)
LibreOffice 4.4.3.2 on Linux Mint 17.2
octomancer
Posts: 6
Joined: Sat Apr 23, 2016 7:25 pm

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by octomancer »

Hi,

So I've been trying to solve my problem using built in Uno services. I inspected the available services with this code (and utilising the excellent XRay tool):

Code: Select all

dim oSM as object

oSM = GetProcessServiceManager
xray oSM
Then I double clicked the getAvailableServiceNames method to get the list

The 2 services that look interesting are com.sun.star.container.EnumerableMap and com.sun.star.beans.PropertyBag. I looked at both and decided that EnumerableMap would be preferable, but I'm having trouble using it. I've started with this code

Code: Select all

	dim oAccount as object

	oAccount = GetProcessServiceManager.createInstance("com.sun.star.container.EnumerableMap")
	oAccount.put("name1", "value1")
This gives me a com.sun.star.lang.NotInitializedException. So eventually after some googling I got to this code

Code: Select all

	dim oAccount as object
	dim mArgs(1)

	oAccount = GetProcessServiceManager.createInstance("com.sun.star.container.EnumerableMap")
	oAccount.initialize(mArgs)
	oAccount.put("name1", "value1")
Now this gives me a com.sun.star.lang.IllegalArgumentException: com.sun.star.uno.Type expected..

And that's where I'm stuck. No matter what I try, how much I google, I can't find out how to create an object of type Type. Googling for this is not easy as you can imagine! I did stumble across the function CreateUnoValue but I can't get that to work either.

I'm not even sure this is the right way to go about my task any more, but I would like to solve this problem just for satisfaction.

All comments gratefully received.

Cheers,
Rich
LibreOffice 4.4.3.2 on Linux Mint 17.2
User avatar
Villeroy
Volunteer
Posts: 31264
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by Villeroy »

During all those years I've never came across com.sun.star.container.EnumerableMap. Looks like a hash (Perl), dictionary (Python), collection (VB). When I need any such structure, I use an appropriate programming language. Python is an excellent macro language for Open/LibreOffice.
I guess that you need to call the initialize() method of this object. But nobody knows the right arguments except for the programmers who don't shy away from the source code.
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
octomancer
Posts: 6
Joined: Sat Apr 23, 2016 7:25 pm

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by octomancer »

Hi,

I agree it does look like a Perl hash. No surprise, they're both key/value stores :-) And I think I know the arguments to the constructor... a 2 element array of com.sun.star.uno.Type objects, specifying the type of the keys and the type of the values. I just haven't been able to find out how to instantiate the type objects :-) I've found examples in the OpenOffice wiki do what exactly what I'm trying to do, but in Java. So far my guessing has not resulted in me discovering the right syntax in LO Basic :-) I've tried

Code: Select all

Dim vA as com.sun.star.uno.Type

Dim vA
vA = new com.sun.star.uno.Type

vA = createunovalue("com.sun.star.uno.Type", "string")

vA = GetProcessServiceManager.createInstance("com.sun.star.uno.Type")
None works. I knew the last one would fail because Type is not a service. The Java examples all use bareword API classes, as in my second example. I just think what I want to do is not possible in LO Basic. I suppose I could look at the bridge code, but ... NO.

I don't know Python (I'd like to learn it), but I do know Perl so I think I am going to do the heavy lifting in Perl. I'll write out a text file which will essentially be an array of what I want in my spreadsheet cells. Simple enough to read it in and use .setFormulaArray. LO Basic definitely is a pretty kinky language, as I've read elsewhere on this forum ;-) I used to write a little VB and VBA years ago and I don't remember it being this difficult!

Thanks for your time.

Cheers,
Rich
LibreOffice 4.4.3.2 on Linux Mint 17.2
User avatar
Villeroy
Volunteer
Posts: 31264
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by Villeroy »

Calc can import/export csv easily.
The database component can link spreadsheets to data sources such as other spreadsheets, csv, dBase and relational databases via ODBC or JDBC.
Many people do a lot of programming to export text from databases, import text into spreadsheets and apply formatting, calculations, charts to the imported text. All this can be performed easily without a single line of code just using links, templates and format styles.
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
User avatar
karolus
Volunteer
Posts: 1158
Joined: Sat Jul 02, 2011 9:47 am

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by karolus »

Hallo

@octomancer
ask about the problem, not about how you think it should be solved…

Karolus
AOO4, Libreoffice 6.1 on Rasbian OS (on ARM)
Libreoffice 7.4 on Debian 12 (Bookworm) (on RaspberryPI4)
Libreoffice 7.6 flatpak on Debian 12 (Bookworm) (on RaspberryPI4)
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by B Marcelly »

Hello,
Here is a Basic example of using EnumerableMap

Code: Select all

Option Explicit

Sub Main1
Dim PostCodeFR As Object
Dim k As String
Dim enu As Object, elem As Variant

PostCodeFR = com.sun.star.container.EnumerableMap.create("string", "long")
With PostCodeFR
  .put("EMBRUN",   CreateUnoValue("long", 05200))
  .put("GIENS",    CreateUnoValue("long", 83400))
  .put("AUXERRE",  CreateUnoValue("long", 89000))
  .put("HYERES",   CreateUnoValue("long", 83400))
  .put("THIVILLE", CreateUnoValue("long", 28200))
  .put("TAUSSAT",  CreateUnoValue("long", 33148))
  
  Do
    k = InputBox("Give a name of a locality", "")
    if Len(k) = 0  then Exit Do
    if .containsKey(k)  then
      MsgBox(.get(k), 0, k)
    else
      MsgBox("Unknown locality", 0, k)
    end if
  Loop
  
  enu = .createKeyEnumeration(False)
  Do While enu.hasMoreElements
    elem = enu.nextElement
    MsgBox("Key : " & elem)
  Loop

  enu = .createValueEnumeration(False)
  Do While enu.hasMoreElements
    elem = enu.nextElement
    MsgBox("Value : " & elem)
  Loop

  enu = .createElementEnumeration(False)
  Do While enu.hasMoreElements
    elem = enu.nextElement
    MsgBox("Key : " & elem.First & _
      chr(10) & "Value : " & elem.Second)
  Loop
  
  .clear
  enu = .createElementEnumeration(False)
  MsgBox("Any element ? " & enu.hasMoreElements)
End With
End Sub
  • The first instruction is a constructor for new-style services. These services can have different constructors, like here.
  • The second argument of put method uses CreateUnoValue because if the number is lower than 32768 the binding converts it to a short, not a long. This is cumbersome, I wrote Issue 121192 to ask for an improvement.
  • In my example, the same post code is used by different localities. This is usual in France.
  • The key strings are case sensitive.
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
octomancer
Posts: 6
Joined: Sat Apr 23, 2016 7:25 pm

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by octomancer »

Hi,

Thank you so much for posting such an informative chunk of code. It does indeed explain everything that I was finding so difficult. I'm not sure I'm going to stick with LO Basic though. It's quite tough to learn it. The only reason I decided on Basic for this task was because I have written VB and VBA before. But I think that the difficulty of navigating the learning resources obviates any advantage I might have gained. I was on the brink of learning Python anyway, so I'll be back in a few months with questions about Python programming for LO :-D

Thanks to all who took the time to post answers.

Cheers,
Rich
LibreOffice 4.4.3.2 on Linux Mint 17.2
octomancer
Posts: 6
Joined: Sat Apr 23, 2016 7:25 pm

Re: Can a user instantiate a built-in object? (com.sun.star.

Post by octomancer »

karolus wrote:Hallo

@octomancer
ask about the problem, not about how you think it should be solved…

Karolus
lol
LibreOffice 4.4.3.2 on Linux Mint 17.2
Post Reply