VB.Net Dilemma - Libre Vs Open Office

I get it, there is more than one way to do the same thing in with the LO API. One of the dilemma’s I have had is in trying to employ various VBNET examples I’ve found here and elsewhere which purport to use the Libre Office API, but which do not result in identical/equivalently instantiated (Writer) variables for the same object (e.g., the document) and which do not allow the same methods to be used on them and also which do not allow communication with one another. The code below demonstrates all these dilemmas. Simply put, it seems that ‘one way’ of doing something is completely independent of the other(s?) and which does not allow interaction with any other(s?). Notably, I have not installed Open Office nor its SDK on my new development computer, IOWs I never installed anything but LO on it, but I am left to wonder if OO isn’t somehow still available in the LO SDK/API…?

In all this, I have examined the LO Object model, other LO documentation, the Pitonyak document on LO/OO Macros in LO Basic, numerous LO Basic examples and other language examples which I’ve converted (used online converters) to VBNet and through all of it I have found no ‘primer’ to help direct my programming efforts to find a single (or even multiple) protocols (i.e., proper syntax, ‘Typing’ methods) for employing ~all~ of the LO API functionality.

The below code is a .Net Framwork (4.8) VBNet, single file, project. It runs, but demonstrates how some methods for creating a VBNet project run successfully and others do not. In the code my comments include questions about this.

This is a big ask, there are a lot of embedded questions, but can someone please look at the VBNet code below and then help me with these 4 primary questions:

  1. Is the Open Office API being employed for either or both of the examples? How can I look at an example (in any language) and know if its using the Libre Office API or the Open Office API. I know that LO came out of OO and the two must be somewhat similar/inter-changeable, but its unclear where the demarcation line between the two lies.
  2. Does LO API require employing OO constructs, variables and/or methods. How can I know when to use any of these objects?
  3. Why does the code underlying the 3rd button fail?
  4. Why does the code underlying the 4th button fail?

To test/use this code, create a VBNet solution (.Net Framework 4.8) with one form in it. Add 4 buttons (named 1 through 4) and a textbox. Then attach the appropriate code below to the buttons and the textbox. Attached is a picture of the form I created in the solution I created in Visual Studio…The text added to the buttons and elsewhere on the form is instructive. You’ll also need to have a LO Writer Document with the text ‘FindMe’ shown in several locations. Finally, you need to also add an OpenFileDialog to the form. It is used when you double click in the text box.

Option Explicit Off
Option Strict Off

'I’m Sure Not All These Imports are Required, but… Where Can I find which are needed to do what in LO Documentation?
Imports System
Imports System.IO
Imports System.Collections
Imports Microsoft.VisualBasic
'Imports uno
'Imports unoidl
Imports uno.util
Imports unoidl.com.sun.star
Imports unoidl.com.sun.star.text
Imports unoidl.com.sun.star.lang
Imports unoidl.com.sun.star.uno
Imports unoidl.com.sun.star.bridge

Imports unoidl.com.sun.star.frame
Imports unoidl.com.sun.star.view
Imports unoidl.com.sun.star.beans
Imports unoidl.com.sun.star.container
Imports unoidl.com.sun.star.util
Imports unoidl.com.sun.star.packages.zip
Imports unoidl.com.sun.star.sdb.tools
Imports unoidl.com.sun.star.sdbcx
Imports unoidl.com.sun.star.sdbc
Imports unoidl.com.sun.star.awt
Imports unoidl.com.sun.star.graphic
Imports unoidl.com.sun.star.drawing
Imports unoidl.com.sun.star.script.provider

Public Class Form1

Public loDocXComponentContext As XComponentContext = Nothing
Public loXMultiServiceFactory As XMultiServiceFactory = Nothing
Public loXMultiComponentFactory As XMultiComponentFactory = Nothing
Public loDocXComponentLoader As unoidl.com.sun.star.frame.XComponentLoader = Nothing
Public loXDocDesktop As unoidl.com.sun.star.frame.XDesktop = Nothing
Public loDocArProps() As unoidl.com.sun.star.beans.PropertyValue = Nothing
Public loDocXComponent As unoidl.com.sun.star.lang.XComponent
Public loDocXTextDocument As unoidl.com.sun.star.text.XTextDocument = Nothing
Public loDocXText As unoidl.com.sun.star.text.XText = Nothing
Public loDocXTextRange As unoidl.com.sun.star.text.XTextRange = Nothing
Public loDocXTextCursor As unoidl.com.sun.star.text.XTextCursor = Nothing
Public loDocXGraphicProvider As unoidl.com.sun.star.graphic.XGraphicProvider = Nothing

Public loDocXServiceManager As Object

Public loDocXSimpleText As unoidl.com.sun.star.text.XSimpleText = Nothing

Public loXDispatchHelper As XDispatchHelper
Public loXDispatchProvider As unoidl.com.sun.star.frame.XDispatchProvider = Nothing
Public loDocFrame As unoidl.com.sun.star.frame.Frame = Nothing
Public loDocXFrame As unoidl.com.sun.star.frame.XFrame = Nothing
Public loDocXViewCursor As unoidl.com.sun.star.view.XViewCursor = Nothing
Public loDocXFrameCursor As unoidl.com.sun.star.text.XTextCursor = Nothing

Public loDocXTextTable As unoidl.com.sun.star.text.XTextTable = Nothing
Public loDocXTextFrame As unoidl.com.sun.star.text.XTextFrame = Nothing
Public loDocXTextContent As unoidl.com.sun.star.text.XTextContent = Nothing
Public loDocXTableRows As unoidl.com.sun.star.table.XTableRows = Nothing

Public loDocXDrawPage As unoidl.com.sun.star.drawing.XDrawPage = Nothing
Public loDocGraphic As unoidl.com.sun.star.graphic.GraphicObject = Nothing
Public loDocXGraphic As unoidl.com.sun.star.graphic.XGraphic = Nothing
Public oShapes As unoidl.com.sun.star.drawing.ShapeCollection = Nothing
Public loDocXShapes As unoidl.com.sun.star.drawing.XShapes = Nothing
Public loDocXShape As unoidl.com.sun.star.drawing.XShape = Nothing
Public loShapeCollection As unoidl.com.sun.star.drawing.ShapeCollection = Nothing
Public loLine As unoidl.com.sun.star.drawing.ShapeCollection = Nothing
Private strFilePath As String = ""

Private Sub btnDilemma01_Click(sender As Object, e As EventArgs) Handles btnDilemma01.Click
    Try
        ClearAllVariablesToStartOver()
        'THIS SUB OPENS A WRITER DOCUMENT USING METHODOLOGIES FOUND IN THE LIBREOFFICE 'WRITERDEMO' WRITTEN IN VB.NET
        getExistingWriterFile(strFilePath)
    Catch ex As System.Exception

    End Try
End Sub

Private Sub btnDilemma02_Click(sender As Object, e As EventArgs) Handles btnDilemma02.Click
    Try
        ClearAllVariablesToStartOver()
        'THIS SUB OPENS THE SAME FILE IN A ~DIFFERENT WAY~ THAN IN THE WRITER DEMO
        'IT THEN PERFORMS A ~SUCCESSFUL~ SEARCH AND REPLACE
        'See Additional Comments Have Ahead of this Sub
        Search_Replace_All(strFilePath, "FindMe", "ReplaceWithMe")
    Catch ex As System.Exception

    End Try
End Sub

Private Sub btnDilemma03_Click(sender As Object, e As EventArgs) Handles btnDilemma03.Click
    Try
        ClearAllVariablesToStartOver()
        'IF THE SEARCH AND REPLACE SUB IS RE-WRITTEN TO USE THE WRITER DOCUMENT VARIABLES INSTANTIATED AS IN THE 'WRITER DEMO'
        'AND THEN PASSED TO A ~MODIFIED/GENERALIZED~ (Overloaded) VERSION OF THE SEARCH AND REPLACE SUB, THE CODE FAILS.
        'EVEN THOUGH THE 'DESKTOP' VARIABLE SEEMS TO BE POINTING TO THE SAME DOCUMENT???
        getExistingWriterFile(strFilePath)
        Search_Replace_All(loDocXTextDocument, "FindMe", "ReplaceWithMe")
    Catch ex As System.Exception

    End Try
End Sub

Private Sub btnDilemma04_Click(sender As Object, e As EventArgs) Handles btnDilemma04.Click
    Try
        ClearAllVariablesToStartOver()
        'IF ANOTHER DOWNLOADED SEARCH FUNCTION IS USED, IT SEEMS TO WANT TO WORK
        'THIS ONE TRIES TO USE 'EXECUTEDISPATCH' BUT FAILS BECAUSE THE VARIABLE
        'XDispatchProvider IS NOT PROPERLY INSTANTIATED.  I'VE TRIED MULTIPLE METHODS
        'TO CAPTURE/INSTANTIATE IT BUT NONE SEEM TO WORK, HELP!
        getExistingWriterFile(strFilePath)
        SearchDocumentForText("FindMe")
    Catch ex As System.Exception
        MsgBox("Why Does this Fail?")
    End Try
End Sub

Private Sub tbxPathToLODocument_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles tbxPathToLODocument.MouseDoubleClick
    ofdGetLODocumentPath.ShowDialog()
    strFilePath = ofdGetLODocumentPath.FileName
    tbxPathToLODocument.Text = strFilePath
End Sub

'THE FOLLOWING WORKS TO OPEN AN LO WRITER DOCUMENT USING THE APPROACH SHOWN IN THE 'WRITERDEMO' WRITTEN FOR VBNET FOUND IN THE (SINGLE) VBNET EXAMPLE AMONG THE LISTING OF EXAMPLES ON THE LO API WEBSITE
'SOME OBJECTS ARE INSTANTIATED TO NOTHING?  SPECIFICALLY THE loXDispatchProvider to not err but is instantiated to 'Nothing'
'*****THIS PREVENTS ME FROM USING THE 'EXECUTEDISPATCH' FUNCTION IN THE FUNCTION - 'SearchDocumentForText'
'WHICH IS THE LAST FUNCTION IN THIS FILE.

Public Function getExistingWriterFile(ByRef strPathToExistingDocFile As String) As String

    Try
        If strPathToExistingDocFile = "" Then
            MsgBox("You forgot to select the LO Document. Exiting.")
            Return "NG"
        End If
        'THE FOLLOWING HAVE PROVEN TO LOAD ~AND WORK~ SUCCESSFULLY IT GETTING AND USING AN EXISTING WRITER DOCUMENT
        Dim strFunctionResponse As String = "OK"
        loDocXComponentContext = Bootstrap.bootstrap()
        loXMultiServiceFactory = DirectCast(loDocXComponentContext.getServiceManager(), XMultiServiceFactory)
        loXMultiComponentFactory = DirectCast(loDocXComponentContext.getServiceManager(), XMultiComponentFactory)
        loXDocDesktop = loXMultiServiceFactory.createInstance("com.sun.star.frame.Desktop")
        loDocXComponentLoader = DirectCast(loXDocDesktop, unoidl.com.sun.star.frame.XComponentLoader)
        loDocArProps = {} 'This Global Variable is Declared Thusly:  Public  loDocArProps() As unoidl.com.sun.star.beans.PropertyValue = Nothing
        loDocXComponent = loDocXComponentLoader.loadComponentFromURL(GetAbsoluteURI(strPathToExistingDocFile), "_blank", 0, loDocArProps)

        loDocXTextDocument = DirectCast(loDocXComponent, unoidl.com.sun.star.text.XTextDocument)
        loDocXText = loDocXTextDocument.getText
        loDocXTextRange = loDocXTextDocument.getText
        loDocXGraphicProvider = CType(loXMultiComponentFactory.createInstanceWithContext("com.sun.star.graphic.GraphicProvider", loDocXComponentContext), XGraphicProvider)
        loDocXTextCursor = loDocXText.createTextCursor()

        loXDispatchHelper = CType(loXMultiComponentFactory.createInstanceWithContext("com.sun.star.frame.DispatchHelper", loDocXComponentContext), unoidl.com.sun.star.frame.XDispatchHelper)
        loXDispatchProvider = CType(loXMultiComponentFactory.createInstanceWithContext("unoidl.com.sun.star.frame.XDispatchProvider", loDocXComponentContext), unoidl.com.sun.star.frame.XDispatchProvider)
        ''Doesn't work:  loDocXTextContent = DirectCast(loXDocDesktop, unoidl.com.sun.star.text.XTextContent)
        'loXDispatchProvider = DirectCast(loXMultiComponentFactory.createInstanceWithContext("unoidl.com.sun.star.frame.XDispatchProvider", loDocXComponentContext), XDispatchProvider)
        'loXDispatchProvider = DirectCast(loDocXComponentContext.getServiceManager(), unoidl.com.sun.star.frame.XDispatchProvider)
        'loXDispatchProvider = loXMultiComponentFactory.createInstance("com.sun.star.frame.XDispatchProvider")
        'loXDispatchProvider = loXMultiComponentFactory.createInstance("com.sun.star.frame.XDispatchProvider")

        Return strFunctionResponse
    Catch ex As System.Exception
        Return "NG"
    Finally
    End Try
End Function

