| View previous topic :: View next topic |
| Author |
Message |
larsenkc Guest
|
Posted: Sat Dec 20, 2003 5:45 am Post subject: instantiating objects in OOBasic |
|
|
I'm writing a macro in OOBasic to take information from a Writer document, arrange and format it, and put it in another Writer document. WIthin my program, I want to hold a collection of strings in some type of container. Basic array cannot be declared without a size, which I don't know until I've finished pulling my strings out of the document. I'd like to use a XIndexContainer, but for the life of me, I cannot instantiate any type of container. I tried saying
ThisComponent.createInstance("com.sun.star.sdbcx.Container")
but it says that I get a com.sun.star.lang.ServiceNotRegisteredException. But the same syntax works for some other objects, such as a TextField. The obvious explanation is that a TextDocument can't create a Container. But in my helpless wandering through docs, I found that a TextDocument is supposed to implement XMultiServiceFactory (the API doesn't mention this) and that is supposed to be able to tell me what it can create. I said
ThisComponent.Dbg_SupportedInterfaces
and it says that ThisComponent is supposed to implement XMultiServiceFactory. One method of XMultiServiceFactory is getAvailableServiceNames(). So I said
ThisComponent.getAvailableServiceNames()
and it tells me "Action not supported, Invalid service call". So, can somebody please tell me how to get a simple little container in OOBasic?
Thanks
Kelly |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 3991 Location: Lawrence, Kansas, USA
|
Posted: Sat Dec 20, 2003 7:22 am Post subject: |
|
|
Sadly, OOo doesn't provide any general purpose containers for Basic programmers to use.
The container interfaces are very useful, but they are just that: Interfaces. Various services offer these collection interfaces so that you can access contents in a uniform manner. Any two services that implement, say, XNameAccess might have completely different internal implementations.
I have considered writing a component in Python that would offer a number of useful new services to Basic programmers. Then the issue would be getting that component installed. In the past, the only way to do this that I could see would be with the pkgchk tool. This kind of defeats the whole ease of distributing a Basic program. I may reconsider at some point, as I may be able to create the python file in the right location, and then register a component via. the API to the registry, and not use pkgchk at all.
Now for an answer to your problem.
You can use arrays, even if you don't know the size in advance. Use Redim Preserve.
Dim x( 4 )
...later....
Redim Preserve x( 5 )
The array "x", is actually a variable containing an array, sort of like a java.util.Vector (but without any convenient features). You can return the array from a function, or pass it as a parameter. You could even....
x = Array( 23, 45, 69 )
to initialize the array with elements zero to two. Then say...
Redim Preserve x( 5 )
to add three more elements to it.
See this message I recently wrote....
http://www.oooforum.org/forum/viewtopic.php?p=17049#17049
In this message, see the function StringToByteArray. This function takes a string as a parameter, and returns as a function result an array of integers (byte values). This illistrates returning an array as a function result. The opposite function ByteArrayToString takes an array as a parameter. I know I've written other code that dynamically redimensions an array (Redim Preserve) within a loop, but I can't think of an example that I would have posted. _________________ Want to make OOo Drawings like the colored flower design to the left? |
|
| Back to top |
|
 |
larsenkc Guest
|
Posted: Sat Dec 20, 2003 8:19 am Post subject: interface |
|
|
Thanks for your response! But I always have more questions...
Why am I unable to use the interface XMultiServiceFactory? What else am I unable to do, that the docs say I should be able to do?
Where is the language-specific documentation I saw mentioned somewhere in the API?
How can I find the length of a Basic array?
Can I use Redim Preserve to make an array smaller?
Somewhere out there, is there robust documentation for OOBasic, that would have told me about Redim Preserve and other useful tools?
In the example StringToByteArray, you return an array w/o dimension, as if it were an empty array. When the caller receives this back, does the variable it is assigned to need to be dimensioned? Or does the array travel seamlessly, without the need for everybody to know its size?
In the post you referred me to, you discuss SimpleFileAccess. I attempted to save a file using the XStorable interface, following the Developers' Guide, but was unsuccessful. SimpleFileAccess looks much simpler. How do these two relate?
Thanks much for your help!
Kelly |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 3991 Location: Lawrence, Kansas, USA
|
Posted: Sat Dec 20, 2003 9:47 am Post subject: |
|
|
You can use the interface XMultiServiceFactory as part of any Service which provides that interface.
For instance, a Calc document model provides the XMultiServiceFactory, so you can use that interface to create new instances that the Calc document is able to create. The Calc document model will document which services it is able to create for you as part of its XMultiServiceFactory.
For example, if I needed to create a Draw Rectangle Shape, I would not ask a Calc document's XMultiServiceFactory to create it for me. I would ask a Draw document's XMultiServiceFactory to create me a RectangleShape.
Other services should be created at the XMultiServiceFactory of the ServiceManager. In fact, this seems to be the only purpose of the ServiceManager is to obtain new objects.
In OOo Basic (not the same as MS Visual Basic) you can use built in functions LBound() and UBound() to find the lower and upper bounds of an array. I commonly write code like this....
For i = LBound( aArray ) To UBound( aArray )
oElement = aArray( i )
....do something....
Next
You should be able to use Redim Preserve to make an array smaller or larger. I generally have only tried larger.
I only found out abomt Redim Preserve here on OOoForum. I believe that whoever answered my question about it pointed me to the Basic programmer's guide.
If you write something like...
x = StringToByteArray( "Hello There" )
the variable "x" is now an array with the dimensions returned by the function. Since "Hello There" has 11 characters, then x would have elements zero thru ten.
XStorable is unrelated to XSimpleFileAccess.
XStorable is part of a document that allows a document, such as a spreadsheet, to be saved to disk.
XSimpleFileAccess provides you a mechanism to manipulate files and folders via. the API. _________________ Want to make OOo Drawings like the colored flower design to the left? |
|
| Back to top |
|
 |
larsenkc Guest
|
Posted: Sat Dec 20, 2003 10:14 am Post subject: few more things... |
|
|
Since TextDocument provides the XMultiServiceFactory interface, do you have any idea why I was unable to get the list of services it could create? (see first post)
Where can I find the Basic programmer's guide? I've been using the Help in OOo, which leaves much to be desired.
Does XSimpleFileAccess have all the functionality of XStorable? Or are they both needed in different situations?
Thanks.
Kelly |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 3991 Location: Lawrence, Kansas, USA
|
Posted: Sat Dec 20, 2003 10:47 am Post subject: |
|
|
Basic Programmer's Guide is here....
http://docs.sun.com/db/coll/999.2
Part of your answer is here...
http://www.oooforum.org/forum/viewtopic.php?p=17276#17276
I thought it wise to start a new thread about the UCB for everyone's benefit.
Not all services can be instantiated (createInstance) from every possible XMultiServiceFactory. See the documentation for the DrawingDocument, for example....
http://api.openoffice.org/docs/common/ref/com/sun/star/drawing/DrawingDocument.html
This has the service DrawingDocumentFactory
http://api.openoffice.org/docs/common/ref/com/sun/star/drawing/DrawingDocumentFactory.html
This service has the XMultiServiceFactory for creating services. But it cannot just create any service. Only certian ones. As you can see, the DrawingDocumentFactory (which has XMultiServiceFactory as an interface) can create, for example, a ClosedBezierShape, or a LineShape, or EllipseShape. But I would not expect a DrawingDocumentFactory, and therefore a DrawingDocument to be able to create, say, a spreadsheet document.
You can get a list of the services that any XMultiServiceFactory offers.
| Code: | Sub Main
' Create a new drawing.
oDoc = StarDesktop.loadComponentFromURL( "private:factory/sdraw", "_blank", 0, Array() )
' Get a list of the services it can create from its XMultiServiceFactory,
' which is really part of it's DrawingDocumentFactory.
' Note that aServices will contain an array after this statement.
' What we're doing is getting a list of the services that the XMultiServiceFactory
' of a drawing document can create. We could get such a list from any XMultiServiceFactory.
aServices = oDoc.getAvailableServiceNames()
' Create a Writer document to dump list of service names to.
oOutput = StarDesktop.loadComponentFromURL( "private:factory/swriter", "_blank", 0, Array() )
' Iterate over each element of the array...
For i = LBound( aServices ) To UBound( aServices )
' get the array element, which is a service name.
cServiceName = aServices( i )
' Print it into a writer document.
Writer_PrintLn( oOutput, cServiceName )
Next
End Sub
|
Sorry for the length of this simple function, but OOo code often needs more lines of comments than of code.
The above macro does the following....
1. Create a new Drawing document (which has an XMultiServiceFactory)
2. Get a list of the services that this factory knows how to create.
3. Create a writer document.
4. Dump a listing of services from step 2 into the writer document.
Note especially the use of the technique LBound() and UBound(), since I don't know what the array bounds are. Also note that the array is assigned as the result of a method call from OOo. Similar to my StringToByteArray() function mentioned earlier.
Of course, to make the above work, you need a couple useful subroutines.
| Code: | Sub Writer_Print( oDoc, cString )
oText = oDoc.getText()
oCursor = oText.createTextCursor()
oCursor.gotoEnd( False )
nLen = Len( cString )
nStart = 1
Do
nPos = Instr( nStart, cString, Chr(13) )
bCRFound = (nPos > 0)
If Not bCRFound Then
nPos = nLen + 1
EndIf
cSegment = Mid( cString, nStart, nPos-nStart )
nStart = nPos + 1
oText.insertString( oCursor, cSegment, False )
If bCRFound Then
oText.insertControlCharacter( oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
EndIf
Loop While bCRFound
End Sub
Sub Writer_PrintLn( oDoc, Optional cString )
If IsMissing( cString ) Then
cString = ""
EndIf
Writer_Print( oDoc, cString + Chr(13) )
End Sub
|
This is fun. Keep asking questions. Unfortunantly, sometimes I don't have time for a detailed answer. Let's see how fast I can get in over my head. Or alternately, learn something new, as I just did with the code above to print a list of services that a factory can create. I honestly did not know about getAvailableServiceNames() until now. _________________ Want to make OOo Drawings like the colored flower design to the left? |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 3991 Location: Lawrence, Kansas, USA
|
|
| Back to top |
|
 |
larsenkc Guest
|
Posted: Sat Dec 20, 2003 11:48 am Post subject: getAvailableServiceNames() |
|
|
I'm glad you're having fun; I am too, with this program. I also have fun whenever I'm on the answering end of the questions.
If you go back to my first post, I had tried getAvailableServiceNames() and got an error. This was part of my frustration; that it was supposed to exist, but didn't. Now I copied & pasted your code, and it worked. I have no idea why mine didn't, but it's long since been deleted.
When I get an error message in OOBasic, how can I figure out what the real error is?
The Basic Programmer's Guide is for StarOffice 6.0. I downloaded it once before, only to find that the API was very different then. Writing code based on this old reference is self-torture, because when I run it, half the syntax doesn't work anymore. Auuuggghhhh!! |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 3991 Location: Lawrence, Kansas, USA
|
Posted: Sat Dec 20, 2003 12:31 pm Post subject: |
|
|
Are we talking about the same version? Star Office 6.0 should be like OOo 1.0. Star Office 7.0 should be like OOo 1.1. Star Office 5.x should be like before OOo really existed.
When I was first learning to program OOo, I got something called a "StarBasic Programmer's Tutorial" or something like that, and it was indeed for SO 5.2, which was not quite like OOo.
Since OOo 1.0 and 1.1 are very similar in their API, I would expect SO 6.0 and 7.0 to be similar.
Personally, the only docs I use these days are the Developer's Guide
http://api.openoffice.org/DevelopersGuide/DevelopersGuide.html
(Developer's Guide TOC is here)
http://api.openoffice.org/docs/DevelopersGuide/DevelopersGuide.htm
and the online API reference....
http://api.openoffice.org/docs/common/ref/com/sun/star/module-ix.html
The kind of documentation you're looking for still needs to be written.
But honest, once you learn how to "surf" the API reference, and cross reference it with the Developer's Guide, and do lots of first hand experiments, and keep a lab notebook, you can really figure out just about anything about OOo.
It's a detective game.
I'm going to continue this in a seperate thread about Array Semantics.
http://www.oooforum.org/forum/viewtopic.php?p=17287#17287
Of course, feel free to continue other questions here. _________________ Want to make OOo Drawings like the colored flower design to the left? |
|
| Back to top |
|
 |
larsenkc Guest
|
Posted: Mon Dec 22, 2003 12:41 am Post subject: prog guide |
|
|
I looked at the StarBasic Prog Guide again, and it does indeed help me. I guess it just didn't help for whatever I needed before. My bad.
I know that I can figure out what I need from the Dev Guide & API, it's just that when I've been searching for a few hours, and I finally give up and come here, and it's 4 AM so I have to wait even longer for an answer, I get whiny like a user. But really, I should just shut up & go to bed. Programming is a social endeavor, and I shouldn't expect to get it all out of books. :oP |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 3991 Location: Lawrence, Kansas, USA
|
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 3991 Location: Lawrence, Kansas, USA
|
|
| Back to top |
|
 |
dysmas Power User

Joined: 14 Apr 2007 Posts: 59 Location: Grenoble, France
|
Posted: Fri Mar 28, 2008 7:06 am Post subject: |
|
|
Hello,
this is an old thread, but my question is related to it.
I want to use the TextLayout interface, which implies to first instantiate the XCanvasFactory.
But I have been unable to do that, and I get the com.sun.star.lang.ServiceNotRegisteredException
message.
==========================================================
I edit this message, because I found the right code, and just in case it may help someone, here it is :
| Code: | Set OpenOffice = CreateObject("com.sun.star.ServiceManager")
Set oCanvasF = OpenOffice.createInstance("com.sun.star.rendering.CanvasFactory")
|
_________________ Dysmas |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|