office-gobmx/wizards/source/scriptforge/SF_Exception.xba
Jean-Pierre Ledure 7b2a6f0444 ScriptForge (SFDatabases) new Dataset service
A dataset represents a set of tabular data
stored/produced by a database.
To use datasets, the database instance must exist
but the Base document may not be open.

A Dataset instance is create either with
- the (new) database.CreateDataset() method
- from an existing dataset with the (new)
  dataset.CreateDataset() method.

The proposed API supports next main purposes:
- browse for- and backward thru the dataset to get its content
- update any record with new values
- create new records or delete some.
In summary, the AKA "CRUD" operations
(create, read, update, delete).

The originality of the proposed API is the use
of a dense syntax to make insertions and updates
easy and readable:
Example:
(BASIC)
  Dim newID As Long
  newID = dataset.Insert("LastName", "Doe", "FirstName", "John")
  '     ... is equivalent to:
  Dim dict As Object, newID As Long
  Set dict = CreateScriptService("ScriptForge.Dictionary")
  dict.Add("LastName", "Doe")
  dict.Add("FirstName", "John")
  newID = dataset.Insert(dict)
(PYTHON) - next statements are equivalent
  newid = dataset.Insert('LastName', 'Doe', 'FirstName', 'John')
  newid = dataset.Insert({'LastName': 'Doe', 'FirstName': 'John'})
  newid = dataset.Insert(dict(LastName = 'Doe', FirstName = 'John'))
  newid = dataset.Insert(LastName = 'Doe', FirstName = 'John')

You will notice that the returned value is the AutoValue primery
key (when it exists) which makes it reuse as a foreign key
immediate.

The API is fully available both in Basic and Python user scripts.

The new service will require its inclusion in the user documentation.

Change-Id: I4f834c4234e5b96ec8fddfffbad791ecf31899df
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159325
Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
Tested-by: Jenkins
2023-11-11 18:20:15 +01:00

1413 lines
No EOL
69 KiB
XML

<?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_Exception" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
REM === Full documentation is available on https://help.libreoffice.org/ ===
REM =======================================================================================================================
Option Compatible
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; Exception (aka SF_Exception)
&apos;&apos;&apos; =========
&apos;&apos;&apos; Generic singleton class for Basic code debugging and error handling
&apos;&apos;&apos;
&apos;&apos;&apos; Errors may be generated by
&apos;&apos;&apos; the Basic run-time error detection
&apos;&apos;&apos; in the ScriptForge code =&gt; RaiseAbort()
&apos;&apos;&apos; in a user code =&gt; Raise()
&apos;&apos;&apos; an error detection implemented
&apos;&apos;&apos; in the ScriptForge code =&gt; RaiseFatal()
&apos;&apos;&apos; in a user code =&gt; Raise() or RaiseWarning()
&apos;&apos;&apos;
&apos;&apos;&apos; When a run-time error occurs, the properties of the Exception object are filled
&apos;&apos;&apos; with information that uniquely identifies the error and information that can be used to handle it
&apos;&apos;&apos; The SF_Exception object is in this context similar to the VBA Err object
&apos;&apos;&apos; See https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/err-object
&apos;&apos;&apos; The Number property identifies the error: it can be a numeric value or a string
&apos;&apos;&apos; Numeric values up to 2000 are considered Basic run-time errors
&apos;&apos;&apos;
&apos;&apos;&apos; The &quot;console&quot; logs events, actual variable values, errors, ... It is an easy mean
&apos;&apos;&apos; to debug Basic programs especially when the IDE is not usable, f.i. in Calc user defined functions
&apos;&apos;&apos; or during control events processing
&apos;&apos;&apos; =&gt; DebugPrint()
&apos;&apos;&apos;
&apos;&apos;&apos; The usual behaviour of the application when an error occurs is:
&apos;&apos;&apos; 1. Log the error in the console
&apos;&apos;&apos; 2, Inform the user about the error with either a standard or a customized message
&apos;&apos;&apos; 3. Optionally, stop the execution of the current macro
&apos;&apos;&apos;
&apos;&apos;&apos; Detailed user documentation:
&apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_exception.html?DbPAR=BASIC
&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
&apos; SF_Utils
Const MISSINGARGERROR = &quot;MISSINGARGERROR&quot;
Const ARGUMENTERROR = &quot;ARGUMENTERROR&quot;
Const ARRAYERROR = &quot;ARRAYERROR&quot;
Const FILEERROR = &quot;FILEERROR&quot;
&apos; SF_Array
Const ARRAYSEQUENCEERROR = &quot;ARRAYSEQUENCEERROR&quot;
Const ARRAYINSERTERROR = &quot;ARRAYINSERTERROR&quot;
Const ARRAYINDEX1ERROR = &quot;ARRAYINDEX1ERROR&quot;
Const ARRAYINDEX2ERROR = &quot;ARRAYINDEX2ERROR&quot;
Const CSVPARSINGERROR = &quot;CSVPARSINGERROR&quot;
Const CSVOVERFLOWWARNING = &quot;CSVOVERFLOWWARNING&quot;
&apos; SF_Dictionary
Const DUPLICATEKEYERROR = &quot;DUPLICATEKEYERROR&quot;
Const UNKNOWNKEYERROR = &quot;UNKNOWNKEYERROR&quot;
Const INVALIDKEYERROR = &quot;INVALIDKEYERROR&quot;
&apos; SF_FileSystem
Const UNKNOWNFILEERROR = &quot;UNKNOWNFILEERROR&quot;
Const UNKNOWNFOLDERERROR = &quot;UNKNOWNFOLDERERROR&quot;
Const NOTAFILEERROR = &quot;NOTAFILEERROR&quot;
Const NOTAFOLDERERROR = &quot;NOTAFOLDERERROR&quot;
Const OVERWRITEERROR = &quot;OVERWRITEERROR&quot;
Const READONLYERROR = &quot;READONLYERROR&quot;
Const NOFILEMATCHERROR = &quot;NOFILEMATCHFOUND&quot;
Const FOLDERCREATIONERROR = &quot;FOLDERCREATIONERROR&quot;
Const FILESYSTEMERROR = &quot;FILESYSTEMERROR&quot;
&apos; SF_Services
Const UNKNOWNSERVICEERROR = &quot;UNKNOWNSERVICEERROR&quot;
Const SERVICESNOTLOADEDERROR = &quot;SERVICESNOTLOADEDERROR&quot;
&apos; SF_Session
Const CALCFUNCERROR = &quot;CALCFUNCERROR&quot;
Const NOSCRIPTERROR = &quot;NOSCRIPTERROR&quot;
Const SCRIPTEXECERROR = &quot;SCRIPTEXECERROR&quot;
Const WRONGEMAILERROR = &quot;WRONGEMAILERROR&quot;
Const SENDMAILERROR = &quot;SENDMAILERROR&quot;
&apos; SF_TextStream
Const FILENOTOPENERROR = &quot;FILENOTOPENERROR&quot;
Const FILEOPENMODEERROR = &quot;FILEOPENMODEERROR&quot;
Const ENDOFFILEERROR = &quot;ENDOFFILEERROR&quot;
&apos; SF_UI
Const DOCUMENTERROR = &quot;DOCUMENTERROR&quot;
Const DOCUMENTCREATIONERROR = &quot;DOCUMENTCREATIONERROR&quot;
Const DOCUMENTOPENERROR = &quot;DOCUMENTOPENERROR&quot;
Const BASEDOCUMENTOPENERROR = &quot;BASEDOCUMENTOPENERROR&quot;
&apos; SF_Document
Const DOCUMENTDEADERROR = &quot;DOCUMENTDEADERROR&quot;
Const DOCUMENTSAVEERROR = &quot;DOCUMENTSAVEERROR&quot;
Const DOCUMENTSAVEASERROR = &quot;DOCUMENTSAVEASERROR&quot;
Const DOCUMENTREADONLYERROR = &quot;DOCUMENTREADONLYERROR&quot;
Const DBCONNECTERROR = &quot;DBCONNECTERROR&quot;
&apos; SF_Calc
Const CALCADDRESSERROR = &quot;CALCADDRESSERROR&quot;
Const DUPLICATESHEETERROR = &quot;DUPLICATESHEETERROR&quot;
Const OFFSETADDRESSERROR = &quot;OFFSETADDRESSERROR&quot;
Const DUPLICATECHARTERROR = &quot;DUPLICATECHARTERROR&quot;
Const RANGEEXPORTERROR = &quot;RANGEEXPORTERROR&quot;
&apos; SF_Chart
Const CHARTEXPORTERROR = &quot;CHARTEXPORTERROR&quot;
&apos; SF_Form
Const FORMDEADERROR = &quot;FORMDEADERROR&quot;
Const CALCFORMNOTFOUNDERROR = &quot;CALCFORMNOTFOUNDERROR&quot;
Const WRITERFORMNOTFOUNDERROR = &quot;WRITERFORMNOTFOUNDERROR&quot;
Const BASEFORMNOTFOUNDERROR = &quot;BASEFORMNOTFOUNDERROR&quot;
Const SUBFORMNOTFOUNDERROR = &quot;SUBFORMNOTFOUNDERROR&quot;
Const FORMCONTROLTYPEERROR = &quot;FORMCONTROLTYPEERROR&quot;
&apos; SF_Dialog
Const DIALOGNOTFOUNDERROR = &quot;DIALOGNOTFOUNDERROR&quot;
Const DIALOGDEADERROR = &quot;DIALOGDEADERROR&quot;
Const CONTROLTYPEERROR = &quot;CONTROLTYPEERROR&quot;
Const TEXTFIELDERROR = &quot;TEXTFIELDERROR&quot;
Const PAGEMANAGERERROR = &quot;PAGEMANAGERERROR&quot;
Const DUPLICATECONTROLERROR = &quot;DUPLICATECONTROLERROR&quot;
&apos; SF_Database
Const DBREADONLYERROR = &quot;DBREADONLYERROR&quot;
Const SQLSYNTAXERROR = &quot;SQLSYNTAXERROR&quot;
Const SQLSYNTAX2ERROR = &quot;SQLSYNTAX2ERROR&quot;
Const NOCURRENTRECORDERROR = &quot;NOCURRENTRECORDERROR&quot;
Const RECORDUPDATEERROR = &quot;RECORDUPDATEERROR&quot;
Const FIELDEXPORTERROR = &quot;FIELDEXPORTERROR&quot;
&apos; Python
Const PYTHONSHELLERROR = &quot;PYTHONSHELLERROR&quot;
&apos; SF_UnitTest
Const UNITTESTLIBRARYERROR = &quot;UNITTESTLIBRARYERROR&quot;
Const UNITTESTMETHODERROR = &quot;UNITTESTMETHODERROR&quot;
REM ============================================================= PRIVATE MEMBERS
&apos; User defined errors
Private _Number As Variant &apos; Error number/code (Integer or String)
Private _Source As Variant &apos; Where the error occurred: a module, a Sub/Function, ...
Private _Description As String &apos; The error message
&apos; System run-time errors
Private _SysNumber As Long &apos; Alias of Err
Private _SysSource As Long &apos; Alias of Erl
Private _SysDescription As String &apos; Alias of Error$
REM ============================================================ MODULE CONSTANTS
Const RUNTIMEERRORS = 2000 &apos; Upper limit of Basic run-time errors
Const CONSOLENAME = &quot;ConsoleLines&quot; &apos; Name of control in the console dialog
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Public Function Dispose() As Variant
Set Dispose = Nothing
End Function &apos; ScriptForge.SF_Exception Explicit destructor
REM ================================================================== PROPERTIES
REM -----------------------------------------------------------------------------
Property Get Description() As Variant
&apos;&apos;&apos; Returns the description of the last error that has occurred
&apos;&apos;&apos; Example:
&apos;&apos;&apos; myException.Description
Description = _PropertyGet(&quot;Description&quot;)
End Property &apos; ScriptForge.SF_Exception.Description (get)
REM -----------------------------------------------------------------------------
Property Let Description(ByVal pvDescription As Variant)
&apos;&apos;&apos; Set the description of the last error that has occurred
&apos;&apos;&apos; Example:
&apos;&apos;&apos; myException.Description = &quot;Not smart to divide by zero&quot;
_PropertySet &quot;Description&quot;, pvDescription
End Property &apos; ScriptForge.SF_Exception.Description (let)
REM -----------------------------------------------------------------------------
Property Get Number() As Variant
&apos;&apos;&apos; Returns the code of the last error that has occurred
&apos;&apos;&apos; Example:
&apos;&apos;&apos; myException.Number
Number = _PropertyGet(&quot;Number&quot;)
End Property &apos; ScriptForge.SF_Exception.Number (get)
REM -----------------------------------------------------------------------------
Property Let Number(ByVal pvNumber As Variant)
&apos;&apos;&apos; Set the code of the last error that has occurred
&apos;&apos;&apos; Example:
&apos;&apos;&apos; myException.Number = 11 &apos; Division by 0
_PropertySet &quot;Number&quot;, pvNumber
End Property &apos; ScriptForge.SF_Exception.Number (let)
REM -----------------------------------------------------------------------------
Property Get Source() As Variant
&apos;&apos;&apos; Returns the location of the last error that has occurred
&apos;&apos;&apos; Example:
&apos;&apos;&apos; myException.Source
Source = _PropertyGet(&quot;Source&quot;)
End Property &apos; ScriptForge.SF_Exception.Source (get)
REM -----------------------------------------------------------------------------
Property Let Source(ByVal pvSource As Variant)
&apos;&apos;&apos; Set the location of the last error that has occurred
&apos;&apos;&apos; Example:
&apos;&apos;&apos; myException.Source = 123 &apos; Line # 123. Source may also be a string
_PropertySet &quot;Source&quot;, pvSource
End Property &apos; ScriptForge.SF_Exception.Source (let)
REM -----------------------------------------------------------------------------
Property Get ObjectType As String
&apos;&apos;&apos; Only to enable object representation
ObjectType = &quot;SF_Exception&quot;
End Property &apos; ScriptForge.SF_String.ObjectType
REM -----------------------------------------------------------------------------
Property Get ServiceName As String
&apos;&apos;&apos; Internal use
ServiceName = &quot;ScriptForge.Exception&quot;
End Property &apos; ScriptForge.SF_Exception.ServiceName
REM ===================================================================== METHODS
REM -----------------------------------------------------------------------------
Public Sub Clear()
&apos;&apos;&apos; Reset the current error status and clear the SF_Exception object
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; On Local Error GoTo Catch
&apos;&apos;&apos; &apos; ...
&apos;&apos;&apos; Catch:
&apos;&apos;&apos; SF_Exception.Clear() &apos; Deny the error
Const cstThisSub = &quot;Exception.Clear&quot;
Const cstSubArgs = &quot;&quot;
Check:
Try:
With SF_Exception
._Number = Empty
._Source = Empty
._Description = &quot;&quot;
._SysNumber = 0
._SysSource = 0
._SysDescription = &quot;&quot;
End With
Finally:
On Error GoTo 0
Exit Sub
Catch:
GoTo Finally
End Sub &apos; ScriptForge.SF_Exception.Clear
REM -----------------------------------------------------------------------------
Public Sub Console(Optional ByVal Modal As Variant, _
Optional ByRef _Context As Variant _
)
&apos;&apos;&apos; Display the console messages in a modal or non-modal dialog
&apos;&apos;&apos; If the dialog is already active, when non-modal, it is brought to front
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Modal: Boolean. Default = True
&apos;&apos;&apos; _Context: From Python, the XComponentXontext (FOR INTERNAL USE ONLY)
&apos;&apos;&apos; Example:
&apos;&apos;&apos; SF_Exception.Console()
Dim bConsoleActive As Boolean &apos; When True, dialog is active
Dim oModalBtn As Object &apos; Modal close button
Dim oNonModalBtn As Object &apos; Non modal close button
Const cstThisSub = &quot;Exception.Console&quot;
Const cstSubArgs = &quot;[Modal=True]&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Finally &apos; Never interrupt processing
Check:
If IsMissing(Modal) Or IsEmpty(Modal) Then Modal = True
If IsMissing(_Context) Or IsEmpty(_Context) Then _Context = Nothing
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Modal, &quot;Modal&quot;, V_BOOLEAN) Then GoTo Finally
End If
Try:
With _SF_
bConsoleActive = False
If Not IsNull(.ConsoleDialog) Then bConsoleActive = .ConsoleDialog._IsStillAlive(False) &apos; False to not raise an error
If bConsoleActive And Modal = False Then
&apos; Bring to front
.ConsoleDialog.Activate()
Else
&apos; Initialize dialog and fill with actual data
&apos; The dual modes (modal and non-modal) require to have 2 close buttons o/w only 1 is visible
&apos; - a usual OK button
&apos; - a Default button triggering the Close action
Set .ConsoleDialog = CreateScriptService(&quot;SFDialogs.Dialog&quot;, &quot;GlobalScope&quot;, &quot;ScriptForge&quot;, &quot;dlgConsole&quot;, _Context)
&apos; Setup labels and visibility
Set oModalBtn = .ConsoleDialog.Controls(&quot;CloseModalButton&quot;)
Set oNonModalBtn = .ConsoleDialog.Controls(&quot;CloseNonModalButton&quot;)
oModalBtn.Visible = Modal
oNonModalBtn.Visible = CBool(Not Modal)
&apos; Load console lines
_ConsoleRefresh()
.ConsoleDialog.Execute(Modal)
&apos; Terminate the modal dialog
If Modal Then
Set .ConsoleControl = .ConsoleControl.Dispose()
Set .ConsoleDialog = .ConsoleDialog.Dispose()
End If
End If
End With
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Sub
End Sub &apos; ScriptForge.SF_Exception.Console
REM -----------------------------------------------------------------------------
Public Sub ConsoleClear(Optional ByVal Keep)
&apos;&apos;&apos; Clear the console keeping an optional number of recent messages
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Keep: the number of messages to keep
&apos;&apos;&apos; If Keep is bigger than the number of messages stored in the console,
&apos;&apos;&apos; the console is not cleared
&apos;&apos;&apos; Example:
&apos;&apos;&apos; SF_Exception.ConsoleClear(5)
Dim lConsole As Long &apos; UBound of ConsoleLines
Const cstThisSub = &quot;Exception.ConsoleClear&quot;
Const cstSubArgs = &quot;[Keep=0]&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Finally &apos; Never interrupt processing
Check:
If IsMissing(Keep) Or IsEmpty(Keep) Then Keep = 0
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Keep, &quot;Keep&quot;, V_NUMERIC) Then GoTo Finally
End If
Try:
With _SF_
If Keep &lt;= 0 Then
.ConsoleLines = Array()
Else
lConsole = UBound(.ConsoleLines)
If Keep &lt; lConsole + 1 Then .ConsoleLines = SF_Array.Slice(.ConsoleLines, lConsole - Keep + 1)
End If
End With
&apos; If active, the console dialog needs to be refreshed
_ConsoleRefresh()
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Sub
End Sub &apos; ScriptForge.SF_Exception.ConsoleClear
REM -----------------------------------------------------------------------------
Public Function ConsoleToFile(Optional ByVal FileName As Variant) As Boolean
&apos;&apos;&apos; Export the content of the console to a text file
&apos;&apos;&apos; If the file exists and the console is not empty, it is overwritten without warning
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName: the complete file name to export to. If it exists, is overwritten without warning
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if the file could be created
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; SF_Exception.ConsoleToFile(&quot;myFile.txt&quot;)
Dim bExport As Boolean &apos; Return value
Dim oFile As Object &apos; Output file handler
Dim sLine As String &apos; A single line
Const cstThisSub = &quot;Exception.ConsoleToFile&quot;
Const cstSubArgs = &quot;FileName&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bExport = False
Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
End If
Try:
If UBound(_SF_.ConsoleLines) &gt; -1 Then
Set oFile = SF_FileSystem.CreateTextFile(FileName, Overwrite := True)
If Not IsNull(oFile) Then
With oFile
For Each sLine In _SF_.ConsoleLines
.WriteLine(sLine)
Next sLine
.CloseFile()
End With
End If
bExport = True
End If
Finally:
If Not IsNull(oFile) Then Set oFile = oFile.Dispose()
ConsoleToFile = bExport
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_Exception.ConsoleToFile
REM -----------------------------------------------------------------------------
Public Sub DebugDisplay(ParamArray pvArgs() As Variant)
&apos;&apos;&apos; Display the list of arguments in a readable form in a message box
&apos;&apos;&apos; Arguments are separated by a LINEFEED character
&apos;&apos;&apos; The maximum length of each individual argument = 1024 characters
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Any number of arguments of any type
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; SF_Exception.DebugDisplay(a, Array(1, 2, 3), , &quot;line1&quot; &amp; Chr(10) &amp; &quot;Line2&quot;, DateSerial(2020, 04, 09))
Dim sOutputMsg As String &apos; Line to display
Dim sOutputCon As String &apos; Line to write in console
Dim sArgMsg As String &apos; Single argument
Dim sArgCon As String &apos; Single argument
Dim i As Integer
Const cstTab = 4
Const cstMaxLength = 1024
Const cstThisSub = &quot;Exception.DebugDisplay&quot;
Const cstSubArgs = &quot;Arg0, [Arg1, ...]&quot;
If SF_Utils._ErrorHandling() Then On Local Error Goto Finally &apos; Never interrupt processing
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
&apos; Build new console line
sOutputMsg = &quot;&quot; : sOutputCon = &quot;&quot;
For i = 0 To UBound(pvArgs)
If IsError(pvArgs(i)) Then pvArgs(i) = &quot;&quot;
sArgMsg = Iif(i = 0, &quot;&quot;, SF_String.sfNEWLINE) &amp; SF_Utils._Repr(pvArgs(i), cstMaxLength) &apos;Do not use SF_String.Represent()
sArgCon = Iif(i = 0, &quot;&quot;, SF_String.sfTAB) &amp; SF_Utils._Repr(pvArgs(i), cstMaxLength)
sOutputMsg = sOutputMsg &amp; sArgMsg
sOutputCon = sOutputCon &amp; sArgCon
Next i
&apos; Add to actual console
_SF_._AddToConsole(SF_String.ExpandTabs(sOutputCon, cstTab))
&apos; Display the message
MsgBox(sOutputMsg, MB_OK + MB_ICONINFORMATION, &quot;DebugDisplay&quot;)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Sub
End Sub &apos; ScriptForge.SF_Exception.DebugDisplay
REM -----------------------------------------------------------------------------
Public Sub DebugPrint(ParamArray pvArgs() As Variant)
&apos;&apos;&apos; Print the list of arguments in a readable form in the console
&apos;&apos;&apos; Arguments are separated by a TAB character (simulated by spaces)
&apos;&apos;&apos; The maximum length of each individual argument = 1024 characters
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Any number of arguments of any type
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; SF_Exception.DebugPrint(a, Array(1, 2, 3), , &quot;line1&quot; &amp; Chr(10) &amp; &quot;Line2&quot;, DateSerial(2020, 04, 09))
Dim sOutput As String &apos; Line to write in console
Dim sArg As String &apos; Single argument
Dim i As Integer
Const cstTab = 4
Const cstMaxLength = 1024
Const cstThisSub = &quot;Exception.DebugPrint&quot;
Const cstSubArgs = &quot;Arg0, [Arg1, ...]&quot;
If SF_Utils._ErrorHandling() Then On Local Error Goto Finally &apos; Never interrupt processing
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
&apos; Build new console line
sOutput = &quot;&quot;
For i = 0 To UBound(pvArgs)
If IsError(pvArgs(i)) Then pvArgs(i) = &quot;&quot;
sArg = Iif(i = 0, &quot;&quot;, SF_String.sfTAB) &amp; SF_Utils._Repr(pvArgs(i), cstMaxLength) &apos;Do not use SF_String.Represent()
sOutput = sOutput &amp; sArg
Next i
&apos; Add to actual console
_SF_._AddToConsole(SF_String.ExpandTabs(sOutput, cstTab))
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Sub
End Sub &apos; ScriptForge.SF_Exception.DebugPrint
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; If the property does not exist, returns Null
&apos;&apos;&apos; Exceptions
&apos;&apos;&apos; ARGUMENTERROR The property does not exist
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; myException.GetProperty(&quot;MyProperty&quot;)
Const cstThisSub = &quot;Exception.GetProperty&quot;
Const cstSubArgs = &quot;&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
GetProperty = Null
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:
GetProperty = _PropertyGet(PropertyName)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_Exception.GetProperty
REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
&apos;&apos;&apos; Return the list of public methods of the Exception service as an array
Methods = Array( _
&quot;Clear&quot; _
, &quot;Console&quot; _
, &quot;ConsoleClear&quot; _
, &quot;ConsoleToFile&quot; _
, &quot;DebugPrint&quot; _
, &quot;Raise&quot; _
, &quot;RaiseAbort&quot; _
, &quot;RaiseFatal&quot; _
, &quot;RaiseWarning&quot; _
)
End Function &apos; ScriptForge.SF_Exception.Methods
REM -----------------------------------------------------------------------------
Public Function Properties() As Variant
&apos;&apos;&apos; Return the list or properties of the Timer class as an array
Properties = Array( _
&quot;Description&quot; _
, &quot;Number&quot; _
, &quot;Source&quot; _
)
End Function &apos; ScriptForge.SF_Exception.Properties
REM -----------------------------------------------------------------------------
Public Sub PythonPrint(ParamArray pvArgs() As Variant)
&apos;&apos;&apos; Display the list of arguments in a readable form in the Python console
&apos;&apos;&apos; Arguments are separated by a TAB character (simulated by spaces)
&apos;&apos;&apos; The maximum length of each individual argument = 1024 characters
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Any number of arguments of any type
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; SF_Exception.PythonPrint(a, Array(1, 2, 3), , &quot;line1&quot; &amp; Chr(10) &amp; &quot;Line2&quot;, DateSerial(2020, 04, 09))
Dim sOutput As String &apos; Line to write in console
Dim sArg As String &apos; Single argument
Dim i As Integer
Const cstTab = 4
Const cstMaxLength = 1024
Const cstPyHelper = &quot;$&quot; &amp; &quot;_SF_Exception__PythonPrint&quot;
Const cstThisSub = &quot;Exception.PythonPrint&quot;
Const cstSubArgs = &quot;Arg0, [Arg1, ...]&quot;
If SF_Utils._ErrorHandling() Then On Local Error Goto Finally &apos; Never interrupt processing
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
&apos; Build new console line
sOutput = &quot;&quot;
For i = 0 To UBound(pvArgs)
If IsError(pvArgs(i)) Then pvArgs(i) = &quot;&quot;
sArg = Iif(i = 0, &quot;&quot;, SF_String.sfTAB) &amp; SF_Utils._Repr(pvArgs(i), cstMaxLength)
sOutput = sOutput &amp; sArg
Next i
&apos; Add to actual console
sOutput = SF_String.ExpandTabs(sOutput, cstTab)
_SF_._AddToConsole(sOutput)
&apos; Display the message in the Python shell console
With ScriptForge.SF_Session
.ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper &amp; cstPyHelper, sOutput)
End With
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Sub
End Sub &apos; ScriptForge.SF_Exception.PythonPrint
REM -----------------------------------------------------------------------------
Public Sub Raise(Optional ByVal Number As Variant _
, Optional ByVal Source As Variant _
, Optional ByVal Description As Variant _
)
&apos;&apos;&apos; Generate a run-time error. An error message is displayed to the user and logged
&apos;&apos;&apos; in the console. The execution is STOPPED
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Number: the error number, may be numeric or string
&apos;&apos;&apos; If numeric and &lt;= 2000, it is considered a LibreOffice Basic run-time error (default = Err)
&apos;&apos;&apos; Source: the line where the error occurred (default = Erl) or any string describing the location of the error
&apos;&apos;&apos; Description: the error message to log in the console and to display to the user
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; On Local Error GoTo Catch
&apos;&apos;&apos; &apos; ...
&apos;&apos;&apos; Catch:
&apos;&apos;&apos; SF_Exception.Raise() &apos; Standard behaviour
&apos;&apos;&apos; SF_Exception.Raise(11) &apos; Force division by zero
&apos;&apos;&apos; SF_Exception.Raise(&quot;MYAPPERROR&quot;, &quot;myFunction&quot;, &quot;Application error&quot;)
&apos;&apos;&apos; SF_Exception.Raise(,, &quot;To divide by zero is not a good idea !&quot;)
Dim sMessage As String &apos; Error message to log and to display
Dim L10N As Object &apos; Alias to LocalizedInterface
Const cstThisSub = &quot;Exception.Raise&quot;
Const cstSubArgs = &quot;[Number=Err], [Source=Erl], [Description]&quot;
&apos; Save Err, Erl, .. values before any On Error ... statement
SF_Exception._CaptureSystemError()
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(Number) Or IsEmpty(Number) Then Number = -1
If IsMissing(Source) Or IsEmpty(Source) Then Source = -1
If IsMissing(Description) Or IsEmpty(Description) Then Description = &quot;&quot;
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Number, &quot;Number&quot;, Array(V_STRING, V_NUMERIC)) Then GoTo Finally
If Not SF_Utils._Validate(Source, &quot;Source&quot;, Array(V_STRING, V_NUMERIC)) Then GoTo Finally
If Not SF_Utils._Validate(Description, &quot;Description&quot;, V_STRING) Then GoTo Finally
End If
Try:
With SF_Exception
If Number &gt;= 0 Then .Number = Number
If VarType(Source) = V_STRING Then
If Len(Source) &gt; 0 Then .Source = Source
ElseIf Source &gt;= 0 Then &apos; -1 = Default =&gt; no change
.Source = Source
End If
If Len(Description) &gt; 0 Then .Description = Description
&apos; Log and display
Set L10N = _SF_._GetLocalizedInterface()
sMessage = L10N.GetText(&quot;LONGERRORDESC&quot;, .Number, .Source, .Description)
.DebugPrint(sMessage)
If _SF_.DisplayEnabled Then MsgBox L10N.GetText(&quot;ERRORNUMBER&quot;, .Number) _
&amp; SF_String.sfNewLine &amp; L10N.GetText(&quot;ERRORLOCATION&quot;, .Source) _
&amp; SF_String.sfNewLine &amp; .Description _
, MB_OK + MB_ICONSTOP _
, L10N.GetText(&quot;ERRORNUMBER&quot;, .Number)
.Clear()
End With
Finally:
SF_Utils._ExitFunction(cstThisSub)
If _SF_.StopWhenError Then
_SF_._StackReset()
Stop
End If
Exit Sub
Catch:
GoTo Finally
End Sub &apos; ScriptForge.SF_Exception.Raise
REM -----------------------------------------------------------------------------
Public Sub RaiseAbort(Optional ByVal Source As Variant)
&apos;&apos;&apos; Manage a run-time error that occurred inside the ScriptForge piece of software itself.
&apos;&apos;&apos; The event is logged.
&apos;&apos;&apos; The execution is STOPPED
&apos;&apos;&apos; For INTERNAL USE only
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Source: the line where the error occurred
Dim sLocation As String &apos; Common header in error messages: location of error
Dim vLocation As Variant &apos; Split array (library, module, method)
Dim sMessage As String &apos; Error message to log and to display
Dim L10N As Object &apos; Alias to LocalizedInterface
Const cstTabSize = 4
Const cstThisSub = &quot;Exception.RaiseAbort&quot;
Const cstSubArgs = &quot;[Source=Erl]&quot;
&apos; Save Err, Erl, .. values before any On Error ... statement
SF_Exception._CaptureSystemError()
On Local Error Resume Next
Check:
If IsMissing(Source) Or IsEmpty(Source) Then Source = &quot;&quot;
Try:
With SF_Exception
&apos; Prepare message header
Set L10N = _SF_._GetLocalizedInterface()
If Len(_SF_.MainFunction) &gt; 0 Then &apos; MainFunction = [Library.]Module.Method
vLocation = Split(_SF_.MainFunction, &quot;.&quot;)
If UBound(vLocation) &lt; 2 Then vLocation = SF_Array.Prepend(vLocation, &quot;ScriptForge&quot;)
sLocation = L10N.GetText(&quot;VALIDATESOURCE&quot;, vLocation(0), vLocation(1), vLocation(2)) &amp; &quot;\n\n\n&quot;
Else
sLocation = &quot;&quot;
End If
&apos; Log and display
sMessage = L10N.GetText(&quot;LONGERRORDESC&quot;, .Number, .Source, .Description)
.DebugPrint(sMessage)
If _SF_.DisplayEnabled Then
sMessage = sLocation _
&amp; L10N.GetText(&quot;INTERNALERROR&quot;) _
&amp; L10N.GetText(&quot;ERRORLOCATION&quot;, Source &amp; &quot;/&quot; &amp; .Source) &amp; SF_String.sfNewLine &amp; .Description _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; L10N.GetText(&quot;STOPEXECUTION&quot;)
MsgBox SF_String.ExpandTabs(SF_String.Unescape(sMessage), cstTabSize) _
, MB_OK + MB_ICONSTOP _
, L10N.GetText(&quot;ERRORNUMBER&quot;, .Number)
End If
.Clear()
End With
Finally:
_SF_._StackReset()
If _SF_.StopWhenError Then Stop
Exit Sub
Catch:
GoTo Finally
End Sub &apos; ScriptForge.SF_Exception.RaiseAbort
REM -----------------------------------------------------------------------------
Public Sub RaiseFatal(Optional ByVal ErrorCode As Variant _
, ParamArray pvArgs _
)
&apos;&apos;&apos; Generate a run-time error caused by an anomaly in a user script detected by ScriptForge
&apos;&apos;&apos; The message is logged in the console. The execution is STOPPED
&apos;&apos;&apos; For INTERNAL USE only
&apos;&apos;&apos; Args:
&apos;&apos;&apos; ErrorCode: as a string, the unique identifier of the error
&apos;&apos;&apos; pvArgs: the arguments to insert in the error message
Dim sLocation As String &apos; Common header in error messages: location of error
Dim sService As String &apos; Service name having detected the error
Dim sMethod As String &apos; Method name having detected the error
Dim vLocation As Variant &apos; Split array (library, module, method)
Dim sMessage As String &apos; Message to log and display
Dim L10N As Object &apos; Alias of LocalizedInterface
Dim sAlt As String &apos; Alternative error messages
Dim iButtons As Integer &apos; MB_OK or MB_YESNO
Dim iMsgBox As Integer &apos; Return value of the message box
Const cstTabSize = 4
Const cstThisSub = &quot;Exception.RaiseFatal&quot;
Const cstSubArgs = &quot;ErrorCode, [Arg0[, Arg1 ...]]&quot;
Const cstStop = &quot;&quot; &apos; Chr(9211)
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(ErrorCode) Or IsEmpty(ErrorCode) Then ErrorCode = &quot;&quot;
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(ErrorCode, &quot;ErrorCode&quot;, V_STRING) Then GoTo Finally
End If
Try:
Set L10N = _SF_._GetLocalizedInterface()
&apos; Location header common to all error messages
If Len(_SF_.MainFunction) &gt; 0 Then &apos; MainFunction = [Library.]Module.Method
vLocation = Split(_SF_.MainFunction, &quot;.&quot;)
If UBound(vLocation) &lt; 2 Then vLocation = SF_Array.Prepend(vLocation, &quot;ScriptForge&quot;)
sService = vLocation(1)
sMethod = vLocation(2)
sLocation = L10N.GetText(&quot;VALIDATESOURCE&quot;, vLocation(0), sService, sMethod) _
&amp; &quot;\n&quot; &amp; L10N.GetText(&quot;VALIDATEARGS&quot;, _RightCaseArgs(_SF_.MainFunctionArgs))
Else
sService = &quot;&quot;
sMethod = &quot;&quot;
sLocation = &quot;&quot;
End If
With L10N
Select Case UCase(ErrorCode)
Case MISSINGARGERROR &apos; SF_Utils._Validate(Name)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEMISSING&quot;, pvArgs(0))
Case ARGUMENTERROR &apos; SF_Utils._Validate(Value, Name, Types, Values, Regex, Class)
pvArgs(1) = _RightCase(pvArgs(1))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(1)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATIONRULES&quot;)
If Len(pvArgs(2)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATETYPES&quot;, pvArgs(1), pvArgs(2))
If Len(pvArgs(3)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEVALUES&quot;, pvArgs(1), pvArgs(3))
If Len(pvArgs(4)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEREGEX&quot;, pvArgs(1), pvArgs(4))
If Len(pvArgs(5)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATECLASS&quot;, pvArgs(1), pvArgs(5))
sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEACTUAL&quot;, pvArgs(1), pvArgs(0))
Case ARRAYERROR &apos; SF_Utils._ValidateArray(Value, Name, Dimensions, Types, NotNull)
pvArgs(1) = _RightCase(pvArgs(1))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(1)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATIONRULES&quot;) _
&amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEARRAY&quot;, pvArgs(1))
If pvArgs(2) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEDIMS&quot;, pvArgs(1), pvArgs(2))
If Len(pvArgs(3)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEALLTYPES&quot;, pvArgs(1), pvArgs(3))
If pvArgs(4) Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATENOTNULL&quot;, pvArgs(1))
sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEACTUAL&quot;, pvArgs(1), pvArgs(0))
Case FILEERROR &apos; SF_Utils._ValidateFile(Value, Name, WildCards)
pvArgs(1) = _RightCase(pvArgs(1))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(1)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATIONRULES&quot;) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEFILE&quot;, pvArgs(1))
sAlt = &quot;VALIDATEFILE&quot; &amp; SF_FileSystem.FileNaming
sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(sAlt, pvArgs(1))
If pvArgs(2) Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEWILDCARD&quot;, pvArgs(1))
sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEACTUAL&quot;, pvArgs(1), pvArgs(0))
Case ARRAYSEQUENCEERROR &apos; SF_Array.RangeInit(From, UpTo, ByStep)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYSEQUENCE&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case ARRAYINSERTERROR &apos; SF_Array.AppendColumn/Row/PrependColumn/Row(VectorName, Array_2D, Vector)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYINSERT&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case ARRAYINDEX1ERROR &apos; SF_Array.ExtractColumn/Row(IndexName, Array_2D, Index)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYINDEX1&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case ARRAYINDEX2ERROR &apos; SF_Array.Slice(From, UpTo)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYINDEX2&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case CSVPARSINGERROR &apos; SF_Array.ImportFromCSVFile(FileName, LineNumber, Line)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CSVPARSING&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case DUPLICATEKEYERROR &apos; SF_Dictionary.Add/ReplaceKey(&quot;Key&quot;, Key)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DUPLICATEKEY&quot;, pvArgs(0), pvArgs(1))
Case UNKNOWNKEYERROR &apos; SF_Dictionary.Remove/ReplaceItem/ReplaceKey(&quot;Key&quot;, Key)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNKEY&quot;, pvArgs(0), pvArgs(1))
Case INVALIDKEYERROR &apos; SF_Dictionary.Add/ReplaceKey(Key)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;INVALIDKEY&quot;)
Case UNKNOWNFILEERROR &apos; SF_FileSystem.CopyFile/MoveFile/DeleteFile/CreateScriptService(&quot;L10N&quot;)(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNFILE&quot;, pvArgs(0), pvArgs(1))
Case UNKNOWNFOLDERERROR &apos; SF_FileSystem.CopyFolder/MoveFolder/DeleteFolder/Files/SubFolders(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNFOLDER&quot;, pvArgs(0), pvArgs(1))
Case NOTAFILEERROR &apos; SF_FileSystem.CopyFile/MoveFile/DeleteFile(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOTAFILE&quot;, pvArgs(0), pvArgs(1))
Case NOTAFOLDERERROR &apos; SF_FileSystem.CopyFolder/MoveFolder/DeleteFolder/Files/SubFolders(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOTAFOLDER&quot;, pvArgs(0), pvArgs(1))
Case OVERWRITEERROR &apos; SF_FileSystem.Copy+Move/File+Folder/CreateTextFile/OpenTextFile(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;OVERWRITE&quot;, pvArgs(0), pvArgs(1))
Case READONLYERROR &apos; SF_FileSystem.Copy+Move+Delete/File+Folder(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;READONLY&quot;, pvArgs(0), pvArgs(1))
Case NOFILEMATCHERROR &apos; SF_FileSystem.Copy+Move+Delete/File+Folder(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOFILEMATCH&quot;, pvArgs(0), pvArgs(1))
Case FOLDERCREATIONERROR &apos; SF_FileSystem.CreateFolder(ArgName, Filename)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FOLDERCREATION&quot;, pvArgs(0), pvArgs(1))
Case FILESYSTEMERROR &apos; SF_FileSystem.---(ArgName, MethodName, ArgValue)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FILESYSTEM&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case UNKNOWNSERVICEERROR &apos; SF_Services.CreateScriptService(ArgName, Value, Library, Service)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNSERVICE&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case SERVICESNOTLOADEDERROR &apos; SF_Services.CreateScriptService(ArgName, Value, Library)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SERVICESNOTLOADED&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case CALCFUNCERROR &apos; SF_Session.ExecuteCalcFunction(CalcFunction)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, _RightCase(&quot;CalcFunction&quot;)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CALCFUNC&quot;, pvArgs(0))
Case NOSCRIPTERROR &apos; SF_Session._GetScript(Language, &quot;Scope&quot;, Scope, &quot;Script&quot;, Script)
pvArgs(1) = _RightCase(pvArgs(1)) : pvArgs(3) = _RightCase(pvArgs(3))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, _RightCase(&quot;Script&quot;)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOSCRIPT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4))
Case SCRIPTEXECERROR &apos; SF_Session.ExecuteBasicScript(&quot;Script&quot;, Script, Cause)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SCRIPTEXEC&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case WRONGEMAILERROR &apos; SF_Session.SendMail(Arg, Email)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;WRONGEMAIL&quot;, pvArgs(1))
Case SENDMAILERROR &apos; SF_Session.SendMail()
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SENDMAIL&quot;)
Case FILENOTOPENERROR &apos; SF_TextStream._IsFileOpen(FileName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FILENOTOPEN&quot;, pvArgs(0))
Case FILEOPENMODEERROR &apos; SF_TextStream._IsFileOpen(FileName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FILEOPENMODE&quot;, pvArgs(0), pvArgs(1))
Case ENDOFFILEERROR &apos; SF_TextStream.ReadLine/ReadAll/SkipLine(FileName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ENDOFFILE&quot;, pvArgs(0))
Case DOCUMENTERROR &apos; SF_UI.GetDocument(ArgName, WindowName)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENT&quot;, pvArgs(0), pvArgs(1))
Case DOCUMENTCREATIONERROR &apos; SF_UI.Create(Arg1Name, DocumentType, Arg2Name, TemplateFile)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTCREATION&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case DOCUMENTOPENERROR &apos; SF_UI.OpenDocument(Arg1Name, FileName, Arg2Name, Password, Arg3Name, FilterName)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2)) : pvArgs(4) = _RightCase(pvArgs(4))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTOPEN&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4), pvArgs(5))
Case BASEDOCUMENTOPENERROR &apos; SF_UI.OpenBaseDocument(Arg1Name, FileName, Arg2Name, RegistrationName)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;BASEDOCUMENTOPEN&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case DOCUMENTDEADERROR &apos; SF_Document._IsStillAlive(FileName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTDEAD&quot;, pvArgs(0))
Case DOCUMENTSAVEERROR &apos; SF_Document.Save(Arg1Name, FileName)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTSAVE&quot;, pvArgs(0), pvArgs(1))
Case DOCUMENTSAVEASERROR &apos; SF_Document.SaveAs(Arg1Name, FileName, Arg2, Overwrite, Arg3, FilterName)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2)) : pvArgs(4) = _RightCase(pvArgs(4))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTSAVEAS&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4), pvArgs(5))
Case DOCUMENTREADONLYERROR &apos; SF_Document.update property(&quot;Document&quot;, FileName)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTREADONLY&quot;, pvArgs(0), pvArgs(1))
Case DBCONNECTERROR &apos; SF_Base.GetDatabase(&quot;User&quot;, User, &quot;Password&quot;, Password, FileName)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DBCONNECT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4))
Case CALCADDRESSERROR &apos; SF_Calc._ParseAddress(Address, &quot;Range&quot;/&quot;Sheet&quot;, Scope, Document)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CALCADDRESS&quot; &amp; Iif(Left(pvArgs(0), 5) = &quot;Sheet&quot;, &quot;1&quot;, &quot;2&quot;), pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case DUPLICATESHEETERROR &apos; SF_Calc.InsertSheet(arg, SheetName, Document)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DUPLICATESHEET&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case OFFSETADDRESSERROR &apos; SF_Calc.RangeOffset(&quot;Range&quot;, Range, &quot;Rows&quot;, Rows, &quot;Columns&quot;, Columns, &quot;Height&quot;, Height, &quot;Width&quot;, Width, &quot;Document, Document)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2)) : pvArgs(4) = _RightCase(pvArgs(4))
pvArgs(6) = _RightCase(pvArgs(6)) : pvArgs(8) = _RightCase(pvArgs(8)) : pvArgs(10) = _RightCase(pvArgs(10))
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 DUPLICATECHARTERROR &apos; SF_Calc.CreateChart(chart, ChartName, sheet, SheetName, Document, file)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DUPLICATECHART&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4), pvArgs(5))
Case RANGEEXPORTERROR &apos; SF_Calc.ExportRangeToFile(Arg1Name, FileName, Arg2, Overwrite)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;RANGEEXPORT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case CHARTEXPORTERROR &apos; SF_Chart.ExportToFile(Arg1Name, FileName, Arg2, Overwrite)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CHARTEXPORT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
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 SUBFORMNOTFOUNDERROR &apos; SF_Form.Subforms(Subform, Mainform)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SUBFORMNOTFOUND&quot;, pvArgs(0), pvArgs(1))
Case FORMCONTROLTYPEERROR &apos; SF_FormControl._SetProperty(ControlName, FormName, ControlType, Property)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FORMCONTROLTYPE&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case DIALOGNOTFOUNDERROR &apos; SF_Dialog._NewDialog(Service, DialogName, WindowName)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2)) : pvArgs(4) = _RightCase(pvArgs(4))
pvArgs(6) = _RightCase(pvArgs(6))
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) _
, pvArgs(5), pvArgs(6), pvArgs(7))
Case DIALOGDEADERROR &apos; SF_Dialog._IsStillAlive(DialogName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DIALOGDEAD&quot;, pvArgs(0))
Case CONTROLTYPEERROR &apos; SF_DialogControl._SetProperty(ControlName, DialogName, ControlType, Property)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CONTROLTYPE&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case TEXTFIELDERROR &apos; SF_DialogControl.WriteLine(ControlName, DialogName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;TEXTFIELD&quot;, pvArgs(0), pvArgs(1))
Case PAGEMANAGERERROR &apos; SF_Dialog.SetPageManager(PilotsList, TabsList, WizardsList)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;PAGEMANAGER&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4), pvArgs(5))
Case DUPLICATECONTROLERROR &apos; SF_Dialog.CreateControl(ControlName, DialogName)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DUPLICATECONTROL&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case DBREADONLYERROR &apos; SF_Database.RunSql(), SF_Dataset.Delete(), Insert(), Update()
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DBREADONLY&quot;, vLocation(2))
Case SQLSYNTAXERROR &apos; SF_Database._ExecuteSql(SQL)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SQLSYNTAX&quot;, pvArgs(0))
Case SQLSYNTAX2ERROR &apos; SF_Dataset.Reload/_Initialize(SQL, Filter, OrderBy)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SQLSYNTAX2&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case NOCURRENTRECORDERROR &apos; SF_Dataset.Insert/Update/GetValue/Delete
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOCURRENTRECORD&quot;)
Case RECORDUPDATEERROR &apos; SF_Dataset.Insert/Update(FieldName, FieldValue, FieldType)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;RECORDUPDATE&quot;, pvArgs(0), pvArgs(1), pvARgs(2))
Case FIELDEXPORTERROR &apos; SF_Dataset.ExportFieldToFile(Arg1Name, FileName, Arg2, Overwrite)
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FIELDEXPORT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case PYTHONSHELLERROR &apos; SF_Exception.PythonShell (Python only)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;PYTHONSHELL&quot;)
Case UNITTESTLIBRARYERROR &apos; SFUnitTests._NewUnitTest(LibraryName)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNITTESTLIBRARY&quot;, pvArgs(0))
Case UNITTESTMETHODERROR &apos; SFUnitTests.SF_UnitTest(Method)
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNITTESTMETHOD&quot;, pvArgs(0))
Case Else
End Select
End With
&apos; Log fatal event
_SF_._AddToConsole(sMessage)
&apos; Display fatal event, if relevant (default)
If _SF_.DisplayEnabled Then
If _SF_.StopWhenError Then sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; L10N.GetText(&quot;STOPEXECUTION&quot;)
&apos; Do you need more help ?
If Len(sMethod) &gt; 0 Then
sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; L10N.GetText(&quot;NEEDMOREHELP&quot;, sMethod)
iButtons = MB_YESNO + MB_DEFBUTTON2
Else
iButtons = MB_OK
End If
iMsgBox = MsgBox(SF_String.ExpandTabs(SF_String.Unescape(sMessage), cstTabSize) _
, iButtons + MB_ICONEXCLAMATION _
, L10N.GetText(&quot;ERRORNUMBER&quot;, ErrorCode) _
)
&apos; If more help needed ...
If iMsgBox = IDYES Then _OpenHelpInBrowser(sService, sMethod)
End If
Finally:
SF_Utils._ExitFunction(cstThisSub)
_SF_._StackReset()
If _SF_.StopWhenError Then Stop
Exit Sub
Catch:
GoTo Finally
End Sub &apos; ScriptForge.SF_Exception.RaiseFatal
REM -----------------------------------------------------------------------------
Public Sub RaiseWarning(Optional ByVal Number As Variant _
, Optional ByVal Source As Variant _
, Optional ByVal Description As Variant _
)
&apos;&apos;&apos; Generate a run-time error. An error message is displayed to the user and logged
&apos;&apos;&apos; in the console. The execution is NOT STOPPED
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Number: the error number, may be numeric or string
&apos;&apos;&apos; If numeric and &lt;= 2000, it is considered a LibreOffice Basic run-time error (default = Err)
&apos;&apos;&apos; Source: the line where the error occurred (default = Erl) or any string describing the location of the error
&apos;&apos;&apos; Description: the error message to log in the console and to display to the user
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if successful. Anyway, the execution continues
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; On Local Error GoTo Catch
&apos;&apos;&apos; &apos; ...
&apos;&apos;&apos; Catch:
&apos;&apos;&apos; SF_Exception.RaiseWarning() &apos; Standard behaviour
&apos;&apos;&apos; SF_Exception.RaiseWarning(11) &apos; Force division by zero
&apos;&apos;&apos; SF_Exception.RaiseWarning(&quot;MYAPPERROR&quot;, &quot;myFunction&quot;, &quot;Application error&quot;)
&apos;&apos;&apos; SF_Exception.RaiseWarning(,, &quot;To divide by zero is not a good idea !&quot;)
Dim bStop As Boolean &apos; Alias for stop switch
Const cstThisSub = &quot;Exception.RaiseWarning&quot;
Const cstSubArgs = &quot;[Number=Err], [Source=Erl], [Description]&quot;
&apos; Save Err, Erl, .. values before any On Error ... statement
SF_Exception._CaptureSystemError()
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(Number) Or IsEmpty(Number) Then Number = -1
If IsMissing(Source) Or IsEmpty(Source) Then Source = -1
If IsMissing(Description) Or IsEmpty(Description) Then Description = &quot;&quot;
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Number, &quot;Number&quot;, Array(V_STRING, V_NUMERIC, V_EMPTY)) Then GoTo Finally
If Not SF_Utils._Validate(Source, &quot;Source&quot;, Array(V_STRING, V_NUMERIC, V_EMPTY)) Then GoTo Finally
If Not SF_Utils._Validate(Description, &quot;Description&quot;, V_STRING) Then GoTo Finally
End If
Try:
bStop = _SF_.StopWhenError &apos; Store current value to reset it before leaving the Sub
_SF_.StopWhenError = False
SF_Exception.Raise(Number, Source, Description)
Finally:
SF_Utils._ExitFunction(cstThisSub)
_SF_.StopWhenError = bStop
Exit Sub
Catch:
GoTo Finally
End Sub &apos; ScriptForge.SF_Exception.RaiseWarning
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;Exception.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; ScriptForge.SF_Exception.SetProperty
REM =========================================================== PRIVATE FUNCTIONS
REM -----------------------------------------------------------------------------
Private Sub _CaptureSystemError()
&apos;&apos;&apos; Store system error status in system error properties
&apos;&apos;&apos; Called at each invocation of an error management property or method
&apos;&apos;&apos; Reset by SF_Exception.Clear()
If Err &gt; 0 And _SysNumber = 0 Then
_SysNumber = Err
_SysSource = Erl
_SysDescription = Error$
End If
End Sub &apos; ScriptForge.SF_Exception._CaptureSystemError
REM -----------------------------------------------------------------------------
Public Sub _CloseConsole(Optional ByRef poEvent As Object)
&apos;&apos;&apos; Close the console when opened in non-modal mode
&apos;&apos;&apos; Triggered by the CloseNonModalButton from the dlgConsole dialog
On Local Error GoTo Finally
Try:
With _SF_
If Not IsNull(.ConsoleDialog) Then
If .ConsoleDialog._IsStillAlive(False) Then &apos; False to not raise an error
Set .ConsoleControl = .ConsoleControl.Dispose()
Set .ConsoleDialog = .ConsoleDialog.Dispose()
End If
End If
End With
Finally:
Exit Sub
End Sub &apos; ScriptForge.SF_Exception._CloseConsole
REM -----------------------------------------------------------------------------
Private Sub _ConsoleRefresh()
&apos;&apos;&apos; Reload the content of the console in the dialog
&apos;&apos;&apos; Needed when console first loaded or when totally or partially cleared
With _SF_
&apos; Do nothing if console inactive
If IsNull(.ConsoleDialog) Then GoTo Finally
If Not .ConsoleDialog._IsStillAlive(False) Then &apos; False to not generate an error when dead
Set .ConsoleControl = .ConsoleControl.Dispose()
Set .ConsoleDialog = Nothing
GoTo Finally
End If
&apos; Store the relevant text in the control
If IsNull(.ConsoleControl) Then Set .ConsoleControl = .ConsoleDialog.Controls(CONSOLENAME)
.ConsoleControl.Value = &quot;&quot;
If UBound(.ConsoleLines) &gt;= 0 Then .ConsoleControl.WriteLine(Join(.ConsoleLines, SF_String.sfNEWLINE))
End With
Finally:
Exit Sub
End Sub &apos; ScriptForge.SF_Exception._ConsoleRefresh
REM -----------------------------------------------------------------------------
Private Sub _OpenHelpInBrowser(ByVal psService As String, ByVal psMethod As String)
&apos;&apos;&apos; Open the help page and help anchor related to the given ScriptForge service and method
Dim sUrl As String &apos; URL to open
Const cstURL = &quot;https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_%1.html?&amp;DbPAR=BASIC#%2&quot;
On Local Error GoTo Finally &apos; No reason to risk abort here
Try:
sUrl = SF_String.ReplaceStr(cstURL, Array(&quot;%1&quot;, &quot;%2&quot;), Array(LCase(psService), psMethod))
SF_Session.OpenUrlInBrowser(sUrl)
Finally:
Exit Sub
End Sub &apos; ScriptForge.SF_Exception._OpenHelpInBrowser
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
Dim cstThisSub As String
Const cstSubArgs = &quot;&quot;
cstThisSub = &quot;SF_Exception.get&quot; &amp; psProperty
SF_Exception._CaptureSystemError()
Select Case psProperty
Case &quot;Description&quot;
If _Description = &quot;&quot; Then _PropertyGet = _SysDescription Else _PropertyGet = _Description
Case &quot;Number&quot;
If IsEmpty(_Number) Then _PropertyGet = _SysNumber Else _PropertyGet = _Number
Case &quot;Source&quot;
If IsEmpty(_Source) Then _PropertyGet = _SysSource Else _PropertyGet = _Source
Case Else
_PropertyGet = Null
End Select
Finally:
Exit Function
End Function &apos; ScriptForge.SF_Exception._PropertyGet
REM -----------------------------------------------------------------------------
Private Function _PropertySet(Optional ByVal psProperty As String _
, Optional ByVal pvValue As Variant _
) As Boolean
&apos;&apos;&apos; Set a new value to the named property
&apos;&apos;&apos; Applicable only to user defined errors
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psProperty: the name of the property
&apos;&apos;&apos; pvValue: the new value
Dim cstThisSub As String
Const cstSubArgs = &quot;&quot;
cstThisSub = &quot;SF_Exception.set&quot; &amp; psProperty
_PropertySet = False
SF_Exception._CaptureSystemError()
&apos; Argument validation must be manual to preserve system error status
&apos; If wrong VarType then property set is ignored
Select Case psProperty
Case &quot;Description&quot;
If VarType(pvValue) = V_STRING Then _Description = pvValue
Case &quot;Number&quot;
Select Case SF_Utils._VarTypeExt(pvValue)
Case V_STRING
_Number = pvValue
Case V_NUMERIC
_Number = CLng(pvValue)
If _Number &lt;= RUNTIMEERRORS And Len(_Description) = 0 Then _Description = Error(_Number)
Case V_EMPTY
_Number = Empty
Case Else
End Select
Case &quot;Source&quot;
Select Case SF_Utils._VarTypeExt(pvValue)
Case V_STRING
_Source = pvValue
Case V_NUMERIC
_Source = CLng(pvValue)
Case Else
End Select
Case Else
End Select
_PropertySet = True
Finally:
Exit Function
End Function &apos; ScriptForge.SF_Exception._PropertySet
REM -----------------------------------------------------------------------------
Private Function _Repr() As String
&apos;&apos;&apos; Convert the Exception instance to a readable string, typically for debugging purposes (DebugPrint ...)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Return:
&apos;&apos;&apos; &quot;[Exception]: A readable string&quot;
_Repr = &quot;[Exception]: &quot; &amp; _Number &amp; &quot; (&quot; &amp; _Description &amp; &quot;)&quot;
End Function &apos; ScriptForge.SF_Exception._Repr
REM -----------------------------------------------------------------------------
Private Function _RightCase(psString As String) As String
&apos;&apos;&apos; Return the input argument in lower case only when the procedure in execution
&apos;&apos;&apos; has been triggered from a Python script
&apos;&apos;&apos; Indeed, Python requires lower case arguments
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psString: probably an identifier in ProperCase
&apos;&apos;&apos; Return:
&apos;&apos;&apos; The input argument in lower case or left unchanged depending on the execution context
Try:
If _SF_.TriggeredByPython Then _RightCase = LCase(psString) Else _RightCase = psString
Finally:
Exit Function
End Function &apos; ScriptForge.SF_Exception._RightCase
REM -----------------------------------------------------------------------------
Private Function _RightCaseArgs(psString As String) As String
&apos;&apos;&apos; Return the input argument unchanged when the execution context is Basic
&apos;&apos;&apos; When it is Python, the argument names are lowercased.
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psString: one of the cstSubArgs strings located in each official method
&apos;&apos;&apos; Return:
&apos;&apos;&apos; The input string in which the argument names are put in lower case when called from Python scripts
Dim sSubArgs As String &apos; Return value
Dim vArgs As Variant &apos; Input string split on the comma character
Dim sSingleArg As String &apos; Single vArgs item
Dim vSingleArgs As Variant &apos; vSingleArg split on equal sign
Dim i As Integer
Const cstComma = &quot;,&quot;
Const cstEqual = &quot;=&quot;
Try:
If Len(psString) = 0 Then
sSubArgs = &quot;&quot;
ElseIf _SF_.TriggeredByPython Then
vArgs = SF_String.SplitNotQuoted(psString, cstComma, QuoteChar := &quot;&quot;&quot;&quot;)
For i = 0 To UBound(vArgs)
sSingleArg = vArgs(i)
vSingleArgs = Split(sSingleArg, cstEqual)
vSingleArgs(0) = LCase(vSingleArgs(0))
vArgs(i) = join(vSingleArgs, cstEqual)
Next i
sSubArgs = Join(vArgs, cstComma)
Else
sSubArgs = psString
End If
Finally:
_RightCaseArgs = sSubArgs
Exit Function
End Function &apos; ScriptForge.SF_Exception._RightCaseArgs
REM ============================================ END OF SCRIPTFORGE.SF_EXCEPTION
</script:module>