'THE FOLLOWING ALSO WORKS!  BUT THE METHODS 'CREATESEARCHDESCRIPTOR' 'SETSEARCHSTRING' 'SETREPLACESTRING' 'REPLACEALL' ARE ALL ~NOT~ EXPOSED THROUGH
'VISUAL STUDIO 'DOT' EXTENSION SEARCHES.  THEY ARE DOT EXTENSIONS TO AN OBJECT VARIABLE SO NO ERROR IS DECLARED.
'BUT OBVIOUSLY THEY...(AND OTHERS?) ASSOCIATED WITH AN LO/OO OBJECT MUST BE AVAILABLE BECAUSE THIS WORKS.
'THIS SUB WAS DOWNLOADED FROM SOMEWHERE I'VE FORGOTTEN (SORRY)
'IT ~SEEMS~ TO BE WRITTEN TO THE OO API/SDK...NOT THE LO API, BUT RUNS ON MY COMPUTER WHERE OO IS NOT INSTALLED??
'THIS SUB LOADS A SEPERATE INSTANCE OF LO/OO AND OPENS THE SAME DOCUMENT

Public Sub Search_Replace_All(ByRef strDocumentPath As String, ByRef strToSearchFor As String, ByRef strToReplaceWith As String)
    Dim oSM                   'Root object for accessing OpenOffice from VB
    Dim oDesk, oDoc As Object 'First objects from the API
    Dim arg() = {}            'Ignore it for the moment 

    'Instantiate OOo : this line is mandatory with VB for OOo API
    oSM = CreateObject("com.sun.star.ServiceManager")

    'Create the first and most important service
    oDesk = oSM.createInstance("com.sun.star.frame.Desktop")

    'Create a new doc
    oDoc = oDesk.loadComponentFromURL(GetAbsoluteURI(strDocumentPath), "_blank", 0, arg)

    Dim objText As Object, objCursor As Object
    objText = oDoc.GetText
    objCursor = objText.createTextCursor

    ' replace all
    Dim oSrch As Object
    oSrch = oDoc.createReplaceDescriptor
    oSrch.setSearchString(strToSearchFor)
    oSrch.setReplaceString(strToReplaceWith)
    oDoc.replaceAll(oSrch)

End Sub

'THE FOLLOWING DOES NOT WORK AND I DO NOT UNDERSTAND WHY.  COMPARE THIS SUB TO THE SUB JUST BEFORE IT.
'THE FOLLOWING ONE FAILS AT THE LINE 'objCursor = objText.createTextCursor'

Public Sub Search_Replace_All(ByRef theDocument As unoidl.com.sun.star.text.XTextDocument,
                                     ByRef strTextToFind As String,
                                     ByRef strTextToReplaceWith As String)
    'DOWNLOADED AS A VB.NET (WORKABLE?) FUNCTION
    'Dim oSM                   'Root object for accessing OpenOffice from VB
    'Dim oDesk, oDoc As Object 'First objects from the API
    'Dim arg() = {}            'Ignore it for the moment 

    ''Instanciate OOo : this line is mandatory with VB for OOo API
    'oSM = CreateObject("com.sun.star.ServiceManager")

    ''Create the first and most important service
    'oDesk = oSM.createInstance("com.sun.star.frame.Desktop")

    ''Create a new doc
    'oDoc = oDesk.loadComponentFromURL(GetAbsoluteURI(strDocumentPath), "_blank", 0, arg)

    Dim objText As Object, objCursor As Object
    objText = theDocument.getText
    objCursor = objText.createTextCursor

    ' replace all
    Dim oSrch As Object
    oSrch = CType(theDocument, Object).createSearchDescriptor
    oSrch = CType(theDocument, Object).createReplaceDescriptor
    oSrch.setSearchString(strTextToFind)
    oSrch.setReplaceString(strTextToReplaceWith)
    CType(theDocument, Object).replaceAll(oSrch)

End Sub
Public Function GetAbsoluteURI(ByRef strFileSpec As String) As String
    Dim newURI As Uri
    Dim ConvertedURI As String = ""
    Try
        newURI = New System.Uri(strFileSpec)
        ConvertedURI = newURI.AbsoluteUri
        Return ConvertedURI
    Catch ex As system.Exception
        Return MsgBox("Did you forget to select a valid LO Writer Document?")
    End Try
End Function
Private Sub ClearAllVariablesToStartOver()
    loDocXComponentContext = Nothing
    loXMultiServiceFactory = Nothing
    loXMultiComponentFactory = Nothing
    loDocXComponentLoader = Nothing
    loXDocDesktop = Nothing
    loDocArProps = {}
    loDocXComponent = Nothing
    loDocXTextDocument = Nothing
    loDocXText = Nothing
    loDocXTextRange = Nothing
    loDocXTextCursor = Nothing
    loDocXGraphicProvider = Nothing

    loDocXServiceManager = Nothing

    loDocXSimpleText = Nothing

    loXDispatchHelper = Nothing
    loXDispatchProvider = Nothing
    loDocFrame = Nothing
    loDocXFrame = Nothing
    loDocXViewCursor = Nothing
    loDocXFrameCursor = Nothing

    loDocXTextTable = Nothing
    loDocXTextFrame = Nothing
    loDocXTextContent = Nothing
    loDocXTableRows = Nothing

    loDocXDrawPage = Nothing
    loDocGraphic = Nothing
    loDocXGraphic = Nothing
    oShapes = Nothing
    loDocXShapes = Nothing
    loDocXShape = Nothing
    loShapeCollection = Nothing
    loLine = Nothing
