About VBA-UserForms

More ideas…
While spinning the ideas I got while recoding my tuning I realized that I could extract data from .xml files stored into my LO project’s package and store the extracted data to string variables on the fly. This gives me ability to manipulate the data the way I want and then save the manipulated data either back to the project package or to some other target like a single file or a package archive.

The first step on this was to create a macro to read data:
There are no easy to find examples available how this could be done, and it took a while until I came across Andrew Pitonyak’s documentation which handled among many other things TextInputStream object. Andrew’s explanation of how to extract the data into a string wasn’t the easiest to understand, in the case you want to read the data into string at once instead of doing it line by line in a do-while-loop.
But finally I got it:

Sub BasicMain
    ExtractSpecificFileFromProjectAchiveAsText "Dialogs/Standard/", "MultiPageTemp.xml"
End Sub

Sub ExtractSpecificFileFromProjectAchiveAsText(sFolder As String, sFile As String)

    Dim oZipHandler As Object
    Dim args(0)
    Dim args1()
    Dim entries() As String
    Dim xmlContent As Variant
    Dim fileToRead As String
      	
    fileToRead = sFolder & sFile
    oZipHandler = CreateUnoService("com.sun.star.packages.zip.ZipFileAccess")
    args(0) = thisComponent.URL
    oZipHandler.initialize(args)
    
    entries = oZipHandler.getElementNames()
    Dim textStream As Object
    textStream = CreateUnoService("com.sun.star.io.TextInputStream")
    Dim stream As Object, line As String
    
    For i = LBound(entries) To UBound(entries)
        If entries(i) = fileToRead Then
            stream = oZipHandler.getByName(entries(i))
            textStream.setEncoding("UTF-8")
            textStream.setInputStream(stream)
            xmlContent = textStream.readString(args1, true)
            textStream.closeInput()
            textStream = Nothing
            stream = Nothing
            Erase entries
            args = ""
            Erase args1
            oZipHandler = Nothing
            Exit For
        End If
    Next 

    MsgBox "Extracted content: " & chr(10) & xmlContent

End Sub

This offers an opportunity to extremely expand what can be done just using pure Basic.

Hello!
You can work with the xml file from the document archive right away, as it is done here.
In this case, you will be pleased to know that the DocumentBuilder service provides the same methods as the Microsoft DOMDocument object.
An alternative is to use Python with its countless built-in capabilities.

@sokol92

Thx for your tip.
But I use my own built string builder/xml handler. By doing this I’m able to step aside from UNO controlling almost completely.

EDIT:
Here’s an example that clearly explains that recycling data through DomBuilder - Dom is unnecessary and would only slow down the process:

Option VBASupport 1

Private originalStr As String
Private pageTmpStr As String
Private buildStr As String

Sub StarToWork

	Dim tmpStr As String, spos  As Long,  epos  As Long
	originalStr = GetTempTabPage
	MsgBox "The original:" & chr(10) & originalStr
	spos = InStr(originalStr,"<dlg:page")
	MsgBox spos
	epos = InStr(originalStr, chr(34) & "Page1" & chr(34) & "/>") + Len(chr(34) & "Page1" & chr(34) & "/>")
	MsgBox epos
	pageTmpStr = Mid(originalStr, spos, epos - spos)
	MsgBox pageTmpStr
	buildStr =  Replace(originalStr, chr(34) & "Page1" & chr(34) & "/>", chr(34) & "Page1" & chr(34) & ">" & chr(10) & _
	"You can put  here whatever content you want." & chr(10) & "I'll use manipulated data read from a Dialog (xml) inside the project package" & chr(10) & _
	"which mimes content of a Tab page. Tip everything between tag <BulletinBoard></BulletinBoard> including the start and end tag" _ 
	& chr(10) & "</dlg:page>" & chr(10) & Replace(pageTmpStr, "Page1", "Page2")) 'and so on...
	MsgBox buildStr
	MsgBox "You may guess what I do with BuildString when I'm happy with the result...."
End Sub


Function GetTempTabPage() As String

	GetTempTabPage = _
"<?xml version=""1.0"" encoding=""UTF-8""?>" & chr(10) & _
"<!DOCTYPE dlg:window PUBLIC ""-//OpenOffice.org//DTD OfficeDocument 1.0//EN"" ""dialog.dtd"">" & chr(10) & _
"<dlg:window xmlns:dlg=""http://openoffice.org/2000/dialog"" xmlns:script=""http://openoffice.org/2000/script"" dlg:style-id=""1"" dlg:id=""MultiPage_Template"" dlg:left=""0"" dlg:top=""0"" dlg:width=""331"" dlg:height=""253"" dlg:closeable=""true"" dlg:moveable=""true"">" & chr(10) & _
 "<dlg:styles>" & chr(10) & _
  "<dlg:style dlg:style-id=""0"" dlg:background-color=""0xece9d8""/>" & chr(10) & _
  "<dlg:style dlg:style-id=""1"" dlg:background-color=""0xdee6ef""/>" & chr(10) & _
 "</dlg:styles>" & chr(10) & _
 "<dlg:bulletinboard>" & chr(10) & _
  "<dlg:multipage dlg:style-id=""0"" dlg:id=""MultiPage1"" dlg:tab-index=""0"" dlg:left=""27"" dlg:top=""23"" dlg:width=""272"" dlg:height=""195"" dlg:value=""4"">" & chr(10) & _
   "<dlg:bulletinboard>" & chr(10) & _
    "<dlg:page dlg:style-id=""0"" dlg:id=""Page1"" dlg:tab-index=""0"" dlg:visible=""false"" dlg:left=""1"" dlg:top=""21"" dlg:width=""249"" dlg:height=""173"" dlg:title=""Page1""/>" & chr(10) & _
   "</dlg:bulletinboard>" & chr(10) & _
  "</dlg:multipage>" & chr(10) & _
 "</dlg:bulletinboard>" & chr(10) & _
"</dlg:window>" & chr(10)
End Function

In addition, my response to all those who so enthusiastically advertise the excellence of Python:
As for me, I have isolated Python already for a long ago by zipping the executable, renaming the zip and deleting the original. I don’t give a shit about anything that separates you from knowing the underlying fundamentals. In my opinion sooner or later it leads to a situation where everyone has turned into a herd of cows without any innovativeness. It’s like being in a church where the priest tells you how to live your life while they’re collecting the money…

Your enthusiasm for finding previously untrodden paths is commendable. Having alternative solutions gives us more options when choosing. :slight_smile:

Until the day you only have one option to choose from :upside_down_face: