OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Trying to automate compare in Visual Basic: some problems.

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API
View previous topic :: View next topic  
Author Message
Chris_147
General User
General User


Joined: 28 Aug 2003
Posts: 27

PostPosted: Tue Sep 23, 2003 5:19 am    Post subject: Trying to automate compare in Visual Basic: some problems. Reply with quote

Hi,

I'm trying to automate the compare functionality in Writer (and Calc) to compare Office docs. But it doesn't seem to be very easy.
I recorded it with a macro in Writer, and tried to transform that to VB code:

Dim ServMan As Object
Dim Desktop As Object
Dim Document1 As Object
Dim Document2 As Object
Dim args() As Object
Dim args1(0) As Object
Dim Dispatcher As Object

Set ServMan = CreateObject("com.sun.star.ServiceManager")
Set Desktop = ServMan.CreateInstance("com.sun.star.frame.Desktop")
Set Document1 = Desktop.LoadComponentFromURL("file:///C:/test1.doc", "_blank", 0, args)

Set Dispatcher = ServMan.CreateInstance("com.sun.star.frame.DispatchHelper")

Set args1(0) = ServMan.CreateInstance("com.sun.star.beans.PropertyValue")
args1(0).Name = "ShowTrackedChanges"
args1(0).Value = True
Dispatcher.executeDispatch(Document1, ".uno:ShowTrackedChanges", "", 0, args1(0))
Dispatcher.executeDispatch(document1, ".uno:CompareDocuments", "", 0, Array())

The last two lines are not correct according to VB. But I have no idea what's wrong?!

Some remarks though:
* I searched the complete SDK on ShowTrackedChanges and found nothing?
* What is the Array() for? It never gets declared or initialised?
* What is the DispatchHelper for, what's its use?

So clearly I don't completely understand the OOo API...

Thanks for the help,

Chris
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Tue Sep 23, 2003 6:28 am    Post subject: Reply with quote

Quote:
What is the DispatchHelper for, what's its use?


The Developer's Guide discusses the dispatch mechanism here.

http://api.openoffice.org/docs/DevelopersGuide/OfficeDev/OfficeDev.htm#1+1+6+Using+the+Dispatch+Framework

From my reading and understanding of it, I would say that the dispatch mechanism is how the "front end", i.e the UI that you interact with, communicates with the "back end", i.e. the engine that does the work. Every command you issue is a dispatch event.

The macro recorder records these interactions between the UI and the back end, and then writes hideously ugly code that attempts to do the same thing, assuming you play it back with all conditions in the same initial state (i.e. selection, etc.). Macro recorder code therefore always deals with the interactions between the UI and the engine. Hand written code often deals directly with the API of the back end, and sometimes the frames or controllers on the front end, but usually avoids the dispatcher.

Quote:
What is the Array() for? It never gets declared or initialised?


Array() is a way to instantly create an anonymous array object.

Both of the following code examples have a very similar effect.


Example 1...
Code:

Dim x(3) As Long
x(0) = 382
x(1) = 928
x(2) = 139
x(3) = 879


Example 2...
Code:

x = Array( 382, 928, 139, 879 )


An empty array should be sort of like a Dim x() with no argument. An empty array. But rather than have one statement to dimension it, and have to assign it a name, and then pass the name to something, it is easier when you need an empty array to just write Array(). I like anonymous arrays so well that I often use Array(...) with some arguments in it, like this....

oDoc = StarDesktop.loadComponentFromURL( ........somestuff....,_
Array( MakePropertyValue( "FilterName", "Rich Text Format" ) ) )

where MakePropertyValue() is a function in my library that makes and returns a com.sun.star.beans.PropertyValue. I can write multiple calls to MakePropertyValue() in one Array() without dimensioning an array.

Quote:
I searched the complete SDK on ShowTrackedChanges and found nothing?


Me niether. I looked in the Index of the hyperlinked API. I also looked to see if there might be an XShow....anything.

Quote:
The last two lines are not correct according to VB. But I have no idea what's wrong?!