End Sub

'THE FOLLOWING IS ANOTHER FUNCTION I'VE DOWNLOADED BUT CANNOT MAKE WORK BECAUSE I'M UNABLE TO PROPERLY INSTANTIATE THE
''loXDispatchProvider' VARIABLE.  IN THE 'getExistingWriterFile' FUNCTION, 'loXDispatchProvider' IS INSTANTIATED TO 'NOTHING'

Public Sub SearchDocumentForText(ByRef strSearchText As String)

    Dim localProps(21) As unoidl.com.sun.star.beans.PropertyValue
    Try
        'ARE ALL THESE PROPERTIES NECESSARY EACH TIME A SEARCH IS PERFORMED?
        localProps(0) = CreateProp("SearchItem.StyleFamily", New uno.Any(2))
        localProps(1) = CreateProp("SearchItem.CellType", New uno.Any(1))
        localProps(2) = CreateProp("SearchItem.RowDirection", New uno.Any(True))
        localProps(3) = CreateProp("SearchItem.AllTables", New uno.Any(False))
        localProps(4) = CreateProp("SearchItem.SearchFiltered", New uno.Any(False))
        localProps(5) = CreateProp("SearchItem.Backward", New uno.Any(False))
        localProps(6) = CreateProp("SearchItem.Pattern", New uno.Any(False))
        localProps(7) = CreateProp("SearchItem.Content", New uno.Any(False))
        localProps(8) = CreateProp("SearchItem.AsianOptions", New uno.Any(False))
        localProps(9) = CreateProp("SearchItem.AlgorithmType", New uno.Any(0))
        localProps(10) = CreateProp("SearchItem.SearchFlags", New uno.Any(0))
        localProps(11) = CreateProp("SearchItem.SearchItem.SearchString", New uno.Any(strSearchText))
        localProps(12) = CreateProp("SearchItem.ReplaceString", New uno.Any(""))
        localProps(13) = CreateProp("SearchItem.Locale", New uno.Any(255))
        localProps(14) = CreateProp("SearchItem.ChangedChars", New uno.Any(2))
        localProps(15) = CreateProp("SearchItem.DeletedChars", New uno.Any(2))
        localProps(16) = CreateProp("SearchItem.InsertedChars", New uno.Any(2))
        localProps(17) = CreateProp("SearchItem.TransliterateFlags", New uno.Any(256))
        localProps(18) = CreateProp("SearchItem.Command", New uno.Any(0))
        localProps(19) = CreateProp("SearchItem.SearchFormatted", New uno.Any(False))
        localProps(20) = CreateProp("SearchItem.AlgorithmType2", New uno.Any(1))
        localProps(21) = CreateProp("SearchItem.Quiet", New uno.Any(True))
        'THE FOLLOWING DOES DO ANYTHING BECAUSE THE VARIABLE 'loXDispatchProvider' 
        'ISN'T PROPERLY FILLED IN THE CALLING FUNCTION.  AS WRITTEN, IT IS FILLED WITH 'Nothing'
        'IT ISN'T OBVIOUS HOW TO FILL IT PROPERLY, PLEASE HELP!
        'AND... IF IT WERE TO BE FILLED PROPERLY, THE LINE OF CODE SEEMS TO WANT TO
        '1) PROVIDE A CURSOR TO THE FOUND LOCATION (THE TYPE GENERATED IS AN 'ANY' WHICH CANNOT BE CAST TO A CURSOR....
        'or
        '2) MOVE 'a' CURSOR THE THE FOUND LOCATION
        'IS EITHER TRUE?
        loXDispatchHelper.executeDispatch(loXDispatchProvider, "ExecuteSearch", "", 0, loDocArProps)
    Catch ex As System.Exception

    End Try

End Sub
Public Function CreateProp(ByRef name As String, ByRef value As uno.Any) As unoidl.com.sun.star.beans.PropertyValue
    Dim prop As New unoidl.com.sun.star.beans.PropertyValue
    Try
        prop.Name = name
        prop.Value = value 'CType(value, Object)
        Return prop
    Catch ex As System.Exception
        Return Nothing
    End Try
End Function

End Class