ScriptForge - (SFDocuments) Introduce form class

New SF_Form class in SFDocuments library
Support for Writer, Calc and Base forms

Skeleton of Form class module
Forms() methods in Calc, Base and Document modules
to create a new instance

New error messages in po file

Change-Id: Id78a4604caf61901d87750026be45cef8f74f110
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107848
Tested-by: Jean-Pierre Ledure <jp@ledure.be>
Tested-by: Jenkins
Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
This commit is contained in:
Jean-Pierre Ledure
2020-12-17 08:56:47 +01:00
parent 11382ccf2f
commit e6915d4be4
13 changed files with 1325 additions and 46 deletions
+1
View File
@@ -23,6 +23,7 @@ $(eval $(call gb_Package_add_files,wizards_basicsrvsfdocuments,$(LIBO_SHARE_FOLD
SF_Base.xba \
SF_Calc.xba \
SF_Document.xba \
SF_Form.xba \
SF_Register.xba \
__License.xba \
dialog.xlb \
@@ -104,6 +104,12 @@ Const CALCADDRESSERROR = &quot;CALCADDRESSERROR&quot;
Const DUPLICATESHEETERROR = &quot;DUPLICATESHEETERROR&quot;
Const OFFSETADDRESSERROR = &quot;OFFSETADDRESSERROR&quot;
&apos; SF_Form
Const FORMDEADERROR = &quot;FORMDEADERROR&quot;
Const CALCFORMNOTFOUNDERROR = &quot;CALCFORMNOTFOUNDERROR&quot;
Const WRITERFORMNOTFOUNDERROR = &quot;WRITERFORMNOTFOUNDERROR&quot;
Const BASEFORMNOTFOUNDERROR = &quot;BASEFORMNOTFOUNDERROR&quot;
&apos; SF_Dialog
Const DIALOGNOTFOUNDERROR = &quot;DIALOGNOTFOUNDERROR&quot;
Const DIALOGDEADERROR = &quot;DIALOGDEADERROR&quot;
@@ -824,6 +830,18 @@ Try:
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;OFFSETADDRESS&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4) _
, pvArgs(5), pvArgs(6), pvArgs(7), pvArgs(8), pvArgs(9), pvArgs(10), pvArgs(11))
Case FORMDEADERROR &apos; SF_Form._IsStillAlive(FormName, DocumentName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FORMDEAD&quot;, pvArgs(0), pvArgs(1))
Case CALCFORMNOTFOUNDERROR &apos; SF_Calc.Forms(Index, SheetName, Document)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CALCFORMNOTFOUND&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case WRITERFORMNOTFOUNDERROR &apos; SF_Document.Forms(Index, Document)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;WRITERFORMNOTFOUND&quot;, pvArgs(0), pvArgs(1))
Case BASEFORMNOTFOUNDERROR &apos; SF_Base.Forms(Index, FormDocument, BaseDocument)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;BASEFORMNOTFOUND&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case DIALOGNOTFOUNDERROR &apos; SF_Dialog._NewDialog(Service, DialogName, WindowName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DIALOGNOTFOUND&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4) _
+38
View File
@@ -725,6 +725,44 @@ Try:
&amp; &quot;%11: An identifier\n&quot; _
&amp; &quot;%12: A file name&quot; _
)
&apos; SF_Form._IsStillAlive
.AddText( Context := &quot;FORMDEAD&quot; _
, MsgId := &quot;The requested action could not be executed because the form is not open or the document was closed inadvertently.\n\n&quot; _
&amp; &quot;The concerned form is &apos;%1&apos; in document &apos;%2&apos;.&quot; _
, Comment := &quot;SF_Dialog._IsStillAlive error message\n&quot; _
&amp; &quot;%1: An identifier&quot; _
&amp; &quot;%2: A file name&quot; _
)
&apos; SF_Calc.Forms
.AddText( Context := &quot;CALCFORMNOTFOUND&quot; _
, MsgId := &quot;The requested form could not be found in the Calc sheet. The given index is off-limits.\n\n&quot; _
&amp; &quot;The concerned Calc document is &apos;%3&apos;.\n\n&quot; _
&amp; &quot;The name of the sheet = &apos;%2&apos;\n&quot; _
&amp; &quot;The index = %1&quot; _
, Comment := &quot;SF_Form determination\n&quot; _
&amp; &quot;%1: A number\n&quot; _
&amp; &quot;%2: A sheet name\n&quot; _
&amp; &quot;%3: A file name&quot; _
)
&apos; SF_Document.Forms
.AddText( Context := &quot;WRITERFORMNOTFOUND&quot; _
, MsgId := &quot;The requested form could not be found in the Writer document. The given index is off-limits.\n\n&quot; _
&amp; &quot;The concerned Writer document is &apos;%2&apos;.\n\n&quot; _
&amp; &quot;The index = %1&quot; _
, Comment := &quot;SF_Form determination\n&quot; _
&amp; &quot;%1: A number\n&quot; _
&amp; &quot;%2: A file name&quot; _
)
&apos; SF_Base.Forms
.AddText( Context := &quot;BASEFORMNOTFOUND&quot; _
, MsgId := &quot;The requested form could not be found in the form document &apos;%2&apos;. The given index is off-limits.\n\n&quot; _
&amp; &quot;The concerned Base document is &apos;%3&apos;.\n\n&quot; _
&amp; &quot;The index = %1&quot; _
, Comment := &quot;SF_Form determination\n&quot; _
&amp; &quot;%1: A number\n&quot; _
&amp; &quot;%2: A string\n&quot; _
&amp; &quot;%3: A file name&quot; _
)
&apos; SF_Dialog._NewDialog
.AddText( Context := &quot;DIALOGNOTFOUND&quot; _
, MsgId := &quot;The requested dialog could not be located in the given container or library.\n&quot; _
+2
View File
@@ -226,6 +226,8 @@ Dim sHeader As String &apos; The specific header to insert
Try:
With _SF_
If Not IsNull(.Interface) Then .Interface.Dispose()
._LoadLocalizedInterface(psMode := &quot;ADDTEXT&quot;) &apos; Force reload of labels from the code
.Interface.ExportToPOTFile(FileName, Header := sHeader)
End With
+61 -4
View File
@@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n"
"POT-Creation-Date: 2020-12-06 12:16:30\n"
"POT-Creation-Date: 2020-12-15 15:57:29\n"
"PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
@@ -465,7 +465,7 @@ msgstr ""
#. SF_Session.ExecuteBasicScript error message
#. %1: An identifier
#. %2: A string
#. %3: A number
#. %3: A (long) string
#, kde-format
msgctxt "SCRIPTEXEC"
msgid ""
@@ -726,6 +726,62 @@ msgid ""
"« %11 » = %12"
msgstr ""
#. SF_Dialog._IsStillAlive error message
#. %1: An identifier%2: A file name
#, kde-format
msgctxt "FORMDEAD"
msgid ""
"The requested action could not be executed because the form is not "
"open or the document was closed inadvertently.\n"
"\n"
"The concerned form is '%1' in document '%2'."
msgstr ""
#. SF_Form determination
#. %1: A number
#. %2: A sheet name
#. %3: A file name
#, kde-format
msgctxt "CALCFORMNOTFOUND"
msgid ""
"The requested form could not be found in the Calc sheet. The given "
"index is off-limits.\n"
"\n"
"The concerned Calc document is '%3'.\n"
"\n"
"The name of the sheet = '%2'\n"
"The index = %1"
msgstr ""
#. SF_Form determination
#. %1: A number
#. %2: A file name
#, kde-format
msgctxt "WRITERFORMNOTFOUND"
msgid ""
"The requested form could not be found in the Writer document. The "
"given index is off-limits.\n"
"\n"
"The concerned Writer document is '%2'.\n"
"\n"
"The index = %1"
msgstr ""
#. SF_Form determination
#. %1: A number
#. %2: A string
#. %3: A file name
#, kde-format
msgctxt "BASEFORMNOTFOUND"
msgid ""
"The requested form could not be found in the form document '%2'. The "
"given index is off-limits.\n"
"\n"
"The concerned Base document is '%3'.\n"
"\n"
"The index = %1"
msgstr ""
#. SF_Dialog creation
#. %1: An identifier
#. %2: A string
@@ -766,7 +822,8 @@ msgstr ""
msgctxt "CONTROLTYPE"
msgid ""
"The control '%1' in dialog '%2' is of type '%3'.\n"
"The property or method '%4' is not applicable on that type of dialog controls."
"The property or method '%4' is not applicable on that type of dialog "
"controls."
msgstr ""
#. SF_DialogControl add line in textbox
@@ -798,4 +855,4 @@ msgid ""
"Check its syntax, table and/or field names, ...\n"
"\n"
"SQL Statement : « %1 »"
msgstr ""
msgstr ""
+61 -4
View File
@@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n"
"POT-Creation-Date: 2020-12-06 12:16:30\n"
"POT-Creation-Date: 2020-12-15 15:57:29\n"
"PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
@@ -465,7 +465,7 @@ msgstr ""
#. SF_Session.ExecuteBasicScript error message
#. %1: An identifier
#. %2: A string
#. %3: A number
#. %3: A (long) string
#, kde-format
msgctxt "SCRIPTEXEC"
msgid ""
@@ -726,6 +726,62 @@ msgid ""
"« %11 » = %12"
msgstr ""
#. SF_Dialog._IsStillAlive error message
#. %1: An identifier%2: A file name
#, kde-format
msgctxt "FORMDEAD"
msgid ""
"The requested action could not be executed because the form is not "
"open or the document was closed inadvertently.\n"
"\n"
"The concerned form is '%1' in document '%2'."
msgstr ""
#. SF_Form determination
#. %1: A number
#. %2: A sheet name
#. %3: A file name
#, kde-format
msgctxt "CALCFORMNOTFOUND"
msgid ""
"The requested form could not be found in the Calc sheet. The given "
"index is off-limits.\n"
"\n"
"The concerned Calc document is '%3'.\n"
"\n"
"The name of the sheet = '%2'\n"
"The index = %1"
msgstr ""
#. SF_Form determination
#. %1: A number
#. %2: A file name
#, kde-format
msgctxt "WRITERFORMNOTFOUND"
msgid ""
"The requested form could not be found in the Writer document. The "
"given index is off-limits.\n"
"\n"
"The concerned Writer document is '%2'.\n"
"\n"
"The index = %1"
msgstr ""
#. SF_Form determination
#. %1: A number
#. %2: A string
#. %3: A file name
#, kde-format
msgctxt "BASEFORMNOTFOUND"
msgid ""
"The requested form could not be found in the form document '%2'. The "
"given index is off-limits.\n"
"\n"
"The concerned Base document is '%3'.\n"
"\n"
"The index = %1"
msgstr ""
#. SF_Dialog creation
#. %1: An identifier
#. %2: A string
@@ -766,7 +822,8 @@ msgstr ""
msgctxt "CONTROLTYPE"
msgid ""
"The control '%1' in dialog '%2' is of type '%3'.\n"
"The property or method '%4' is not applicable on that type of dialog controls."
"The property or method '%4' is not applicable on that type of dialog "
"controls."
msgstr ""
#. SF_DialogControl add line in textbox
@@ -798,4 +855,4 @@ msgid ""
"Check its syntax, table and/or field names, ...\n"
"\n"
"SQL Statement : « %1 »"
msgstr ""
msgstr ""
+1 -1
View File
@@ -133,7 +133,7 @@ End Function &apos; SFDatabases.SF_Register._NewDatabase
REM -----------------------------------------------------------------------------
Public Function _NewDatabaseFromSource(Optional ByVal pvArgs As Variant) As Object
&apos;ByRef poDataSource As Object _
&apos; ByRef poDataSource As Object _
&apos; , ByVal psUser As String _
&apos; , ByVal psPassword As String _
&apos; ) As Object
+257 -8
View File
@@ -26,7 +26,9 @@ Option Explicit
&apos;&apos;&apos; the parent methods and properties.
&apos;&apos;&apos; They should also duplicate some generic private members as a subset of their own set of members
&apos;&apos;&apos;
&apos;&apos;&apos; The SF_Base module is provided only to block parent properties that are NOT applicable to Base documents
&apos;&apos;&apos; The SF_Base module is provided mainly to block parent properties that are NOT applicable to Base documents
&apos;&apos;&apos; In addition, it provides methods to identify form documents and access their internal forms
&apos;&apos;&apos; (read more elsewhere (the &quot;SFDocuments.Form&quot; service) about this subject)
&apos;&apos;&apos;
&apos;&apos;&apos; The current module is closely related to the &quot;UI&quot; service of the ScriptForge library
&apos;&apos;&apos;
@@ -46,6 +48,8 @@ Option Explicit
REM ================================================================== EXCEPTIONS
Private Const DBCONNECTERROR = &quot;DBCONNECTERROR&quot;
Private Const FORMDEADERROR = &quot;FORMDEADERROR&quot;
Private Const BASEFORMNOTFOUNDERROR = &quot;BASEFORMNOTFOUNDERROR&quot;
REM ============================================================= PRIVATE MEMBERS
@@ -55,14 +59,18 @@ Private [_Super] As Object &apos; Document superclass, which the current ins
Private ObjectType As String &apos; Must be BASE
Private ServiceName As String
&apos; Window component
&apos; UNO references
Private _Component As Object &apos; com.sun.star.comp.dba.ODatabaseDocument
Private _DataSource As Object &apos; com.sun.star.comp.dba.ODatabaseSource
Private _Database As Object &apos; SFDatabases.Database service instance
Private _FormDocuments As Object
REM ============================================================ MODULE CONSTANTS
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
Const ISBASEFORM = 2 &apos; Form is stored in a Base document
Const cstToken = &quot;//&quot; &apos; Form names accept special characters but not slashes
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
@@ -74,6 +82,7 @@ Private Sub Class_Initialize()
Set _Component = Nothing
Set _DataSource = Nothing
Set _Database = Nothing
Set _FormDocuments = Nothing
End Sub &apos; SFDocuments.SF_Base Constructor
REM -----------------------------------------------------------------------------
@@ -107,7 +116,7 @@ Const cstSubArgs = &quot;[SaveAsk=True]&quot;
Check:
If IsMissing(SaveAsk) Or IsEmpty(SaveAsk) Then SaveAsk = True
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(SaveAsk, &quot;SaveAsk&quot;, V_BOOLEAN) Then GoTo Finally
End If
@@ -123,6 +132,131 @@ Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Base.CloseDocument
REM -----------------------------------------------------------------------------
Public Function FormDocuments() As Variant
&apos;&apos;&apos; Return the list of the FormDocuments contained in the Base document
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-base array of strings
&apos;&apos;&apos; Each entry is the full path name of a form document. The path separator is the slash (&quot;/&quot;)
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myForm As Object, myList As Variant
&apos;&apos;&apos; myList = oDoc.FormDocuments()
Dim vFormNames As Variant &apos; Array of all form names present in the document
Const cstThisSub = &quot;SFDocuments.Base.FormDocuments&quot;
Const cstSubArgs = &quot;&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
End If
Try:
&apos; Build list of available FormDocuments recursively with _CollectFormDocuments
If IsNull(_FormDocuments) Then Set _FormDocuments = _Component.getFormDocuments()
vFormNames = Split(_CollectFormDocuments(_FormDocuments), cstToken)
Finally:
FormDocuments = vFormNames
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Base.FormDocuments
REM -----------------------------------------------------------------------------
Public Function Forms(Optional ByVal FormDocument As Variant _
, Optional ByVal Form As Variant _
) As Variant
&apos;&apos;&apos; Return either
&apos;&apos;&apos; - the list of the Forms contained in the form document
&apos;&apos;&apos; - a SFDocuments.Form object based on its name or its index
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FormDocument: a valid document form name as a case-sensitive string
&apos;&apos;&apos; Form: a form stored in the Base document given by its name or its index
&apos;&apos;&apos; When absent, the list of available forms is returned
&apos;&apos;&apos; To get the first (unique ?) form stored in the form document, set Form = 0
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-base array of strings if Form is absent
&apos;&apos;&apos; An instance of the SF_Form class if Form exists
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; FORMDEADERROR The form is not open
&apos;&apos;&apos; BASEFORMNOTFOUNDERROR FormDocument OK but Form not found
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myForm As Object, myList As Variant
&apos;&apos;&apos; myList = oDoc.Forms(&quot;Folder1/myFormDocument&quot;)
&apos;&apos;&apos; Set myForm = oDoc.Forms(&quot;Folder1/myFormDocument&quot;, 0)
Dim oForm As Object &apos; The new Form class instance
Dim oMainForm As Object &apos; com.sun.star.comp.sdb.Content
Dim oXForm As Object &apos; com.sun.star.form.XForm
Dim vFormDocuments As Variant &apos; Array of form documents
Dim vFormNames As Variant &apos; Array of form names
Dim oForms As Object &apos; Forms collection
Const cstDrawPage = 0 &apos; Only 1 drawpage in a Base document
Const cstThisSub = &quot;SFDocuments.Base.Forms&quot;
Const cstSubArgs = &quot;FormDocument, [Form=&quot;&quot;&quot;&quot;]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(Form) Or IsEmpty(Form) Then Form = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
&apos; Build list of available FormDocuments recursively with _CollectFormDocuments
If IsNull(_FormDocuments) Then Set _FormDocuments = _Component.getFormDocuments()
vFormDocuments = Split(_CollectFormDocuments(_FormDocuments), cstToken)
If Not ScriptForge.SF_Utils._Validate(FormDocument, &quot;FormDocument&quot;, V_STRING, vFormDocuments) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Form, &quot;Form&quot;, Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally
End If
If Not IsLoaded(FormDocument) Then GoTo CatchClosed
Try:
&apos; Start from the form document and go down to forms
Set oMainForm = _FormDocuments.getByHierarchicalName(FormDocument)
Set oForms = oMainForm.Component.DrawPages(cstDrawPage).Forms
vFormNames = oForms.getElementNames()
If Len(Form) = 0 Then &apos; Return the list of valid form names
Forms = vFormNames
Else
If VarType(Form) = V_STRING Then &apos; Find the form by name
If Not ScriptForge.SF_Utils._Validate(Form, &quot;Form&quot;, V_STRING, vFormNames) Then GoTo Finally
Set oXForm = oForms.getByName(Form)
Else &apos; Find the form by index
If Form &lt; 0 Or Form &gt;= oForms.Count Then GoTo CatchNotFound
Set oXForm = oForms.getByIndex(Form)
End If
&apos; Create the new Form class instance
Set oForm = New SF_Form
With oForm
._Name = oXForm.Name
Set .[Me] = oForm
Set .[_Parent] = [Me]
._DrawPage = cstDrawPage
._UsualName = FormDocument &amp; &quot; : &quot; &amp; ._Name
Set ._MainForm = oMainForm
._FormType = ISBASEFORM
Set ._Form = oXForm
End With
Set Forms = oForm
End If
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchClosed:
ScriptForge.SF_Exception.RaiseFatal(FORMDEADERROR, FormDocument, _FileIdent())
CatchNotFound:
ScriptForge.SF_Exception.RaiseFatal(BASEFORMNOTFOUNDERROR, Form, FormDocument, _FileIdent())
End Function &apos; SFDocuments.SF_Base.Forms
REM -----------------------------------------------------------------------------
Public Function GetDatabase(Optional ByVal User As Variant _
, Optional ByVal Password As Variant _
@@ -148,7 +282,7 @@ Check:
If IsMissing(User) Or IsEmpty(User) Then User = &quot;&quot;
If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(User, &quot;User&quot;, V_STRING) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
End If
@@ -209,6 +343,52 @@ Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Base.GetProperty
REM -----------------------------------------------------------------------------
Public Function IsLoaded(Optional ByVal FormDocument As Variant) As Boolean
&apos;&apos;&apos; Return True if the given FormDocument is open for the user
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FormDocument: a valid document form name as a case-sensitive string
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if the form document is currently open, otherise False
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; Form is invalid
&apos;&apos;&apos; Example:
&apos;&apos;&apos; MsgBox oDoc.IsLoaded(&quot;Folder1/myFormDocument&quot;)
Dim bLoaded As Boolean &apos; Return value
Dim vFormNames As Variant &apos; Array of all document form names present in the document
Dim oMainForm As Object &apos; com.sun.star.comp.sdb.Content
Const cstThisSub = &quot;SFDocuments.Base.IsLoaded&quot;
Const cstSubArgs = &quot;FormDocument&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bLoaded = False
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
&apos; Build list of available FormDocuments recursively with _CollectFormDocuments
If IsNull(_FormDocuments) Then Set _FormDocuments = _Component.getFormDocuments()
vFormNames = Split(_CollectFormDocuments(_FormDocuments), cstToken)
If Not ScriptForge.SF_Utils._Validate(FormDocument, &quot;FormDocument&quot;, V_STRING, vFormNames) Then GoTo Finally
End If
Try:
Set oMainForm = _FormDocuments.getByHierarchicalName(FormDocument)
&apos; A document form that has never been opened has no component
&apos; If ever opened and closed afterwards, it keeps the Component but loses its Controller
bLoaded = Not IsNull(oMainForm.Component)
If bLoaded Then bLoaded = Not IsNull(oMainForm.Component.CurrentController)
Finally:
IsLoaded = bLoaded
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Base.IsLoaded
REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
&apos;&apos;&apos; Return the list of public methods of the Model service as an array
@@ -216,6 +396,8 @@ Public Function Methods() As Variant
Methods = Array( _
&quot;Activate&quot; _
, &quot;CloseDocument&quot; _
, &quot;FormDocuments&quot; _
, &quot;Forms&quot; _
, &quot;GetDatabase&quot; _
, &quot;RunCommand&quot; _
, &quot;Save&quot; _
@@ -274,7 +456,7 @@ Finally:
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Documents.SetProperty
End Function &apos; SFDocuments.SF_Base.SetProperty
REM ======================================================= SUPERCLASS PROPERTIES
@@ -417,6 +599,73 @@ End Function &apos; SFDocuments.SF_Base.SaveCopyAs
REM =========================================================== PRIVATE FUNCTIONS
REM -----------------------------------------------------------------------------
Private Function _CollectFormDocuments(ByRef poContainer As Object) As String
&apos;&apos;&apos; Returns a token-separated string of all hierarchical formdocument names
&apos;&apos;&apos; depending on the formdocuments container in argument
&apos;&apos;&apos; The function traverses recursively the whle tree below the container
&apos;&apos;&apos; The initial call starts from the container _Component.getFormDocuments
&apos;&apos;&apos; The list contains closed and open forms
Dim sCollectNames As String &apos; Returno value
Dim oSubItem As Object &apos; com.sun.star.container.XNameAccess (folder) or com.sun.star.ucb.XContent (form)
Dim sFormName As String &apos; Single form name
Dim i As Long
Const cstFormType = &quot;application/vnd.oasis.opendocument.text&quot;
&apos; Identifies forms. Folders have a zero-length content type
On Local Error GoTo Finally
Try:
sCollectNames = &quot;&quot;
With poContainer
For i = 0 To .Count - 1
Set oSubItem = .getByIndex(i)
If oSubItem.ContentType = cstFormType Then &apos; Add the form to the list
sCollectNames = sCollectNames &amp; cstToken &amp; oSubItem.HierarchicalName
Else
sCollectNames = sCollectNames &amp; cstToken &amp; _CollectFormDocuments(oSubItem)
End If
Next i
End With
Finally:
_CollectFormDocuments = Mid(sCollectNames, Len(cstToken) + 1) &apos; Skip the initial token
Exit Function
End Function &apos; SFDocuments.SF_Base._CollectFormDocuments
REM -----------------------------------------------------------------------------
Private Function _FileIdent() As String
&apos;&apos;&apos; Returns a file identification from the information that is currently available
&apos;&apos;&apos; Useful e.g. for display in error messages
_FileIdent = [_Super]._FileIdent()
End Function &apos; SFDocuments.SF_Base._FileIdent
REM -----------------------------------------------------------------------------
Private Function _IsStillAlive(Optional ByVal pbForUpdate As Boolean _
, Optional ByVal pbError As Boolean _
) As Boolean
&apos;&apos;&apos; Returns True if the document has not been closed manually or incidentally since the last use
&apos;&apos;&apos; If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pbForUpdate: if True (default = False), check additionally if document is open for editing
&apos;&apos;&apos; pbError: if True (default), raise a fatal error
Dim bAlive As Boolean &apos; Return value
If IsMissing(pbForUpdate) Then pbForUpdate = False
If IsMissing(pbError) Then pbError = True
Try:
bAlive = [_Super]._IsStillAlive(pbForUpdate, pbError)
Finally:
_IsStillAlive = bAlive
Exit Function
End Function &apos; SFDocuments.SF_Base._IsStillAlive
REM -----------------------------------------------------------------------------
Private Function _PropertyGet(Optional ByVal psProperty As String _
, Optional ByVal pvArg As Variant _
@@ -437,7 +686,7 @@ Const cstSubArgs = &quot;&quot;
cstThisSub = &quot;SFDocuments.SF_Base.get&quot; &amp; psProperty
ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
Select Case psProperty
Case Else
@@ -461,4 +710,4 @@ Private Function _Repr() As String
End Function &apos; SFDocuments.SF_Base._Repr
REM ============================================ END OF SFDOCUMENTS.SF_BASE
</script:module>
</script:module>
+144 -28
View File
@@ -80,6 +80,7 @@ Private Const BASEDOCUMENTOPENERROR = &quot;BASEDOCUMENTOPENERROR&quot;
Private Const CALCADDRESSERROR = &quot;CALCADDRESSERROR&quot;
Private Const DUPLICATESHEETERROR = &quot;DUPLICATESHEETERROR&quot;
Private Const OFFSETADDRESSERROR = &quot;OFFSETADDRESSERROR&quot;
Private Const CALCFORMNOTFOUNDERROR = &quot;CALCFORMNOTFOUNDERROR&quot;
REM ============================================================= PRIVATE MEMBERS
@@ -115,7 +116,9 @@ Private Const MAXROWS = 2^20 &apos; Max number of rows in a sheet
Private Const CALCREFERENCE = &quot;SF_CalcReference&quot; &apos; Object type of _Address
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
Private Const ISCALCFORM = 2 &apos; Form is stored in a Calc document
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
@@ -163,7 +166,7 @@ Const cstSubArgs = &quot;Selection&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If IsArray(pvSelection) Then
If Not ScriptForge.SF_Utils._ValidateArray(pvSelection, &quot;pvSelection&quot;, 1, V_STRING, True) Then GoTo Finally
Else
@@ -276,7 +279,7 @@ Const cstSubArgs = &quot;[SheetName]&quot;
Check:
If IsMissing(SheetName) Or IsEmpty(SheetName) Then SheetName = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , , True) Then GoTo Finally
End If
@@ -315,7 +318,7 @@ Const cstSubArgs = &quot;Range&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
End If
@@ -360,7 +363,7 @@ Const cstSubArgs = &quot;Range&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
End If
@@ -399,7 +402,7 @@ Const cstSubArgs = &quot;Range&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
End If
@@ -460,7 +463,7 @@ Const cstSubArgs = &quot;SheetName, NewName, [BeforeSheet=&quot;&quot;&quot;&quo
Check:
If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True, , , True) Then GoTo Finally
If Not _ValidateSheet(NewName, &quot;NewName&quot;, True) Then GoTo Finally
If Not _ValidateSheet(BeforeSheet, &quot;BeforeSheet&quot;, , True, , True) Then GoTo Finally
@@ -549,7 +552,7 @@ Const cstSubArgs = &quot;FileName, SheetName, NewName, [BeforeSheet=&quot;&quot;
Check:
If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(SheetName, &quot;SheetName&quot;, V_STRING) Then GoTo Finally
If Not _ValidateSheet(NewName, &quot;NewName&quot;, True) Then GoTo Finally
@@ -623,7 +626,7 @@ Const cstSubArgs = &quot;SourceRange, DestinationCell&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(SourceRange, &quot;SourceRange&quot;, Array(V_STRING, ScriptForge.V_OBJECT), , , CALCREFERENCE) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
End If
@@ -714,7 +717,7 @@ Const cstSubArgs = &quot;SourceRange, DestinationRange&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(SourceRange, &quot;SourceRange&quot;, Array(V_STRING, ScriptForge.V_OBJECT), , , CALCREFERENCE) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(DestinationRange, &quot;DestinationRange&quot;, V_STRING) Then GoTo Finally
End If
@@ -848,6 +851,86 @@ Finally:
Exit Function
End Function &apos; SF_Documents.SF_Calc.DSum
REM -----------------------------------------------------------------------------
Public Function Forms(Optional ByVal SheetName As Variant _
, Optional ByVal Form As Variant _
) As Variant
&apos;&apos;&apos; Return either
&apos;&apos;&apos; - the list of the Forms contained in the given sheet
&apos;&apos;&apos; - a SFDocuments.Form object based on its name or its index
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Form: a form stored in the document given by its name or its index
&apos;&apos;&apos; When absent, the list of available forms is returned
&apos;&apos;&apos; To get the first (unique ?) form stored in the form document, set Form = 0
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; CALCFORMNOTFOUNDERROR Form not found
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-base array of strings if Form is absent
&apos;&apos;&apos; An instance of the SF_Form class if Form exists
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myForm As Object, myList As Variant
&apos;&apos;&apos; myList = oDoc.Forms()
&apos;&apos;&apos; Set myForm = oDoc.Forms(&quot;myForm&quot;)
Dim oForm As Object &apos; The new Form class instance
Dim oMainForm As Object &apos; com.sun.star.comp.sdb.Content
Dim oXForm As Object &apos; com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
Dim vFormNames As Variant &apos; Array of form names
Dim oForms As Object &apos; Forms collection
Const cstDrawPage = -1 &apos; There is no DrawPages collection in Calc sheets
Const cstThisSub = &quot;SFDocuments.Calc.Forms&quot;
Const cstSubArgs = &quot;SheetName, [Form=&quot;&quot;&quot;&quot;]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(Form) Or IsEmpty(Form) Then Form = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Form, &quot;Form&quot;, Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally
End If
Try:
&apos; Start from the Calc sheet and go down to forms
Set oForms = _Component.getSheets.getByName(SheetName).DrawPage.Forms
vFormNames = oForms.getElementNames()
If Len(Form) = 0 Then &apos; Return the list of valid form names
Forms = vFormNames
Else
If VarType(Form) = V_STRING Then &apos; Find the form by name
If Not ScriptForge.SF_Utils._Validate(Form, &quot;Form&quot;, V_STRING, vFormNames) Then GoTo Finally
Set oXForm = oForms.getByName(Form)
Else &apos; Find the form by index
If Form &lt; 0 Or Form &gt;= oForms.Count Then GoTo CatchNotFound
Set oXForm = oForms.getByIndex(Form)
End If
&apos; Create the new Form class instance
Set oForm = New SF_Form
With oForm
._Name = oXForm.Name
Set .[Me] = oForm
Set .[_Parent] = [Me]
._DrawPage = cstDrawPage
._UsualName = SheetName &amp; &quot; : &quot; &amp; ._Name
Set ._MainForm = Nothing
._FormType = ISCALCFORM
Set ._Form = oXForm
End With
Set Forms = oForm
End If
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchNotFound:
ScriptForge.SF_Exception.RaiseFatal(CALCFORMNOTFOUNDERROR, Form, _FileIdent())
End Function &apos; SFDocuments.SF_Calc.Forms
REM -----------------------------------------------------------------------------
Function GetColumnName(Optional ByVal ColumnNumber As Variant) As String
&apos;&apos;&apos; Convert a column number (range 1, 2,..1024) into its letter counterpart (range &apos;A&apos;, &apos;B&apos;,..&apos;AMJ&apos;).
@@ -905,7 +988,7 @@ Const cstSubArgs = &quot;Range&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
End If
@@ -988,7 +1071,7 @@ Const cstSubArgs = &quot;Range&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
End If
@@ -1053,7 +1136,7 @@ Const cstSubArgs = &quot;FileName, DestinationCell, [FilterOptions]=&quot;&quot;
Check:
If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = cstFilterOptions
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
End If
@@ -1129,7 +1212,7 @@ Check:
If IsMissing(RegistrationName) Or IsEmpty(RegistrationName) Then RegistrationName = &quot;&quot;
If IsMissing(DirectSQL) Or IsEmpty(DirectSQL) Then DirectSQL = False
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._ValidateFile(FileName, &quot;FileName&quot;, , True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(SQLCommand, &quot;SQLCommand&quot;, V_STRING) Then GoTo Finally
@@ -1219,7 +1302,7 @@ Const cstSubArgs = &quot;SheetName, [BeforeSheet=&quot;&quot;&quot;&quot;]&quot;
Check:
If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, True) Then GoTo Finally
If Not _ValidateSheet(BeforeSheet, &quot;BeforeSheet&quot;, , True, , True) Then GoTo Finally
End If
@@ -1321,7 +1404,7 @@ Const cstSubArgs = &quot;Source, Destination&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not _Validate(Source, &quot;Source&quot;, V_STRING) Then GoTo Finally
If Not _Validate(Destination, &quot;Destination&quot;, V_STRING) Then GoTo Finally
End If
@@ -1375,7 +1458,7 @@ Const cstSubArgs = &quot;SheetName, [BeforeSheet=&quot;&quot;&quot;&quot;]&quot;
Check:
If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) Then GoTo Finally
If Not _ValidateSheet(BeforeSheet, &quot;BeforeSheet&quot;, , True, , True) Then GoTo Finally
End If
@@ -1442,7 +1525,7 @@ Check:
If IsMissing(Height) Or IsEmpty(Height) Then Height = 0
If IsMissing(Width) Or IsEmpty(Width) Then Width = 0
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Rows, &quot;Rows&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Columns, &quot;Columns&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
@@ -1517,7 +1600,7 @@ Const cstSubArgs = &quot;SheetName&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) Then GoTo Finally
End If
@@ -1557,7 +1640,7 @@ Const cstSubArgs = &quot;SheetName, NewName&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive(True) Then GoTo Finally
If Not _IsStillAlive(True) Then GoTo Finally
If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) Then GoTo Finally
If Not _ValidateSheet(NewName, &quot;NewName&quot;, True) Then GoTo Finally
End If
@@ -1604,7 +1687,7 @@ Const cstSubArgs = &quot;TargetCell, Value&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(TargetCell, &quot;TargetCell&quot;, V_STRING) Then GoTo Finally
If IsArray(Value) Then
If Not ScriptForge.SF_Utils._ValidateArray(Value, &quot;Value&quot;) Then GoTo Finally
@@ -1659,7 +1742,7 @@ Const cstSubArgs = &quot;TargetRange, Style&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(TargetRange, &quot;TargetRange&quot;, V_STRING) Then GoTo Finally
Set oStyleFamilies = _Component.StyleFamilies
If oStyleFamilies.hasByName(cstStyle) Then vStyles = oStyleFamilies.getByName(cstStyle).getElementNames() Else vStyles = Array()
@@ -1714,7 +1797,7 @@ Const cstSubArgs = &quot;TargetRange, Formula&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(TargetRange, &quot;TargetRange&quot;, V_STRING) Then GoTo Finally
If IsArray(Formula) Then
If Not ScriptForge.SF_Utils._ValidateArray(Formula, &quot;Formula&quot;, 0, V_STRING) Then GoTo Finally
@@ -1831,7 +1914,7 @@ Const cstSubArgs = &quot;TargetRange, Value&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(TargetRange, &quot;TargetRange&quot;, V_STRING) Then GoTo Finally
If IsArray(Value) Then
If Not ScriptForge.SF_Utils._ValidateArray(Value, &quot;Value&quot;) Then GoTo Finally
@@ -1920,7 +2003,7 @@ Check:
If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
If IsMissing(SortColumns) Or IsEmpty(SortColumns) Then SortColumns = False
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
If Not ScriptForge.SF_Utils._ValidateArray(SortKeys, &quot;SortKeys&quot;, 1, V_NUMERIC, True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
@@ -2339,7 +2422,7 @@ Const cstSubArgs = &quot;Range&quot;
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
End If
@@ -2364,6 +2447,15 @@ Catch:
GoTo Finally
End Function &apos; SF_Documents.SF_Calc._DFunction
REM -----------------------------------------------------------------------------
Private Function _FileIdent() As String
&apos;&apos;&apos; Returns a file identification from the information that is currently available
&apos;&apos;&apos; Useful e.g. for display in error messages
_FileIdent = [_Super]._FileIdent()
End Function &apos; SFDocuments.SF_Calc._FileIdent
REM -----------------------------------------------------------------------------
Function _GetColumnName(ByVal plColumnNumber As Long) As String
&apos;&apos;&apos; Convert a column number (range 1, 2,..1024) into its letter counterpart (range &apos;A&apos;, &apos;B&apos;,..&apos;AMJ&apos;).
@@ -2390,6 +2482,29 @@ Finally:
_GetColumnName = sCol
End Function &apos; SFDocuments.SF_Calc._GetColumnName
REM -----------------------------------------------------------------------------
Private Function _IsStillAlive(Optional ByVal pbForUpdate As Boolean _
, Optional ByVal pbError As Boolean _
) As Boolean
&apos;&apos;&apos; Returns True if the document has not been closed manually or incidentally since the last use
&apos;&apos;&apos; If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pbForUpdate: if True (default = False), check additionally if document is open for editing
&apos;&apos;&apos; pbError: if True (default), raise a fatal error
Dim bAlive As Boolean &apos; Return value
If IsMissing(pbForUpdate) Then pbForUpdate = False
If IsMissing(pbError) Then pbError = True
Try:
bAlive = [_Super]._IsStillAlive(pbForUpdate, pbError)
Finally:
_IsStillAlive = bAlive
Exit Function
End Function &apos; SFDocuments.SF_Calc._IsStillAlive
REM -----------------------------------------------------------------------------
Private Function _LastCell(ByRef poSheet As Object) As Variant
&apos;&apos;&apos; Returns in an array the coordinates of the last used cell in the given sheet
@@ -2632,7 +2747,7 @@ Const cstSubArgs = &quot;&quot;
cstThisSub = &quot;SFDocuments.SF_Calc.get&quot; &amp; psProperty
ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
If Not [_Super]._IsStillAlive() Then GoTo Finally
If Not _IsStillAlive() Then GoTo Finally
Select Case psProperty
Case &quot;CurrentSelection&quot;
@@ -2782,6 +2897,7 @@ Private Function _ValidateSheet(Optional ByRef pvSheetName As Variant _
&apos;&apos;&apos; Sheet designation validation function similar to the SF_Utils._ValidateXXX functions
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pvSheetName: string or numeric position
&apos;&apos;&apos; pvArgName: the name of the variable to be used in the error message
&apos;&apos;&apos; pvNew: if True, sheet must not exist (default = False)
&apos;&apos;&apos; pvActive: if True, the shortcut &quot;~&quot; is accepted (default = False)
&apos;&apos;&apos; pvOptional: if True, a zero-length string is accepted (default = False)
@@ -2840,4 +2956,4 @@ CatchDuplicate:
End Function &apos; SFDocuments.SF_Calc._ValidateSheet
REM ============================================ END OF SFDOCUMENTS.SF_CALC
</script:module>
</script:module>
+87 -1
View File
@@ -24,6 +24,8 @@ Option Explicit
&apos;&apos;&apos; - accessing their standard or custom properties
&apos;&apos;&apos; Specific properties and methods are implemented in the concerned subclass(es) SF_Calc, SF_Writer, ...
&apos;&apos;&apos;
&apos;&apos;&apos; Documents might contain forms. The current service gives access to the &quot;SFDocuments.Form&quot; service
&apos;&apos;&apos;
&apos;&apos;&apos; To workaround the absence of class inheritance in LibreOffice Basic, some redundancy is necessary
&apos;&apos;&apos; Each subclass MUST implement also the generic methods and properties, even if they only call
&apos;&apos;&apos; the parent methods and properties implemented below
@@ -53,10 +55,13 @@ Private Const DOCUMENTSAVEERROR = &quot;DOCUMENTSAVEERROR&quot;
Private Const DOCUMENTSAVEASERROR = &quot;DOCUMENTSAVEASERROR&quot;
Private Const DOCUMENTREADONLYERROR = &quot;DOCUMENTREADONLYERROR&quot;
Private Const FORMDEADERROR = &quot;FORMDEADERROR&quot;
REM ============================================================= PRIVATE MEMBERS
Private [Me] As Object
Private [_Parent] As Object
Private [_SubClass] As Object &apos; Subclass instance
Private ObjectType As String &apos; Must be DOCUMENT
Private ServiceName As String
@@ -74,12 +79,15 @@ Private _CustomProperties As Object &apos; Dictionary of custom properties
REM ============================================================ MODULE CONSTANTS
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
Const ISDOCFORM = 1 &apos; Form is stored in a Calc, Writer, ... document
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
Set [Me] = Nothing
Set [_Parent] = Nothing
Set [_SubClass] = Nothing
ObjectType = &quot;DOCUMENT&quot;
ServiceName = &quot;SFDocuments.Document&quot;
Set _Component = Nothing
@@ -448,6 +456,84 @@ Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Document.CloseDocument
REM -----------------------------------------------------------------------------
Public Function Forms(Optional ByVal Form As Variant) As Variant
&apos;&apos;&apos; APPLICABLE ONLY ON WRITER DOCUMENTS
&apos;&apos;&apos; Return either
&apos;&apos;&apos; - the list of the Forms contained in the form document
&apos;&apos;&apos; - a SFDocuments.Form object based on its name or its index
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Form: a form stored in the document given by its name or its index
&apos;&apos;&apos; When absent, the list of available forms is returned
&apos;&apos;&apos; To get the first (unique ?) form stored in the form document, set Form = 0
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; WRITERFORMNOTFOUNDERROR Form not found
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-base array of strings if Form is absent
&apos;&apos;&apos; An instance of the SF_Form class if Form exists
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myForm As Object, myList As Variant
&apos;&apos;&apos; myList = oDoc.Forms()
&apos;&apos;&apos; Set myForm = oDoc.Forms(&quot;myForm&quot;)
Dim oForm As Object &apos; The new Form class instance
Dim oMainForm As Object &apos; com.sun.star.comp.sdb.Content
Dim oXForm As Object &apos; com.sun.star.form.XForm
Dim vFormNames As Variant &apos; Array of form names
Dim oForms As Object &apos; Forms collection
Const cstDrawPage = 0 &apos; Only 1 drawpage in a Writer document
Const cstThisSub = &quot;SFDocuments.Document.Forms&quot;
Const cstSubArgs = &quot;[Form=&quot;&quot;&quot;&quot;]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(Form) Or IsEmpty(Form) Then Form = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Form, &quot;Form&quot;, Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally
End If
Try:
&apos; Start from the document component and go down to forms
Set oForms = _Component.DrawPages(cstDrawPage).Forms
vFormNames = oForms.getElementNames()
If Len(Form) = 0 Then &apos; Return the list of valid form names
Forms = vFormNames
Else
If VarType(Form) = V_STRING Then &apos; Find the form by name
If Not ScriptForge.SF_Utils._Validate(Form, &quot;Form&quot;, V_STRING, vFormNames) Then GoTo Finally
Set oXForm = oForms.getByName(Form)
Else &apos; Find the form by index
If Form &lt; 0 Or Form &gt;= oForms.Count Then GoTo CatchNotFound
Set oXForm = oForms.getByIndex(Form)
End If
&apos; Create the new Form class instance
Set oForm = New SF_Form
With oForm
._Name = oXForm.Name
Set .[Me] = oForm
Set .[_Parent] = [Me]
._DrawPage = cstDrawPage
._UsualName = ._Name
Set ._MainForm = Nothing
._FormType = ISDOCFORM
Set ._Form = oXForm
End With
Set Forms = oForm
End If
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchNotFound:
ScriptForge.SF_Exception.RaiseFatal(WRITERFORMNOTFOUNDERROR, Form, _FileIdent())
End Function &apos; SFDocuments.SF_Document.Forms
REM -----------------------------------------------------------------------------
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
&apos;&apos;&apos; Return the actual value of the given property
+652
View File
@@ -0,0 +1,652 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_Form" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
REM === The SFDocuments library is one of the associated libraries. ===
REM === Full documentation is available on https://help.libreoffice.org/ ===
REM =======================================================================================================================
Option Compatible
Option ClassModule
Option Explicit
&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
&apos;&apos;&apos; SF_Form
&apos;&apos;&apos; =======
&apos;&apos;&apos; Management of forms defined in LibreOffice documents. Supported types are Base, Calc and Writer documents.
&apos;&apos;&apos; For Base documents, it includes the management of subforms
&apos;&apos;&apos; Each instance of the current class represents a single form or a single subform
&apos;&apos;&apos;
&apos;&apos;&apos; A form may optionally be (understand &quot;is often&quot;) linked to a data source manageable with the SFDatabases.Database service
&apos;&apos;&apos; The current service offers a rapid access to that service
&apos;&apos;&apos;
&apos;&apos;&apos; Definitions:
&apos;&apos;&apos;
&apos;&apos;&apos; FormDocument:
&apos;&apos;&apos; For usual documents, there is only 1 form document. It is in fact the document itself.
&apos;&apos;&apos; A Base document may contain an unlimited number of form documents.
&apos;&apos;&apos; In the Base terminology they are called &quot;forms&quot;. This could create some confusion.
&apos;&apos;&apos; They can be organized in folders. Their name is then always the full path of folders + form
&apos;&apos;&apos; with the slash (&quot;/&quot;) as path separator
&apos;&apos;&apos; A FormDocument is a set of Forms. Form names are visible in the user interface thanks to the form navigator
&apos;&apos;&apos; Often there is only 1 Form present in a FormDocument. Having more, however, might improve
&apos;&apos;&apos; the user experience significantly
&apos;&apos;&apos;
&apos;&apos;&apos; Form: WHERE IT IS ABOUT IN THE CURRENT &quot;Form&quot; SERVICE
&apos;&apos;&apos; Is an abstract set of Controls in an OPEN FormDocument
&apos;&apos;&apos; Each form is (often) linked to a dataset (table, query or Select statement),
&apos;&apos;&apos; located in any database (provided the user may access it)
&apos;&apos;&apos; A usual document may contain several forms. Each of which may have its own data source (database + dataset)
&apos;&apos;&apos; A Base form document may contain several forms. Each of which may address its own dataset. The database however is unique
&apos;&apos;&apos; A form is defined by its owning FormDocument and its FormName or FormIndex
&apos;&apos;&apos;
&apos;&apos;&apos; Service invocations:
&apos;&apos;&apos;
&apos;&apos;&apos; REM the form is stored in a not-Base document (Calc, Writer)
&apos;&apos;&apos; Dim oDoc As Object, myForm As Object
&apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.Document&quot;, ThisComponent)
&apos;&apos;&apos; Set myForm = oDoc.Forms(&quot;Form1&quot;)
&apos;&apos;&apos; &apos; or, alternatively, when there is only 1 form
&apos;&apos;&apos; Set myForm = oDoc.Forms(0)
&apos;&apos;&apos;
&apos;&apos;&apos; REM the form is stored in one of the FormDocuments of a Base document
&apos;&apos;&apos; Dim oDoc As Object, myForm As Object, mySubForm As Object
&apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.Document&quot;, ThisDatabaseDocument)
&apos;&apos;&apos; oDoc.OpenFormDocument(&quot;thisFormDocument&quot;)
&apos;&apos;&apos; Set myForm = oDoc.Forms(&quot;thisFormDocument&quot;, &quot;MainForm&quot;)
&apos;&apos;&apos; &apos; or, alternatively, when there is only 1 form
&apos;&apos;&apos; Set myForm = oDoc.Forms(&quot;thisFormDocument&quot;, 0)
&apos;&apos;&apos; &apos; To access a subform: myForm and mySubForm become distinct instances of the current class
&apos;&apos;&apos; Set mySubForm = myForm.SubForms(&quot;mySubForm&quot;)
&apos;&apos;&apos;
&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
REM ================================================================== EXCEPTIONS
Private Const FORMDEADERROR = &quot;FORMDEADERROR&quot;
REM ============================================================= PRIVATE MEMBERS
Private [Me] As Object
Private [_Parent] As Object
Private ObjectType As String &apos; Must be Form
Private ServiceName As String
&apos; Form location
Private _Name As String &apos; Internal name of the form
Private _DrawPage As Long &apos; Index in DrawOages collection
Private _UsualName As String &apos; Name as known by user
Private _FormType As Integer &apos; One of the ISxxxFORM constants
&apos; Form UNO references
&apos; The forms container found in a Base document
&apos; Vital for Base forms and subforms
Private _MainForm As Object &apos; com.sun.star.comp.sdb.Content
&apos; The entry to the interactions with the form. Set by the _IsStillAlive() method
&apos; Each method or property requiring that the form is opened should first invoke that method
Private _Form As Object &apos; com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
Private _Database As Object &apos; Database class instance
&apos; Form attributes
&apos; Persistent storage for controls
Private _ControlCache As Variant &apos; Array of control objects sorted like ElementNames of XForm
REM ============================================================ MODULE CONSTANTS
Const ISDOCFORM = 1 &apos; Form is stored in a Writer document
Const ISCALCFORM = 2 &apos; Form is stored in a Calc document
Const ISBASEFORM = 3 &apos; Form is stored in a Base document
Const ISSUBFORM = 4 &apos; Form is a subform of a form stored in a Base document or of another subform
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
Set [Me] = Nothing
Set [_Parent] = Nothing
ObjectType = &quot;Form&quot;
ServiceName = &quot;SFDocuments.Form&quot;
_Name = &quot;&quot;
_DrawPage = -1
_FormType = 0
Set _MainForm = Nothing
Set _Form = Nothing
Set _Database = Nothing
_ControlCache = Array()
End Sub &apos; SFDocuments.SF_Form Constructor
REM -----------------------------------------------------------------------------
Private Sub Class_Terminate()
Call Class_Initialize()
End Sub &apos; SFDocuments.SF_Form Destructor
REM -----------------------------------------------------------------------------
Public Function Dispose() As Variant
Call Class_Terminate()
Set Dispose = Nothing
End Function &apos; SFDocuments.SF_Form Explicit Destructor
REM ================================================================== PROPERTIES
REM -----------------------------------------------------------------------------
Property Get Caption() As Variant
&apos;&apos;&apos; The Caption property refers to the title of the Form
Caption = _PropertyGet(&quot;Caption&quot;)
End Property &apos; SFDocuments.SF_Form.Caption (get)
REM -----------------------------------------------------------------------------
Property Let Caption(Optional ByVal pvCaption As Variant)
&apos;&apos;&apos; Set the updatable property Caption
_PropertySet(&quot;Caption&quot;, pvCaption)
End Property &apos; SFDocumentsDialog.SF_Form.Caption (let)
REM -----------------------------------------------------------------------------
Property Get Height() As Variant
&apos;&apos;&apos; The Height property refers to the height of the Form box
Height = _PropertyGet(&quot;Height&quot;)
End Property &apos; SFDocuments.SF_Form.Height (get)
REM -----------------------------------------------------------------------------
Property Let Height(Optional ByVal pvHeight As Variant)
&apos;&apos;&apos; Set the updatable property Height
_PropertySet(&quot;Height&quot;, pvHeight)
End Property &apos; SFDocuments.SF_Form.Height (let)
REM -----------------------------------------------------------------------------
Property Get Name() As String
&apos;&apos;&apos; Return the name of the actual Form
Name = _PropertyGet(&quot;Name&quot;)
End Property &apos; SFDocuments.SF_Form.Name
REM -----------------------------------------------------------------------------
Property Get Visible() As Variant
&apos;&apos;&apos; The Visible property is False before the Execute() statement
Visible = _PropertyGet(&quot;Visible&quot;)
End Property &apos; SFDocuments.SF_Form.Visible (get)
REM -----------------------------------------------------------------------------
Property Let Visible(Optional ByVal pvVisible As Variant)
&apos;&apos;&apos; Set the updatable property Visible
_PropertySet(&quot;Visible&quot;, pvVisible)
End Property &apos; SFDocuments.SF_Form.Visible (let)
REM -----------------------------------------------------------------------------
Property Get Width() As Variant
&apos;&apos;&apos; The Width property refers to the Width of the Form box
Width = _PropertyGet(&quot;Width&quot;)
End Property &apos; SFDocuments.SF_Form.Width (get)
REM -----------------------------------------------------------------------------
Property Let Width(Optional ByVal pvWidth As Variant)
&apos;&apos;&apos; Set the updatable property Width
_PropertySet(&quot;Width&quot;, pvWidth)
End Property &apos; SFDocuments.SF_Form.Width (let)
REM -----------------------------------------------------------------------------
Property Get XFormModel() As Object
&apos;&apos;&apos; The XFormModel property returns the model UNO object of the Form
XFormModel = _PropertyGet(&quot;XFormModel&quot;)
End Property &apos; SFDocuments.SF_Form.XFormModel (get)
REM -----------------------------------------------------------------------------
Property Get XFormView() As Object
&apos;&apos;&apos; The XFormView property returns the view UNO object of the Form
XFormView = _PropertyGet(&quot;XFormView&quot;)
End Property &apos; SFDocuments.SF_Form.XFormView (get)
REM ===================================================================== METHODS
REM -----------------------------------------------------------------------------
Public Function Activate() As Boolean
&apos;&apos;&apos; Set the focus on the current Form instance
&apos;&apos;&apos; Probably called from after an event occurrence or to focus on an open fForm
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if focusing is successful
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim oDlg As Object
&apos;&apos;&apos; Set oDlg = CreateScriptService(,, &quot;myForm&quot;) &apos; Form stored in current document&apos;s standard library
&apos;&apos;&apos; oDlg.Activate()
Dim bActivate As Boolean &apos; Return value
Const cstThisSub = &quot;SFDocuments.Form.Activate&quot;
Const cstSubArgs = &quot;&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bActivate = False
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
End If
Try:
Finally:
Activate = bActivate
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Form.Activate
REM -----------------------------------------------------------------------------
Public Function Controls(Optional ByVal ControlName As Variant) As Variant
&apos;&apos;&apos; Return either
&apos;&apos;&apos; - the list of the controls contained in the Form
&apos;&apos;&apos; - a Form control object based on its name
&apos;&apos;&apos; Args:
&apos;&apos;&apos; ControlName: a valid control name as a case-sensitive string. If absent the list is returned
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-base array of strings if ControlName is absent
&apos;&apos;&apos; An instance of the SF_FormControl class if ControlName exists
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; ControlName is invalid
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myForm As Object, myList As Variant, myControl As Object
&apos;&apos;&apos; Set myForm = CreateScriptService(&quot;SFDocuments.Form&quot;, Container, Library, FormName)
&apos;&apos;&apos; myList = myForm.Controls()
&apos;&apos;&apos; Set myControl = myForm.Controls(&quot;myTextBox&quot;)
Dim oControl As Object &apos; The new control class instance
Dim lIndexOfNames As Long &apos; Index in ElementNames array. Used to access _ControlCache
Dim vControl As Variant &apos; Alias of _ControlCache entry
Const cstThisSub = &quot;SFDocuments.Form.Controls&quot;
Const cstSubArgs = &quot;[ControlName]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(ControlName) Or IsEmpty(ControlName) Then ControlName = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(ControlName, &quot;ControlName&quot;, V_STRING) Then GoTo Finally
End If
Try:
If Len(ControlName) = 0 Then
Else
End If
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchNotFound:
ScriptForge.SF_Utils._Validate(ControlName, &quot;ControlName&quot;, V_STRING, _FormModel.getElementNames())
GoTo Finally
End Function &apos; SFDocuments.SF_Form.Controls
REM -----------------------------------------------------------------------------
Public Function GetDatabase(Optional ByVal User As Variant _
, Optional ByVal Password As Variant _
) As Object
&apos;&apos;&apos; Returns a Database instance (service = SFDatabases.Database) giving access
&apos;&apos;&apos; to the execution of SQL commands on the database defined and/or stored in
&apos;&apos;&apos; the actual Base document
&apos;&apos;&apos; Each form has its own database connection, except within Base documents where
&apos;&apos;&apos; they all share the same connection
&apos;&apos;&apos; Args:
&apos;&apos;&apos; User, Password: the login parameters as strings. Defaults = &quot;&quot;
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A SFDatabases.Database instance or Nothing
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myDb As Object
&apos;&apos;&apos; Set myDb = oForm.GetDatabase()
Dim FSO As Object &apos; Alias for SF_FileSystem
Dim sUser As String &apos; Alias for User
Dim sPassword As String &apos; Alias for Password
Const cstThisSub = &quot;SFDocuments.Form.GetDatabase&quot;
Const cstSubArgs = &quot;[User=&quot;&quot;&quot;&quot;], [Password=&quot;&quot;&quot;&quot;]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Set GetDatabase = Nothing
Check:
If IsMissing(User) Or IsEmpty(User) Then User = &quot;&quot;
If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Parent]._IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(User, &quot;User&quot;, V_STRING) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
End If
Try:
&apos; Adjust connection arguments
If Len(User) = 0 Then
If ScriptForge.SF_Session.HasUnoProperty(_Form, &quot;User&quot;) Then sUser = _Form.User Else sUser = &quot;&quot;
Else
sUser = User
End If
If Len(sUser) + Len(Password) = 0 Then
If ScriptForge.SF_Session.HasUnoProperty(_Form, &quot;Password&quot;) Then sPassword = _Form.Password Else sPassword = Password
End If
&apos; Connect to database, avoiding multiple requests
If IsNull(_Database) Then &apos; 1st connection request from the current form instance
If _FormType = ISBASEFORM Then
&apos; Fetch the shared connection
Set _Database = [_Parent].GetDatabase(User, Password)
ElseIf Len(_Form.DataSOurceName) = 0 Then &apos; There is no database linked with the form
&apos; Return Nothing
Else
&apos; Check if DataSourceName is a file or a registrered name and create database instance accordingly
Set FSO = ScriptForge.SF_FileSystem
If FSO.FileExists(FSO._ConvertFromUrl(_Form.DataSourceName)) Then
Set _Database = ScriptForge.SF_Services.CreateScriptService(&quot;SFDatabases.Database&quot; _
, _Form.DataSourceName, , , sUser, sPassword)
Else
Set _Database = ScriptForge.SF_Services.CreateScriptService(&quot;SFDatabases.Database&quot; _
, , _Form.DataSourceName, , sUser, sPassword)
End If
If IsNull(_Database) Then GoTo CatchConnect
End If
Else
EndIf
Finally:
Set GetDatabase = _Database
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchConnect:
ScriptForge.SF_Exception.RaiseFatal(DBCONNECTERROR, &quot;User&quot;, User, &quot;Password&quot;, Password, [_Super]._FileIdent())
GoTo Finally
End Function &apos; SFDocuments.SF_Form.GetDatabase
REM -----------------------------------------------------------------------------
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
&apos;&apos;&apos; Return the actual value of the given property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; PropertyName: the name of the property as a string
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The actual value of the property
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; ARGUMENTERROR The property does not exist
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; oDlg.GetProperty(&quot;Caption&quot;)
Const cstThisSub = &quot;SFDocuments.Form.GetProperty&quot;
Const cstSubArgs = &quot;&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
GetProperty = Null
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
End If
Try:
GetProperty = _PropertyGet(PropertyName)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Form.GetProperty
REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
&apos;&apos;&apos; Return the list of public methods of the Model service as an array
Methods = Array( _
&quot;Activate&quot; _
, &quot;CloseForm&quot; _
, &quot;Controls&quot; _
, &quot;First&quot; _
, &quot;GetDatabase&quot; _
, &quot;Last&quot; _
, &quot;Move&quot; _
, &quot;New&quot; _
, &quot;Next&quot; _
, &quot;Previous&quot; _
, &quot;Refresh&quot; _
, &quot;Requery&quot; _
, &quot;SubForms&quot; _
)
End Function &apos; SFDocuments.SF_Form.Methods
REM -----------------------------------------------------------------------------
Public Function Properties() As Variant
&apos;&apos;&apos; Return the list or properties of the Form class as an array
Properties = Array( _
&quot;AllowAdditions&quot; _
, &quot;AllowDeletions&quot; _
, &quot;AllowEdits&quot; _
, &quot;Bookmark&quot; _
, &quot;Caption&quot; _
, &quot;CurrentRecord&quot; _
, &quot;Filter&quot; _
, &quot;FilterOn&quot; _
, &quot;Height&quot; _
, &quot;IsLoaded&quot; _
, &quot;LinkChildFields&quot; _
, &quot;LinkParentFields&quot; _
, &quot;Name&quot; _
, &quot;OnApproveCursorMove&quot; _
, &quot;OnApproveParameter&quot; _
, &quot;OnApproveReset&quot; _
, &quot;OnApproveRowChange&quot; _
, &quot;OnApproveSubmit&quot; _
, &quot;OnConfirmDelete&quot; _
, &quot;OnCursorMoved&quot; _
, &quot;OnErrorOccurred&quot; _
, &quot;OnLoaded&quot; _
, &quot;OnReloaded&quot; _
, &quot;OnReloading&quot; _
, &quot;OnResetted&quot; _
, &quot;OnRowChanged&quot; _
, &quot;OnUnloaded&quot; _
, &quot;OnUnloading&quot; _
, &quot;OrderBy&quot; _
, &quot;OrderByOn&quot; _
, &quot;RecordSource&quot; _
, &quot;Visible&quot; _
, &quot;Width&quot; _
)
End Function &apos; SFDocuments.SF_Form.Properties
REM -----------------------------------------------------------------------------
Public Function SetProperty(Optional ByVal PropertyName As Variant _
, Optional ByRef Value As Variant _
) As Boolean
&apos;&apos;&apos; Set a new value to the given property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; PropertyName: the name of the property as a string
&apos;&apos;&apos; Value: its new value
&apos;&apos;&apos; Exceptions
&apos;&apos;&apos; ARGUMENTERROR The property does not exist
Const cstThisSub = &quot;SFDocuments.Form.SetProperty&quot;
Const cstSubArgs = &quot;PropertyName, Value&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
SetProperty = False
Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
End If
Try:
SetProperty = _PropertySet(PropertyName, Value)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Form.SetProperty
REM =========================================================== PRIVATE FUNCTIONS
REM -----------------------------------------------------------------------------
Public Function _GetEventName(ByVal psProperty As String) As String
&apos;&apos;&apos; Return the LO internal event name derived from the SF property name
&apos;&apos;&apos; The SF property name is not case sensitive, while the LO name is case-sensitive
&apos; Corrects the typo on ErrorOccur(r?)ed, if necessary
Dim vProperties As Variant &apos; Array of class properties
Dim sProperty As String &apos; Correctly cased property name
vProperties = Properties()
sProperty = vProperties(ScriptForge.SF_Array.IndexOf(vProperties, psProperty, SortOrder := &quot;ASC&quot;))
_GetEventName = LCase(Mid(sProperty, 3, 1)) &amp; Right(sProperty, Len(sProperty) - 3)
End Function &apos; SFDocuments.SF_Form._GetEventName
REM -----------------------------------------------------------------------------
Private Function _GetListener(ByVal psEventName As String) As String
&apos;&apos;&apos; Getting/Setting macros triggered by events requires a Listener-EventName pair
&apos;&apos;&apos; Return the X...Listener corresponding with the event name in argument
Select Case UCase(psEventName)
Case Else
_GetListener = &quot;&quot;
End Select
End Function &apos; SFDocuments.SF_Form._GetListener
REM -----------------------------------------------------------------------------
Private Function _IsStillAlive(Optional ByVal pbError As Boolean) As Boolean
&apos;&apos;&apos; Return True if the Form is still open
&apos;&apos;&apos; If dead the actual instance is partially (part related to open forms) disposed
&apos;&apos;&apos; and the execution is cancelled when pbError = True (default)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pbError: if True (default), raise a fatal error
Dim bAlive As Boolean &apos; Return value
Check:
On Local Error GoTo Catch &apos; Anticipate DisposedException errors or alike
If IsMissing(pbError) Then pbError = True
Try:
&apos; For usual documents, check that the parent document is still open
&apos; For Base forms and subforms, check the openess of the main form
Select Case _FormType
Case ISDOCFORM, ISCALCFORM
bAlive = [_Parent]._IsStillAlive(pbError)
Case ISBASEFORM, ISSUBFORM
&apos; A form that has never been opened has no component
&apos; If ever opened and closed afterwards, it keeps the Component but loses its Controller
bAlive = Not IsNull(_MainForm.Component)
If bAlive Then bAlive = Not IsNull(_MainForm.Component.CurrentController)
End Select
If Not bAlive Then GoTo Catch
Finally:
_IsStillAlive = bAlive
Exit Function
Catch:
bAlive = False
On Error GoTo 0
&apos; Dispose the properties related to *open* forms
Set _Form = Nothing
If Not IsNull(_Database) And _FormType = ISDOCFORM Then Set _Database = _Database.Dispose()
Set _ControlCache = Nothing
&apos; Display error message
If pbError Then ScriptForge.SF_Exception.RaiseFatal(FORMDEADERROR, _Name, [_Parent]._FileIdent())
GoTo Finally
End Function &apos; SFDocuments.SF_Form._IsStillAlive
REM -----------------------------------------------------------------------------
Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
&apos;&apos;&apos; Return the value of the named property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psProperty: the name of the property
Static oSession As Object &apos; Alias of SF_Session
Dim cstThisSub As String
Const cstSubArgs = &quot;&quot;
cstThisSub = &quot;SFDocuments.Form.get&quot; &amp; psProperty
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
&apos; All the properties except one require an open form
If Not _IsStillAlive() Then GoTo Finally
If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
Select Case UCase(psProperty)
Case UCase(&quot;Caption&quot;)
Case UCase(&quot;Height&quot;)
Case UCase(&quot;Name&quot;)
Case UCase(&quot;Visible&quot;)
Case UCase(&quot;Width&quot;)
Case Else
_PropertyGet = Null
End Select
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Form._PropertyGet
REM -----------------------------------------------------------------------------
Private Function _PropertySet(Optional ByVal psProperty As String _
, Optional ByVal pvValue As Variant _
) As Boolean
&apos;&apos;&apos; Set the new value of the named property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psProperty: the name of the property
&apos;&apos;&apos; pvValue: the new value of the given property
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if successful
Dim bSet As Boolean &apos; Return value
Static oSession As Object &apos; Alias of SF_Session
Dim cstThisSub As String
Const cstSubArgs = &quot;Value&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bSet = False
cstThisSub = &quot;SFDocuments.Form.set&quot; &amp; psProperty
ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
If Not _IsStillAlive() Then GoTo Finally
If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
bSet = True
Select Case UCase(psProperty)
Case UCase(&quot;Caption&quot;)
Case UCase(&quot;Height&quot;)
Case UCase(&quot;Visible&quot;)
Case UCase(&quot;Width&quot;)
Case Else
bSet = False
End Select
Finally:
_PropertySet = bSet
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Form._PropertySet
REM -----------------------------------------------------------------------------
Private Function _Repr() As String
&apos;&apos;&apos; Convert the Model instance to a readable string, typically for debugging purposes (DebugPrint ...)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Return:
&apos;&apos;&apos; &quot;[Form]: Name&quot;
_Repr = &quot;[Form]: &quot; &amp; _UsualName
End Function &apos; SFDocuments.SF_Form._Repr
REM ============================================ END OF SFDOCUMENTS.SF_FORM
</script:module>
@@ -158,10 +158,12 @@ Try:
Set oDocument = New SF_Base
Set oSuperDocument = New SF_Document
Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
Set oSuperDocument.[_SubClass] = oDocument
Case &quot;Calc&quot;
Set oDocument = New SF_Calc
Set oSuperDocument = New SF_Document
Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
Set oSuperDocument.[_SubClass] = oDocument
Case Else &apos; Only superclass
Set oDocument = New SF_Document
Set oSuperDocument = oDocument
+1
View File
@@ -6,4 +6,5 @@
<library:element library:name="SF_Calc"/>
<library:element library:name="SF_Register"/>
<library:element library:name="SF_Base"/>
<library:element library:name="SF_Form"/>
</library:library>