The whole Array() business is probably not valid in VB. I don't know VB, but I doubt it has anonymous arrays. So you would need to Dim whatever array you need, and pass that. The args1(0) probably is passing a single element not the entire array. I don't know VB, but I suspect that you should use some syntax that passes the entire array, not just the first element of the array. Like maybe args1(). Or just args1.

Quote:
file:///C:/test1.doc


You may need to use a syntax like this... file:///c|/test1.doc. Replace the colon with vertical bar. When in OOo-Basic, you must use this syntax. OOo basic provides a function ConvertToURL() which often hides this URL syntax, because it is often used like...

oDoc = StarDesktop.loadComponentFromURL( ConvertToURL( "c:\test1.doc" ), .....otherstuff..... )

Also in this same line of code, you'll note that you are passing the entire array args, not args(0). So if VB is not complaining about this line, the apparently, the syntax to pass the entire array is just the array name with no parens.

Quote:
args1(0).Name = "ShowTrackedChanges"


Ah ha! No wonder we couldn't find ShowTrackedChanges. It is a property name. I wonder if it might appear in the hyperlinked API documentation, but not on its own page. i.e. I wonder if a through search of the contents of each page would find it?

I hope this information helps you. I am not familiar with Writer, especially in regard to comparing documents. Good luck.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Chris_147
General User
General User


Joined: 28 Aug 2003
Posts: 27

PostPosted: Thu Oct 16, 2003 5:28 am    Post subject: Reply with quote

Hi Danny,

thanks for the lengthy reply, but I'm still having problems Sad

In this thead (http://www.oooforum.org/forum/viewtopic.php?t=3313) some usefull information came up on how to set arguments. (thanks Gibson)

One problem I still have is that I don't know on what to execute the "ShowTrackedChanges" and "CompareDocuments" properties.


I tried it with this : objCoreReflection.execute args1(0)
but that returns that execute is unknown.

Problem is that when I search for "ShowTrackedChanges" in the complete SDK, I get nothing back! Are these properties not described???

And to make matters worse: I cannot record a macro of the compare functionality anymore in 1.1. In RC3 (or 4?) I could, but it seems to be gone?!

In old macro code there was something like this:
Code:

Call Dispatcher.executeDispatch(Document1, ".uno:ShowTrackedChanges", "", 0, args1)
Call Dispatcher.executeDispatch(Document1, ".uno:CompareDocuments", "", 0, Array1)


But I don't know how to make a dispatcher...

Anybody any clues?
Back to top
View user's profile Send private message
gibson
General User
General User


Joined: 07 Oct 2003
Posts: 37

PostPosted: Thu Oct 16, 2003 6:32 am    Post subject: Reply with quote

Uhm, trying to understand.
I"ShowTrackedChanges" and "CompareDocuments" are uno commands, you can find a list of all command available here http://www.openoffice.org/files/documents/25/60/commands_11beta.html and here http://api.openoffice.org/servlets/ProjectDownloadList?action=download&dlID=12&JServSessionIdservlets=ewma7zeo61

Your approach to dispatch seems to be ok.
You create the object
Code:
Set Dispatcher = ServMan.CreateInstance("com.sun.star.frame.DispatchHelper")

and then you execute the command
Code:
call Dispatcher.executeDispatch(Document1, ".uno:ShowTrackedChanges", "", 0, args1(0))
(remember the Call or remove parenthesis)
".uno:ShowTrackedChanges" is the command, args array can be empty if ".uno:ShowTrackedChanges" doesn't need arguments, you can search for ShowTrackedChanges into the sxc linked above and look for arguments in the "attributes" column.

My only doubt is on "document1", I don't know if you can use the document or the frame, maybe you need to get the frame from the component you loaded with LoadComponentFromURL

I'm learning about dispatch right now so if I've news I'll tell you, look what I've done http://www.oooforum.org/forum/viewtopic.php?t=3295
Back to top
View user's profile Send private message
Chris_147
General User
General User


Joined: 28 Aug 2003
Posts: 27

PostPosted: Thu Oct 16, 2003 7:18 am    Post subject: Reply with quote

Gibson, you are SOOO right!!!

I changed my code to this:
Code:

Dim objServiceManager As Object
Dim objCoreReflection As Object


Private Sub Command1_Click()
Dim ServMan As Object
Dim Desktop As Object
Dim Document1 As Object
Dim Document2 As Object
Dim Frame As Object
Dim Window As Object
Dim args0() As Object
Dim Dispatcher As Object
Dim Array1() As Object
Dim args1(0 To 1)

'Creating service manager
Set objServiceManager = CreateObject("com.sun.star.ServiceManager")

'Creating a public object to use reflection for structured properties
Set objCoreReflection = objServiceManager.createinstance("com.sun.star.reflection.CoreReflection")

'Creating a Desktop to open files
Set Desktop = objServiceManager.createinstance("com.sun.star.frame.Desktop")

'Create the Dispatcher
Set Dispatcher = objServiceManager.createinstance("com.sun.star.frame.DispatchHelper")

'Open the file
Set Document1 = Desktop.LoadComponentFromURL("file:///C:/test1.doc", "_blank", 0, args0)

'Set the frame
Set Frame = Desktop.getCurrentFrame

'Set the arguments
Set args1(0) = OOoPropertyValue("ShowTrackedChanges", "True")
Set args1(1) = OOoPropertyValue("CompareDocuments", "True")

'Execute the comparison
Dispatcher.executeDispatch Frame, ".uno:ShowTrackedChanges", "", 0, args1
Dispatcher.executeDispatch Frame, ".uno:CompareDocuments", "", 0, args1

'Set Window = Frame.GetContainerWindow
'Window.SetVisible (True)
End Sub

Function OOoPropertyValue(cName, uValue)
Dim oPropertyValue As Object

   Set oPropertyValue = createStruct("com.sun.star.beans.PropertyValue")
   
   oPropertyValue.Name = cName
   oPropertyValue.Handle = -1
   oPropertyValue.Value = uValue
   oPropertyValue.State = 0
     
   Set OOoPropertyValue = oPropertyValue
End Function

Function createStruct(strTypeName)
Dim classSize As Object

   Set classSize = objCoreReflection.forName(strTypeName)
   Dim aStruct
   classSize.CreateObject aStruct
   Set createStruct = aStruct
End Function


and it works like a charm Smile
Only problem I have left is how to skip the dialog for opening the second file.
I want to do that also programmatically...
Any ideas?

Anyway, thanks for the help. For the next 10 minutes you are my God Smile

Chris
Back to top
View user's profile Send private message
gibson
General User
General User


Joined: 07 Oct 2003
Posts: 37

PostPosted: Thu Oct 16, 2003 7:23 am    Post subject: Reply with quote

Chris_147 wrote:
Gibson, you are SOOO right!!!
Only problem I have left is how to skip the dialog for opening the second file.
I want to do that also programmatically...
Any ideas?


The skipping of dialogs is my current problem Smile I'm working on that...hope someone can help
Back to top
View user's profile Send private message
Chris_147
General User
General User


Joined: 28 Aug 2003
Posts: 27

PostPosted: Thu Oct 16, 2003 7:24 am    Post subject: Reply with quote

Gibson wrote:

...you can find a list of all command available here http://www.openoffice.org/files/documents/25/60/commands_11beta.html
and here http://api.openoffice.org/servlets/ProjectDownloadList?action=download&dlID=12&JServSessionIdservlets=ewma7zeo61


Not trying to critisize my God-for-10-minutes, Laughing but:
That second one gives me a 404.
And the first one, indeed lists a link to commands, but when I click that I get the same page again??
Back to top
View user's profile Send private message
Chris_147
General User
General User


Joined: 28 Aug 2003
Posts: 27

PostPosted: Thu Oct 16, 2003 8:08 am    Post subject: Reply with quote

Did some testing:

* When files are read-only, it the compare functionality is not available Sad
(VB then gives a Uno.Runtime exception)

* This code doesn't work for Excel files. Calc opens the file correct, but with the ShowTrackedChanges, it gives again an exception.

And I thought I would quickly write a wrapper around OOo and be done with it Smile
Back to top
View user's profile Send private message
gibson
General User
General User


Joined: 07 Oct 2003
Posts: 37

PostPosted: Thu Oct 16, 2003 8:14 am    Post subject: Reply with quote

Both links works for me.
The first one is a list of commands, no link to click Smile
The second one it's a link to an sxc file. It can be retrieved also from here http://api.openoffice.org/servlets/ProjectDownloadList selecting SLOT.SXC
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Thu Oct 16, 2003 10:11 am    Post subject: Reply with quote

Chris_147 wrote:
Only problem I have left is how to skip the dialog for opening the second file.
I want to do that also programmatically...


Just guessing. Is the problem that a dialog appears on the CompareDocuments dispatch?

In the array args1, what if you add a third property specifying no interaction handler?

I notice that you create a single array of two properties: ShowTrackedChanges and CompareDocuments. Then you pass this same array to BOTH dispatch calls on ShowTrackedChanges and CompareDocuments?

The Calc spreadsheet of slots indicates what the possible arguments are to any given dispatch. I am wondering if the CompareDocument dispatch call supports the InteractionHandler or some other parameter that would prevent a dialog box from appearing?
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Chris_147
General User
General User


Joined: 28 Aug 2003
Posts: 27

PostPosted: Fri Dec 19, 2003 6:18 am    Post subject: Reply with quote

Hi DannyB,

About the 2 dispatch calls: only one is needed apparantly (so why the macro recorder added the second one, I don't know)
So it boils down to:
Code:

Set CompParams(0) = OOoPropertyValue("CompareDocuments", True)

'Execute the comparison
Dispatcher.executeDispatch Frame, ".uno:CompareDocuments", "", 0, CompParams


This code however opens a dialog where the user has to select a second file to compare. I want to automate this also...
I tried something like this:
Code:

Set CompParams(0) = OOoPropertyValue("InteractionHandler", False)
Set CompParams(1) = OOoPropertyValue("FileName", "file:///" & CompFile1)
Set CompParams(2) = OOoPropertyValue("CompareDocuments", True)

'Execute the comparison
Dispatcher.executeDispatch Frame, ".uno:CompareDocuments", "", 0, CompParams


And this in all possible order (for the CompParams), but no success.

Also tried to open 2 documents (even the second one hidden), but that also didn't work.

Does anybody have any idea on how to open the second file for comparison without user interaction?
Back to top
View user's profile Send private message
Chris_147
General User
General User


Joined: 28 Aug 2003
Posts: 27

PostPosted: Fri Jan 09, 2004 5:35 am    Post subject: Help needed with compare functionality Reply with quote

So,

I haven't got any further with comparing 2 documents.
(it would really be THE killer feature to introduce OOo at my work Smile)

Anyway, with the code above I can open one document and issue the command to compare, but unfortunately it opens a dialog box to choose the second document.

So some possible routes could be:

* can I fill in the parameters of this dialog box? Really have no idea, tried the suggestion of DannyB above, but that didn't work...

* Can I put the dialogbox to the correct position so that the user only has to click OK?

* I tried to understand the slots.sxc document mentioned above, but I really couldn't understand it. I find the compare command mentioned in it, but it doesn't mean anything to me...

Can anybody help me with this?

Chris
Back to top
View user's profile Send private message
estape
Newbie
Newbie


Joined: 15 Nov 2005
Posts: 3

PostPosted: Tue Nov 15, 2005 10:46 am    Post subject: Reply with quote

This post is quite old so I hope someone read my reply! I wrote a macro that compares two files using the command line (without showing the dialog to choose the second file). I use it for CVS diff:
Code:

sub CompareDocuments(file1, file2) 

   cURL1 = ConvertToURL( file1 )
     
 
   Set objServiceManager = CreateObject("com.sun.star.ServiceManager")

   'Creating a Desktop to open files
   Set Desktop = objServiceManager.createinstance("com.sun.star.frame.Desktop")
   
   'Creating a public object to use reflection for structured properties
   rem   Set objCoreReflection = objServiceManager.createinstance("com.sun.star.reflection.CoreReflection")
   
   ' Open the document.
   oDoc = Desktop.loadComponentFromURL( cURL1, "_blank", 0, Array() ) 

   rem ----------------------------------------------------------------------
   rem define variables
   dim document   as object
   dim dispatcher as object
   rem ----------------------------------------------------------------------

   'Create the Dispatcher
   dispatcher = objServiceManager.createinstance("com.sun.star.frame.DispatchHelper")

   rem get access to the document
   rem document   = ThisComponent.CurrentController.Frame
   document = Desktop.getCurrentFrame()

   rem ----------------------------------------------------------------------
   dim args1(0) as new com.sun.star.beans.PropertyValue
   args1(0).Name = "ShowTrackedChanges"
   args1(0).Value = true
   
   dispatcher.executeDispatch(document, ".uno:ShowTrackedChanges", "", 0, args1())
   
   rem ----------------------------------------------------------------------
   rem open the second file
   
   cURL = ConvertToURL(file2)
   
   properties = []
   dim p(0) as new com.sun.star.beans.PropertyValue
   p(0).Name = "URL"
   p(0).Value = cURL
   
   dispatcher.executeDispatch(document, ".uno:CompareDocuments", "", 0, p())
   
end sub



I really don't know a lot of macros so I wrote it doing cut and paste from other macros. I use OpenOffice 2.0. It works fine if OpenOffice (or quickstarter) is already open when I run the macro, but if I call the macro from the command line and OpenOffice is not running I get an error:
Iin the line
Code:
Set Desktop = objServiceManager.createinstance("com.sun.star.frame.Desktop")

I get the error
BASIC runtime error. An exception occurred Type: Unknown Message: [automation bridge] The dispatch object does not support ITypeInfo!

If I change the order of the instructions I get the error always in the line after
Code:
   Set objServiceManager = CreateObject("com.sun.star.ServiceManager")


So maybe I have to wait in some way to the ServiceManager is really created.

To work arround the problem I have to start OOo quickstarter. Does anyone know if I'm doing something wrong?

Octavi
Back to top
View user's profile Send private message
consoleye
Newbie
Newbie


Joined: 15 Feb 2007
Posts: 1

PostPosted: Thu Feb 15, 2007 2:37 pm    Post subject: Reply with quote

CreateObject("com.sun.star.ServiceManager") seems to be deprecated.
After hunting in docs etc. I modified your code in two places and it seems to be working now in openoffice.org-2.0
I switch the deprecated call to CreateUnoService()

I run it as follows:
openoffice.org-2.0 -nodefault "macro:///Standard.CompareDocs.CompareDocuments(fileV1.odt,fileV2.odt)"

it would be nice if the output went into a pdf file and could be use with -headless

Code:

Sub CompareDocuments(file1, file2)

   cURL1 = ConvertToURL( file1 )
 
   'Creating a Desktop to open files
   Set DeskTop = CreateUnoService("com.sun.star.frame.Desktop")

   ' Open the document.
   oDoc = Desktop.loadComponentFromURL( cURL1, "_blank", 0, Array() )

   rem ----------------------------------------------------------------------
   rem define variables
   dim document   as object
   dim dispatcher as object
   rem ----------------------------------------------------------------------

   'Create the Dispatcher
   dispatcher = CreateUnoService("com.sun.star.frame.DispatchHelper")

   rem get access to the document
   rem document   = ThisComponent.CurrentController.Frame
   document = Desktop.getCurrentFrame()

   rem ----------------------------------------------------------------------
   dim args1(0) as new com.sun.star.beans.PropertyValue
   args1(0).Name = "ShowTrackedChanges"
   args1(0).Value = true
   
   dispatcher.executeDispatch(document, ".uno:ShowTrackedChanges", "", 0, args1())
   
   rem ----------------------------------------------------------------------
   rem open the second file
   
   cURL = ConvertToURL(file2)
   
   properties = []
   dim p(0) as new com.sun.star.beans.PropertyValue
   p(0).Name = "URL"
   p(0).Value = cURL
   
   dispatcher.executeDispatch(document, ".uno:CompareDocuments", "", 0, p())

End Sub
Back to top
View user's profile Send private message
estape
Newbie
Newbie


Joined: 15 Nov 2005
Posts: 3

PostPosted: Fri Feb 16, 2007 12:38 am    Post subject: Reply with quote

Now works fine!! Thanks!

For conversion to pdf maybe you could mix it somehow with these macros:

http://www.oooforum.org/forum/viewtopic.phtml?t=3772

Octavi
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
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