SF_Exception.xba 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
  3. <script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_Exception" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
  4. REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
  5. REM === Full documentation is available on https://help.libreoffice.org/ ===
  6. REM =======================================================================================================================
  7. Option Compatible
  8. Option Explicit
  9. &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;
  10. &apos;&apos;&apos; Exception (aka SF_Exception)
  11. &apos;&apos;&apos; =========
  12. &apos;&apos;&apos; Generic singleton class for Basic code debugging and error handling
  13. &apos;&apos;&apos;
  14. &apos;&apos;&apos; Errors may be generated by
  15. &apos;&apos;&apos; the Basic run-time error detection
  16. &apos;&apos;&apos; in the ScriptForge code =&gt; RaiseAbort()
  17. &apos;&apos;&apos; in a user code =&gt; Raise()
  18. &apos;&apos;&apos; an error detection implemented
  19. &apos;&apos;&apos; in the ScriptForge code =&gt; RaiseFatal()
  20. &apos;&apos;&apos; in a user code =&gt; Raise() or RaiseWarning()
  21. &apos;&apos;&apos;
  22. &apos;&apos;&apos; When a run-time error occurs, the properties of the Exception object are filled
  23. &apos;&apos;&apos; with information that uniquely identifies the error and information that can be used to handle it
  24. &apos;&apos;&apos; The SF_Exception object is in this context similar to the VBA Err object
  25. &apos;&apos;&apos; See https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/err-object
  26. &apos;&apos;&apos; The Number property identifies the error: it can be a numeric value or a string
  27. &apos;&apos;&apos; Numeric values up to 2000 are considered Basic run-time errors
  28. &apos;&apos;&apos;
  29. &apos;&apos;&apos; The &quot;console&quot; logs events, actual variable values, errors, ... It is an easy mean
  30. &apos;&apos;&apos; to debug Basic programs especially when the IDE is not usable, f.i. in Calc user defined functions
  31. &apos;&apos;&apos; or during control events processing
  32. &apos;&apos;&apos; =&gt; DebugPrint()
  33. &apos;&apos;&apos;
  34. &apos;&apos;&apos; The usual behaviour of the application when an error occurs is:
  35. &apos;&apos;&apos; 1. Log the error in the console
  36. &apos;&apos;&apos; 2, Inform the user about the error with either a standard or a customized message
  37. &apos;&apos;&apos; 3. Optionally, stop the execution of the current macro
  38. &apos;&apos;&apos;
  39. &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;
  40. REM ================================================================== EXCEPTIONS
  41. &apos; SF_Utils
  42. Const MISSINGARGERROR = &quot;MISSINGARGERROR&quot;
  43. Const ARGUMENTERROR = &quot;ARGUMENTERROR&quot;
  44. Const ARRAYERROR = &quot;ARRAYERROR&quot;
  45. Const FILEERROR = &quot;FILEERROR&quot;
  46. &apos; SF_Array
  47. Const ARRAYSEQUENCEERROR = &quot;ARRAYSEQUENCEERROR&quot;
  48. Const ARRAYINSERTERROR = &quot;ARRAYINSERTERROR&quot;
  49. Const ARRAYINDEX1ERROR = &quot;ARRAYINDEX1ERROR&quot;
  50. Const ARRAYINDEX2ERROR = &quot;ARRAYINDEX2ERROR&quot;
  51. Const CSVPARSINGERROR = &quot;CSVPARSINGERROR&quot;
  52. Const CSVOVERFLOWWARNING = &quot;CSVOVERFLOWWARNING&quot;
  53. &apos; SF_Dictionary
  54. Const DUPLICATEKEYERROR = &quot;DUPLICATEKEYERROR&quot;
  55. Const UNKNOWNKEYERROR = &quot;UNKNOWNKEYERROR&quot;
  56. Const INVALIDKEYERROR = &quot;INVALIDKEYERROR&quot;
  57. &apos; SF_FileSystem
  58. Const UNKNOWNFILEERROR = &quot;UNKNOWNFILEERROR&quot;
  59. Const UNKNOWNFOLDERERROR = &quot;UNKNOWNFOLDERERROR&quot;
  60. Const NOTAFILEERROR = &quot;NOTAFILEERROR&quot;
  61. Const NOTAFOLDERERROR = &quot;NOTAFOLDERERROR&quot;
  62. Const OVERWRITEERROR = &quot;OVERWRITEERROR&quot;
  63. Const READONLYERROR = &quot;READONLYERROR&quot;
  64. Const NOFILEMATCHERROR = &quot;NOFILEMATCHFOUND&quot;
  65. Const FOLDERCREATIONERROR = &quot;FOLDERCREATIONERROR&quot;
  66. &apos; SF_Services
  67. Const UNKNOWNSERVICEERROR = &quot;UNKNOWNSERVICEERROR&quot;
  68. Const SERVICESNOTLOADEDERROR = &quot;SERVICESNOTLOADEDERROR&quot;
  69. &apos; SF_Session
  70. Const CALCFUNCERROR = &quot;CALCFUNCERROR&quot;
  71. Const NOSCRIPTERROR = &quot;NOSCRIPTERROR&quot;
  72. Const SCRIPTEXECERROR = &quot;SCRIPTEXECERROR&quot;
  73. Const WRONGEMAILERROR = &quot;WRONGEMAILERROR&quot;
  74. Const SENDMAILERROR = &quot;SENDMAILERROR&quot;
  75. &apos; SF_TextStream
  76. Const FILENOTOPENERROR = &quot;FILENOTOPENERROR&quot;
  77. Const FILEOPENMODEERROR = &quot;FILEOPENMODEERROR&quot;
  78. &apos; SF_UI
  79. Const DOCUMENTERROR = &quot;DOCUMENTERROR&quot;
  80. Const DOCUMENTCREATIONERROR = &quot;DOCUMENTCREATIONERROR&quot;
  81. Const DOCUMENTOPENERROR = &quot;DOCUMENTOPENERROR&quot;
  82. Const BASEDOCUMENTOPENERROR = &quot;BASEDOCUMENTOPENERROR&quot;
  83. &apos; SF_Document
  84. Const DOCUMENTDEADERROR = &quot;DOCUMENTDEADERROR&quot;
  85. Const DOCUMENTSAVEERROR = &quot;DOCUMENTSAVEERROR&quot;
  86. Const DOCUMENTSAVEASERROR = &quot;DOCUMENTSAVEASERROR&quot;
  87. Const DOCUMENTREADONLYERROR = &quot;DOCUMENTREADONLYERROR&quot;
  88. Const DBCONNECTERROR = &quot;DBCONNECTERROR&quot;
  89. &apos; SF_Calc
  90. Const CALCADDRESSERROR = &quot;CALCADDRESSERROR&quot;
  91. Const DUPLICATESHEETERROR = &quot;DUPLICATESHEETERROR&quot;
  92. Const OFFSETADDRESSERROR = &quot;OFFSETADDRESSERROR&quot;
  93. &apos; SF_Dialog
  94. Const DIALOGNOTFOUNDERROR = &quot;DIALOGNOTFOUNDERROR&quot;
  95. Const DIALOGDEADERROR = &quot;DIALOGDEADERROR&quot;
  96. Const CONTROLTYPEERROR = &quot;CONTROLTYPEERROR&quot;
  97. Const TEXTFIELDERROR = &quot;TEXTFIELDERROR&quot;
  98. &apos; SF_Database
  99. Const DBREADONLYERROR = &quot;DBREADONLYERROR&quot;
  100. Const SQLSYNTAXERROR = &quot;SQLSYNTAXERROR&quot;
  101. REM ============================================================= PRIVATE MEMBERS
  102. &apos; User defined errors
  103. Private _Number As Variant &apos; Error number/code (Integer or String)
  104. Private _Source As Variant &apos; Where the error occurred: a module, a Sub/Function, ...
  105. Private _Description As String &apos; The error message
  106. &apos; System run-time errors
  107. Private _SysNumber As Long &apos; Alias of Err
  108. Private _SysSource As Long &apos; Alias of Erl
  109. Private _SysDescription As String &apos; Alias of Error$
  110. REM ============================================================ MODULE CONSTANTS
  111. Const RUNTIMEERRORS = 2000 &apos; Upper limit of Basic run-time errors
  112. Const CONSOLENAME = &quot;ConsoleLines&quot; &apos; Name of control in the console dialog
  113. REM ===================================================== CONSTRUCTOR/DESTRUCTOR
  114. REM -----------------------------------------------------------------------------
  115. Public Function Dispose() As Variant
  116. Set Dispose = Nothing
  117. End Function &apos; ScriptForge.SF_Exception Explicit destructor
  118. REM ================================================================== PROPERTIES
  119. REM -----------------------------------------------------------------------------
  120. Property Get Description() As Variant
  121. &apos;&apos;&apos; Returns the description of the last error that has occurred
  122. &apos;&apos;&apos; Example:
  123. &apos;&apos;&apos; myException.Description
  124. Description = _PropertyGet(&quot;Description&quot;)
  125. End Property &apos; ScriptForge.SF_Exception.Description (get)
  126. REM -----------------------------------------------------------------------------
  127. Property Let Description(ByVal pvDescription As Variant)
  128. &apos;&apos;&apos; Set the description of the last error that has occurred
  129. &apos;&apos;&apos; Example:
  130. &apos;&apos;&apos; myException.Description = &quot;Not smart to divide by zero&quot;
  131. _PropertySet &quot;Description&quot;, pvDescription
  132. End Property &apos; ScriptForge.SF_Exception.Description (let)
  133. REM -----------------------------------------------------------------------------
  134. Property Get Number() As Variant
  135. &apos;&apos;&apos; Returns the code of the last error that has occurred
  136. &apos;&apos;&apos; Example:
  137. &apos;&apos;&apos; myException.Number
  138. Number = _PropertyGet(&quot;Number&quot;)
  139. End Property &apos; ScriptForge.SF_Exception.Number (get)
  140. REM -----------------------------------------------------------------------------
  141. Property Let Number(ByVal pvNumber As Variant)
  142. &apos;&apos;&apos; Set the code of the last error that has occurred
  143. &apos;&apos;&apos; Example:
  144. &apos;&apos;&apos; myException.Number = 11 &apos; Division by 0
  145. _PropertySet &quot;Number&quot;, pvNumber
  146. End Property &apos; ScriptForge.SF_Exception.Number (let)
  147. REM -----------------------------------------------------------------------------
  148. Property Get Source() As Variant
  149. &apos;&apos;&apos; Returns the location of the last error that has occurred
  150. &apos;&apos;&apos; Example:
  151. &apos;&apos;&apos; myException.Source
  152. Source = _PropertyGet(&quot;Source&quot;)
  153. End Property &apos; ScriptForge.SF_Exception.Source (get)
  154. REM -----------------------------------------------------------------------------
  155. Property Let Source(ByVal pvSource As Variant)
  156. &apos;&apos;&apos; Set the location of the last error that has occurred
  157. &apos;&apos;&apos; Example:
  158. &apos;&apos;&apos; myException.Source = 123 &apos; Line # 123. Source may also be a string
  159. _PropertySet &quot;Source&quot;, pvSource
  160. End Property &apos; ScriptForge.SF_Exception.Source (let)
  161. REM -----------------------------------------------------------------------------
  162. Property Get ObjectType As String
  163. &apos;&apos;&apos; Only to enable object representation
  164. ObjectType = &quot;SF_Exception&quot;
  165. End Property &apos; ScriptForge.SF_String.ObjectType
  166. REM -----------------------------------------------------------------------------
  167. Property Get ServiceName As String
  168. &apos;&apos;&apos; Internal use
  169. ServiceName = &quot;ScriptForge.Exception&quot;
  170. End Property &apos; ScriptForge.SF_Exception.ServiceName
  171. REM ===================================================================== METHODS
  172. REM -----------------------------------------------------------------------------
  173. Public Sub Clear()
  174. &apos;&apos;&apos; Reset the current error status and clear the SF_Exception object
  175. &apos;&apos;&apos; Args:
  176. &apos;&apos;&apos; Examples:
  177. &apos;&apos;&apos; On Local Error GoTo Catch
  178. &apos;&apos;&apos; &apos; ...
  179. &apos;&apos;&apos; Catch:
  180. &apos;&apos;&apos; SF_Exception.Clear() &apos; Deny the error
  181. Const cstThisSub = &quot;Exception.Clear&quot;
  182. Const cstSubArgs = &quot;&quot;
  183. Check:
  184. Try:
  185. With SF_Exception
  186. ._Number = Empty
  187. ._Source = Empty
  188. ._Description = &quot;&quot;
  189. ._SysNumber = 0
  190. ._SysSource = 0
  191. ._SysDescription = &quot;&quot;
  192. End With
  193. Finally:
  194. On Error GoTo 0
  195. Exit Sub
  196. Catch:
  197. GoTo Finally
  198. End Sub &apos; ScriptForge.SF_Exception.Clear
  199. REM -----------------------------------------------------------------------------
  200. Public Sub Console(Optional ByVal Modal As Variant)
  201. &apos;&apos;&apos; Display the console messages in a modal or non-modal dialog
  202. &apos;&apos;&apos; If the dialog is already active, when non-modal, it is brought to front
  203. &apos;&apos;&apos; Args:
  204. &apos;&apos;&apos; Modal: Boolean. Default = True
  205. &apos;&apos;&apos; Example:
  206. &apos;&apos;&apos; SF_Exception.Console()
  207. Dim bConsoleActive As Boolean &apos; When True, dialog is active
  208. Dim sClose As String &apos; Caption of the close buttons
  209. Dim oModalBtn As Object &apos; Modal close button
  210. Dim oNonModalBtn As Object &apos; Non modal close button
  211. Const cstThisSub = &quot;Exception.Console&quot;
  212. Const cstSubArgs = &quot;[Modal=True]&quot;
  213. If SF_Utils._ErrorHandling() Then On Local Error GoTo Finally &apos; Never interrupt processing
  214. Check:
  215. If IsMissing(Modal) Or IsEmpty(Modal) Then Modal = True
  216. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  217. If Not SF_Utils._Validate(Modal, &quot;Modal&quot;, V_BOOLEAN) Then GoTo Finally
  218. End If
  219. Try:
  220. With _SF_
  221. bConsoleActive = False
  222. If Not IsNull(.ConsoleDialog) Then bConsoleActive = .ConsoleDialog._IsStillAlive(False) &apos; False to not raise an error
  223. If bConsoleActive And Modal = False Then
  224. &apos; Bring to front
  225. .ConsoleDialog.Activate()
  226. Else
  227. &apos; Initialize dialog and fill with actual data
  228. &apos; The dual modes (modal and non-modal) require to have 2 close buttons o/w only 1 is visible
  229. &apos; - a usual OK button
  230. &apos; - a Default button triggering the Close action
  231. Set .ConsoleDialog = CreateScriptService(&quot;SFDialogs.Dialog&quot;, &quot;GlobalScope&quot;, &quot;ScriptForge&quot;, &quot;dlgConsole&quot;)
  232. &apos; Setup labels and visibility
  233. sClose = .Interface.GetText(&quot;CLOSEBUTTON&quot;)
  234. Set oModalBtn = .ConsoleDialog.Controls(&quot;CloseModalButton&quot;)
  235. Set oNonModalBtn = .ConsoleDialog.Controls(&quot;CloseNonModalButton&quot;)
  236. If Modal Then oModalBtn.Caption = sClose Else oNonModalBtn.Caption = sClose
  237. oModalBtn.Visible = Modal
  238. oNonModalBtn.Visible = CBool(Not Modal)
  239. &apos; Load console lines
  240. _ConsoleRefresh()
  241. .ConsoleDialog.Execute(Modal)
  242. &apos; Terminate the modal dialog
  243. If Modal Then
  244. Set .ConsoleControl = .ConsoleControl.Dispose()
  245. Set .ConsoleDialog = .ConsoleDialog.Dispose()
  246. End If
  247. End If
  248. End With
  249. Finally:
  250. SF_Utils._ExitFunction(cstThisSub)
  251. Exit Sub
  252. End Sub &apos; ScriptForge.SF_Exception.Console
  253. REM -----------------------------------------------------------------------------
  254. Public Sub ConsoleClear(Optional ByVal Keep)
  255. &apos;&apos;&apos; Clear the console keeping an optional number of recent messages
  256. &apos;&apos;&apos; Args:
  257. &apos;&apos;&apos; Keep: the number of messages to keep
  258. &apos;&apos;&apos; If Keep is bigger than the the number of messages stored in the console,
  259. &apos;&apos;&apos; the console is not cleared
  260. &apos;&apos;&apos; Example:
  261. &apos;&apos;&apos; SF_Exception.ConsoleClear(5)
  262. Dim lConsole As Long &apos; UBound of ConsoleLines
  263. Const cstThisSub = &quot;Exception.ConsoleClear&quot;
  264. Const cstSubArgs = &quot;[Keep=0]&quot;
  265. If SF_Utils._ErrorHandling() Then On Local Error GoTo Finally &apos; Never interrupt processing
  266. Check:
  267. If IsMissing(Keep) Or IsEmpty(Keep) Then Keep = 0
  268. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  269. If Not SF_Utils._Validate(Keep, &quot;Keep&quot;, V_NUMERIC) Then GoTo Finally
  270. End If
  271. Try:
  272. With _SF_
  273. If Keep &lt;= 0 Then
  274. .ConsoleLines = Array()
  275. Else
  276. lConsole = UBound(.ConsoleLines)
  277. If Keep &lt; lConsole + 1 Then .ConsoleLines = SF_Array.Slice(.ConsoleLines, lConsole - Keep + 1)
  278. End If
  279. End With
  280. &apos; If active, the console dialog needs to be refreshed
  281. _ConsoleRefresh()
  282. Finally:
  283. SF_Utils._ExitFunction(cstThisSub)
  284. Exit Sub
  285. End Sub &apos; ScriptForge.SF_Exception.ConsoleClear
  286. REM -----------------------------------------------------------------------------
  287. Public Function ConsoleToFile(Optional ByVal FileName As Variant) As Boolean
  288. &apos;&apos;&apos; Export the content of the console to a text file
  289. &apos;&apos;&apos; If the file exists and the console is not empty, it is overwritten without warning
  290. &apos;&apos;&apos; Args:
  291. &apos;&apos;&apos; FileName: the complete file name to export to. If it exists, is overwritten without warning
  292. &apos;&apos;&apos; Returns:
  293. &apos;&apos;&apos; True if the file could be created
  294. &apos;&apos;&apos; Examples:
  295. &apos;&apos;&apos; SF_Exception.ConsoleToFile(&quot;myFile.txt&quot;)
  296. Dim bExport As Boolean &apos; Return value
  297. Dim oFile As Object &apos; Output file handler
  298. Dim sLine As String &apos; A single line
  299. Const cstThisSub = &quot;Exception.ConsoleToFile&quot;
  300. Const cstSubArgs = &quot;FileName&quot;
  301. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  302. bExport = False
  303. Check:
  304. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  305. If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  306. End If
  307. Try:
  308. If UBound(_SF_.ConsoleLines) &gt; -1 Then
  309. Set oFile = SF_FileSystem.CreateTextFile(FileName, Overwrite := True)
  310. If Not IsNull(oFile) Then
  311. With oFile
  312. For Each sLine In _SF_.ConsoleLines
  313. .WriteLine(sLine)
  314. Next sLine
  315. .CloseFile()
  316. End With
  317. End If
  318. bExport = True
  319. End If
  320. Finally:
  321. If Not IsNull(oFile) Then Set oFile = oFile.Dispose()
  322. ConsoleToFile = bExport
  323. SF_Utils._ExitFunction(cstThisSub)
  324. Exit Function
  325. Catch:
  326. GoTo Finally
  327. End Function &apos; ScriptForge.SF_Exception.ConsoleToFile
  328. REM -----------------------------------------------------------------------------
  329. Public Sub DebugPrint(ParamArray pvArgs() As Variant)
  330. &apos;&apos;&apos; Print the list of arguments in a readable form in the console
  331. &apos;&apos;&apos; Arguments are separated by a TAB character (simulated by spaces)
  332. &apos;&apos;&apos; The maximum length of each individual argument = 1024 characters
  333. &apos;&apos;&apos; Args:
  334. &apos;&apos;&apos; Any number of arguments of any type
  335. &apos;&apos;&apos; Examples:
  336. &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))
  337. Dim sOutput As String &apos; Line to write in console
  338. Dim sArg As String &apos; Single argument
  339. Dim sMainSub As String &apos; Temporary storage for main function
  340. Dim i As Integer
  341. Const cstTab = 4
  342. Const cstMaxLength = 1024
  343. Const cstThisSub = &quot;Exception.DebugPrint&quot;
  344. Const cstSubArgs = &quot;Arg0, [Arg1, ...]&quot;
  345. If SF_Utils._ErrorHandling() Then On Local Error Goto Finally &apos; Never interrupt processing
  346. SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  347. Try:
  348. &apos; Build new console line
  349. sOutput = &quot;&quot;
  350. For i = 0 To UBound(pvArgs)
  351. sArg = Iif(i = 0, &quot;&quot;, SF_String.sfTAB) &amp; SF_Utils._Repr(pvArgs(i), cstMaxLength) &apos;Do not use SF_String.Represent()
  352. sOutput = sOutput &amp; sArg
  353. Next i
  354. &apos; Add to actual console
  355. _SF_._AddToConsole(SF_String.ExpandTabs(sOutput, cstTab))
  356. Finally:
  357. SF_Utils._ExitFunction(cstThisSub)
  358. Exit Sub
  359. End Sub &apos; ScriptForge.SF_Exception.DebugPrint
  360. REM -----------------------------------------------------------------------------
  361. Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
  362. &apos;&apos;&apos; Return the actual value of the given property
  363. &apos;&apos;&apos; Args:
  364. &apos;&apos;&apos; PropertyName: the name of the property as a string
  365. &apos;&apos;&apos; Returns:
  366. &apos;&apos;&apos; The actual value of the property
  367. &apos;&apos;&apos; If the property does not exist, returns Null
  368. &apos;&apos;&apos; Exceptions
  369. &apos;&apos;&apos; ARGUMENTERROR The property does not exist
  370. &apos;&apos;&apos; Examples:
  371. &apos;&apos;&apos; myException.GetProperty(&quot;MyProperty&quot;)
  372. Const cstThisSub = &quot;Exception.GetProperty&quot;
  373. Const cstSubArgs = &quot;&quot;
  374. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  375. GetProperty = Null
  376. Check:
  377. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  378. If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  379. End If
  380. Try:
  381. GetProperty = _PropertyGet(PropertyName)
  382. Finally:
  383. SF_Utils._ExitFunction(cstThisSub)
  384. Exit Function
  385. Catch:
  386. GoTo Finally
  387. End Function &apos; ScriptForge.SF_Exception.GetProperty
  388. REM -----------------------------------------------------------------------------
  389. Public Function Methods() As Variant
  390. &apos;&apos;&apos; Return the list of public methods of the Exception service as an array
  391. Methods = Array( _
  392. &quot;Clear&quot; _
  393. , &quot;Console&quot; _
  394. , &quot;ConsoleClear&quot; _
  395. , &quot;ConsoleToFile&quot; _
  396. , &quot;DebugPrint&quot; _
  397. , &quot;Raise&quot; _
  398. , &quot;RaiseAbort&quot; _
  399. , &quot;RaiseFatal&quot; _
  400. , &quot;RaiseWarning&quot; _
  401. )
  402. End Function &apos; ScriptForge.SF_Exception.Methods
  403. REM -----------------------------------------------------------------------------
  404. Public Function Properties() As Variant
  405. &apos;&apos;&apos; Return the list or properties of the Timer class as an array
  406. Properties = Array( _
  407. &quot;Description&quot; _
  408. , &quot;Number&quot; _
  409. , &quot;Source&quot; _
  410. )
  411. End Function &apos; ScriptForge.SF_Exception.Properties
  412. REM -----------------------------------------------------------------------------
  413. Public Sub Raise(Optional ByVal Number As Variant _
  414. , Optional ByVal Source As Variant _
  415. , Optional ByVal Description As Variant _
  416. )
  417. &apos;&apos;&apos; Generate a run-time error. An error message is displayed to the user and logged
  418. &apos;&apos;&apos; in the console. The execution is STOPPED
  419. &apos;&apos;&apos; Args:
  420. &apos;&apos;&apos; Number: the error number, may be numeric or string
  421. &apos;&apos;&apos; If numeric and &lt;= 2000, it is considered a LibreOffice Basic run-time error (default = Err)
  422. &apos;&apos;&apos; Source: the line where the error occurred (default = Erl) or any string describing the location of the error
  423. &apos;&apos;&apos; Description: the error message to log in the console and to display to the user
  424. &apos;&apos;&apos; Examples:
  425. &apos;&apos;&apos; On Local Error GoTo Catch
  426. &apos;&apos;&apos; &apos; ...
  427. &apos;&apos;&apos; Catch:
  428. &apos;&apos;&apos; SF_Exception.Raise() &apos; Standard behaviour
  429. &apos;&apos;&apos; SF_Exception.Raise(11) &apos; Force division by zero
  430. &apos;&apos;&apos; SF_Exception.Raise(&quot;MYAPPERROR&quot;, &quot;myFunction&quot;, &quot;Application error&quot;)
  431. &apos;&apos;&apos; SF_Exception.Raise(,, &quot;To divide by zero is not a good idea !&quot;)
  432. Dim sMessage As String &apos; Error message to log and to display
  433. Dim L10N As Object &apos; Alias to Interface
  434. Const cstThisSub = &quot;Exception.Raise&quot;
  435. Const cstSubArgs = &quot;[Number=Err], [Source=Erl], [Description]&quot;
  436. &apos; Save Err, Erl, .. values before any On Error ... statement
  437. SF_Exception._CaptureSystemError()
  438. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  439. Check:
  440. If IsMissing(Number) Or IsEmpty(Number) Then Number = -1
  441. If IsMissing(Source) Or IsEmpty(Source) Then Source = -1
  442. If IsMissing(Description) Or IsEmpty(Description) Then Description = &quot;&quot;
  443. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  444. If Not SF_Utils._Validate(Number, &quot;Number&quot;, Array(V_STRING, V_NUMERIC)) Then GoTo Finally
  445. If Not SF_Utils._Validate(Source, &quot;Source&quot;, Array(V_STRING, V_NUMERIC)) Then GoTo Finally
  446. If Not SF_Utils._Validate(Description, &quot;Description&quot;, V_STRING) Then GoTo Finally
  447. End If
  448. Try:
  449. With SF_Exception
  450. If Number &gt;= 0 Then .Number = Number
  451. If VarType(Source) = V_STRING Then
  452. If Len(Source) &gt; 0 Then .Source = Source
  453. ElseIf Source &gt;= 0 Then &apos; -1 = Default =&gt; no change
  454. .Source = Source
  455. End If
  456. If Len(Description) &gt; 0 Then .Description = Description
  457. &apos; Log and display
  458. Set L10N = _SF_.Interface
  459. sMessage = L10N.GetText(&quot;LONGERRORDESC&quot;, .Number, .Source, .Description)
  460. .DebugPrint(sMessage)
  461. If _SF_.DisplayEnabled Then MsgBox L10N.GetText(&quot;ERRORNUMBER&quot;, .Number) _
  462. &amp; SF_String.sfNewLine &amp; L10N.GetText(&quot;ERRORLOCATION&quot;, .Source) _
  463. &amp; SF_String.sfNewLine &amp; .Description _
  464. , MB_OK + MB_ICONSTOP _
  465. , L10N.GetText(&quot;ERRORNUMBER&quot;, .Number)
  466. .Clear()
  467. End With
  468. Finally:
  469. SF_Utils._ExitFunction(cstThisSub)
  470. If _SF_.StopWhenError Then
  471. _SF_._StackReset()
  472. Stop
  473. End If
  474. Exit Sub
  475. Catch:
  476. GoTo Finally
  477. End Sub &apos; ScriptForge.SF_Exception.Raise
  478. REM -----------------------------------------------------------------------------
  479. Public Sub RaiseAbort(Optional ByVal Source As Variant)
  480. &apos;&apos;&apos; Manage a run-time error that occurred inside the ScriptForge piece of software itself.
  481. &apos;&apos;&apos; The event is logged.
  482. &apos;&apos;&apos; The execution is STOPPED
  483. &apos;&apos;&apos; For INTERNAL USE only
  484. &apos;&apos;&apos; Args:
  485. &apos;&apos;&apos; Source: the line where the error occurred
  486. Dim sLocation As String &apos; Common header in error messages: location of error
  487. Dim vLocation As Variant &apos; Splitted array (library, module, method)
  488. Dim sMessage As String &apos; Error message to log and to display
  489. Dim L10N As Object &apos; Alias to Interface
  490. Const cstTabSize = 4
  491. Const cstThisSub = &quot;Exception.RaiseAbort&quot;
  492. Const cstSubArgs = &quot;[Source=Erl]&quot;
  493. &apos; Save Err, Erl, .. values before any On Error ... statement
  494. SF_Exception._CaptureSystemError()
  495. On Local Error Resume Next
  496. Check:
  497. If IsMissing(Source) Or IsEmpty(Source) Then Source = &quot;&quot;
  498. Try:
  499. With SF_Exception
  500. &apos; Prepare message header
  501. Set L10N = _SF_.Interface
  502. If Len(_SF_.MainFunction) &gt; 0 Then &apos; MainFunction = [Library.]Module.Method
  503. vLocation = Split(_SF_.MainFunction, &quot;.&quot;)
  504. If UBound(vLocation) &lt; 2 Then vLocation = SF_Array.Prepend(vLocation, &quot;ScriptForge&quot;)
  505. sLocation = L10N.GetText(&quot;VALIDATESOURCE&quot;, vLocation(0), vLocation(1), vLocation(2)) &amp; &quot;\n\n\n&quot;
  506. Else
  507. sLocation = &quot;&quot;
  508. End If
  509. &apos; Log and display
  510. Set L10N = _SF_.Interface
  511. sMessage = L10N.GetText(&quot;LONGERRORDESC&quot;, .Number, .Source, .Description)
  512. .DebugPrint(sMessage)
  513. If _SF_.DisplayEnabled Then
  514. sMessage = sLocation _
  515. &amp; L10N.GetText(&quot;INTERNALERROR&quot;) _
  516. &amp; L10N.GetText(&quot;ERRORLOCATION&quot;, Source &amp; &quot;/&quot; &amp; .Source) &amp; SF_String.sfNewLine &amp; .Description _
  517. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; L10N.GetText(&quot;STOPEXECUTION&quot;)
  518. MsgBox SF_String.ExpandTabs(SF_String.Unescape(sMessage), cstTabSize) _
  519. , MB_OK + MB_ICONSTOP _
  520. , L10N.GetText(&quot;ERRORNUMBER&quot;, .Number)
  521. End If
  522. .Clear()
  523. End With
  524. Finally:
  525. _SF_._StackReset()
  526. If _SF_.StopWhenError Then Stop
  527. Exit Sub
  528. Catch:
  529. GoTo Finally
  530. End Sub &apos; ScriptForge.SF_Exception.RaiseAbort
  531. REM -----------------------------------------------------------------------------
  532. Public Sub RaiseFatal(Optional ByVal ErrorCode As Variant _
  533. , ParamArray pvArgs _
  534. )
  535. &apos;&apos;&apos; Generate a run-time error caused by an anomaly in a user script detected by ScriptForge
  536. &apos;&apos;&apos; The message is logged in the console. The execution is STOPPED
  537. &apos;&apos;&apos; For INTERNAL USE only
  538. &apos;&apos;&apos; Args:
  539. &apos;&apos;&apos; ErrorCode: as a string, the unique identifier of the error
  540. &apos;&apos;&apos; pvArgs: the arguments to insert in the error message
  541. Dim sLocation As String &apos; Common header in error messages: location of error
  542. Dim vLocation As Variant &apos; Splitted array (library, module, method)
  543. Dim sMessage As String &apos; Message to log and display
  544. Dim L10N As Object &apos; Alias of Interface
  545. Dim sAlt As String &apos; Alternative error messages
  546. Const cstTabSize = 4
  547. Const cstThisSub = &quot;Exception.RaiseFatal&quot;
  548. Const cstSubArgs = &quot;ErrorCode, [Arg0[, Arg1 ...]]&quot;
  549. Const cstStop = &quot;⏻&quot; &apos; Chr(9211)
  550. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  551. Check:
  552. If IsMissing(ErrorCode) Or IsEmpty(ErrorCode) Then ErrorCode = &quot;&quot;
  553. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  554. If Not SF_Utils._Validate(ErrorCode, &quot;ErrorCode&quot;, V_STRING) Then GoTo Finally
  555. End If
  556. Try:
  557. Set L10N = _SF_.Interface
  558. &apos; Location header common to all error messages
  559. If Len(_SF_.MainFunction) &gt; 0 Then &apos; MainFunction = [Library.]Module.Method
  560. vLocation = Split(_SF_.MainFunction, &quot;.&quot;)
  561. If UBound(vLocation) &lt; 2 Then vLocation = SF_Array.Prepend(vLocation, &quot;ScriptForge&quot;)
  562. sLocation = L10N.GetText(&quot;VALIDATESOURCE&quot;, vLocation(0), vLocation(1), vLocation(2)) _
  563. &amp; &quot;\n&quot; &amp; L10N.GetText(&quot;VALIDATEARGS&quot;, _SF_.MainFunctionArgs)
  564. Else
  565. sLocation = &quot;&quot;
  566. End If
  567. With L10N
  568. Select Case UCase(ErrorCode)
  569. Case MISSINGARGERROR &apos; SF_Utils._Validate(Name)
  570. sMessage = sLocation _
  571. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  572. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEMISSING&quot;, pvArgs(0))
  573. Case ARGUMENTERROR &apos; SF_Utils._Validate(Value, Name, Types, Values, Regex, Class)
  574. sMessage = sLocation _
  575. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(1)) _
  576. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATIONRULES&quot;)
  577. If Len(pvArgs(2)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATETYPES&quot;, pvArgs(1), pvArgs(2))
  578. If Len(pvArgs(3)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEVALUES&quot;, pvArgs(1), pvArgs(3))
  579. If Len(pvArgs(4)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEREGEX&quot;, pvArgs(1), pvArgs(4))
  580. If Len(pvArgs(5)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATECLASS&quot;, pvArgs(1), pvArgs(5))
  581. sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEACTUAL&quot;, pvArgs(1), pvArgs(0))
  582. Case ARRAYERROR &apos; SF_Utils._ValidateArray(Value, Name, Dimensions, Types, NotNull)
  583. sMessage = sLocation _
  584. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(1)) _
  585. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATIONRULES&quot;) _
  586. &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEARRAY&quot;, pvArgs(1))
  587. If pvArgs(2) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEDIMS&quot;, pvArgs(1), pvArgs(2))
  588. If Len(pvArgs(3)) &gt; 0 Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEALLTYPES&quot;, pvArgs(1), pvArgs(3))
  589. If pvArgs(4) Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATENOTNULL&quot;, pvArgs(1))
  590. sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEACTUAL&quot;, pvArgs(1), pvArgs(0))
  591. Case FILEERROR &apos; SF_Utils._ValidateFile(Value, Name, WildCards)
  592. sMessage = sLocation _
  593. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(1)) _
  594. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATIONRULES&quot;) _
  595. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEFILE&quot;, pvArgs(1))
  596. sAlt = &quot;VALIDATEFILE&quot; &amp; SF_FileSystem.FileNaming
  597. sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(sAlt, pvArgs(1))
  598. If pvArgs(2) Then sMessage = sMessage &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEWILDCARD&quot;, pvArgs(1))
  599. sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEACTUAL&quot;, pvArgs(1), pvArgs(0))
  600. Case ARRAYSEQUENCEERROR &apos; SF_Array.RangeInit(From, UpTo, ByStep)
  601. sMessage = sLocation _
  602. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYSEQUENCE&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
  603. Case ARRAYINSERTERROR &apos; SF_Array.AppendColumn/Row/PrependColumn/Row(VectorName, Array_2D, Vector)
  604. sMessage = sLocation _
  605. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYINSERT&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
  606. Case ARRAYINDEX1ERROR &apos; SF_Array.ExtractColumn/Row(IndexName, Array_2D, Index)
  607. sMessage = sLocation _
  608. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYINDEX1&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
  609. Case ARRAYINDEX2ERROR &apos; SF_Array.Slice(From, UpTo)
  610. sMessage = sLocation _
  611. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;ARRAYINDEX2&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
  612. Case CSVPARSINGERROR &apos; SF_Array.ImportFromCSVFile(FileName, LineNumber, Line)
  613. sMessage = sLocation _
  614. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CSVPARSING&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
  615. Case DUPLICATEKEYERROR &apos; SF_Dictionary.Add/ReplaceKey(&quot;Key&quot;, Key)
  616. sMessage = sLocation _
  617. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  618. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DUPLICATEKEY&quot;, pvArgs(0), pvArgs(1))
  619. Case UNKNOWNKEYERROR &apos; SF_Dictionary.Remove/ReplaceItem/ReplaceKey(&quot;Key&quot;, Key)
  620. sMessage = sLocation _
  621. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  622. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNKEY&quot;, pvArgs(0), pvArgs(1))
  623. Case INVALIDKEYERROR &apos; SF_Dictionary.Add/ReplaceKey(Key)
  624. sMessage = sLocation _
  625. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  626. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;INVALIDKEY&quot;)
  627. Case UNKNOWNFILEERROR &apos; SF_FileSystem.CopyFile/MoveFile/DeleteFile/CreateScriptService(&quot;L10N&quot;)(ArgName, Filename)
  628. sMessage = sLocation _
  629. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  630. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNFILE&quot;, pvArgs(0), pvArgs(1))
  631. Case UNKNOWNFOLDERERROR &apos; SF_FileSystem.CopyFolder/MoveFolder/DeleteFolder/Files/SubFolders(ArgName, Filename)
  632. sMessage = sLocation _
  633. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  634. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNFOLDER&quot;, pvArgs(0), pvArgs(1))
  635. Case NOTAFILEERROR &apos; SF_FileSystem.CopyFile/MoveFile/DeleteFile(ArgName, Filename)
  636. sMessage = sLocation _
  637. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  638. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOTAFILE&quot;, pvArgs(0), pvArgs(1))
  639. Case NOTAFOLDERERROR &apos; SF_FileSystem.CopyFolder/MoveFolder/DeleteFolder/Files/SubFolders(ArgName, Filename)
  640. sMessage = sLocation _
  641. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  642. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOTAFOLDER&quot;, pvArgs(0), pvArgs(1))
  643. Case OVERWRITEERROR &apos; SF_FileSystem.Copy+Move/File+Folder/CreateTextFile/OpenTextFile(ArgName, Filename)
  644. sMessage = sLocation _
  645. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  646. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;OVERWRITE&quot;, pvArgs(0), pvArgs(1))
  647. Case READONLYERROR &apos; SF_FileSystem.Copy+Move+Delete/File+Folder(ArgName, Filename)
  648. sMessage = sLocation _
  649. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  650. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;READONLY&quot;, pvArgs(0), pvArgs(1))
  651. Case NOFILEMATCHERROR &apos; SF_FileSystem.Copy+Move+Delete/File+Folder(ArgName, Filename)
  652. sMessage = sLocation _
  653. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  654. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOFILEMATCH&quot;, pvArgs(0), pvArgs(1))
  655. Case FOLDERCREATIONERROR &apos; SF_FileSystem.CreateFolder(ArgName, Filename)
  656. sMessage = sLocation _
  657. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  658. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FOLDERCREATION&quot;, pvArgs(0), pvArgs(1))
  659. Case UNKNOWNSERVICEERROR &apos; SF_Services.CreateScriptService(ArgName, Value, Library, Service)
  660. sMessage = sLocation _
  661. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  662. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;UNKNOWNSERVICE&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
  663. Case SERVICESNOTLOADEDERROR &apos; SF_Services.CreateScriptService(ArgName, Value, Library)
  664. sMessage = sLocation _
  665. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  666. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SERVICESNOTLOADED&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
  667. Case CALCFUNCERROR &apos; SF_Session.ExecuteCalcFunction(CalcFunction)
  668. sMessage = sLocation _
  669. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, &quot;CalcFunction&quot;) _
  670. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CALCFUNC&quot;, pvArgs(0))
  671. Case NOSCRIPTERROR &apos; SF_Session._GetScript(Language, &quot;Scope&quot;, Scope, &quot;Script&quot;, Script)
  672. sMessage = sLocation _
  673. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, &quot;Script&quot;) _
  674. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;NOSCRIPT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4))
  675. Case SCRIPTEXECERROR &apos; SF_Session.ExecuteBasicScript(&quot;Script&quot;, Script, Cause)
  676. sMessage = sLocation _
  677. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SCRIPTEXEC&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
  678. Case WRONGEMAILERROR &apos; SF_Session.SendMail(Arg, Email)
  679. sMessage = sLocation _
  680. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  681. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;WRONGEMAIL&quot;, pvArgs(1))
  682. Case SENDMAILERROR &apos; SF_Session.SendMail()
  683. sMessage = sLocation _
  684. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SENDMAIL&quot;)
  685. Case FILENOTOPENERROR &apos; SF_TextStream._IsFileOpen(FileName)
  686. sMessage = sLocation _
  687. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FILENOTOPEN&quot;, pvArgs(0))
  688. Case FILEOPENMODEERROR &apos; SF_TextStream._IsFileOpen(FileName)
  689. sMessage = sLocation _
  690. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FILEOPENMODE&quot;, pvArgs(0), pvArgs(1))
  691. Case DOCUMENTERROR &apos; SF_UI.GetDocument(ArgName, WindowName)
  692. sMessage = sLocation _
  693. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  694. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENT&quot;, pvArgs(0), pvArgs(1))
  695. Case DOCUMENTCREATIONERROR &apos; SF_UI.Create(Arg1Name, DocumentType, Arg2Name, TemplateFile)
  696. sMessage = sLocation _
  697. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTCREATION&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
  698. Case DOCUMENTOPENERROR &apos; SF_UI.OpenDocument(Arg1Name, FileName, Arg2Name, Password, Arg3Name, FilterName)
  699. sMessage = sLocation _
  700. &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))
  701. Case BASEDOCUMENTOPENERROR &apos; SF_UI.OpenBaseDocument(Arg1Name, FileName, Arg2Name, RegistrationName)
  702. sMessage = sLocation _
  703. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;BASEDOCUMENTOPEN&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
  704. Case DOCUMENTDEADERROR &apos; SF_Document._IsStillAlive(FileName)
  705. sMessage = sLocation _
  706. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTDEAD&quot;, pvArgs(0))
  707. Case DOCUMENTSAVEERROR &apos; SF_Document.Save(Arg1Name, FileName)
  708. sMessage = sLocation _
  709. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTSAVE&quot;, pvArgs(0), pvArgs(1))
  710. Case DOCUMENTSAVEASERROR &apos; SF_Document.SaveAs(Arg1Name, FileName, Arg2, Overwrite, Arg3, FilterName)
  711. sMessage = sLocation _
  712. &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))
  713. Case DOCUMENTREADONLYERROR &apos; SF_Document.update property(&quot;Document&quot;, FileName)
  714. sMessage = sLocation _
  715. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DOCUMENTREADONLY&quot;, pvArgs(0), pvArgs(1))
  716. Case DBCONNECTERROR &apos; SF_Base.GetDatabase(&quot;User&quot;, User, &quot;Password&quot;, Password, FileName)
  717. sMessage = sLocation _
  718. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DBCONNECT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4))
  719. Case CALCADDRESSERROR &apos; SF_Calc._ParseAddress(Address, &quot;Range&quot;/&quot;Sheet&quot;, Scope, Document)
  720. sMessage = sLocation _
  721. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  722. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CALCADDRESS&quot; &amp; Iif(pvArgs(0) = &quot;Sheet&quot;, &quot;1&quot;, &quot;2&quot;), pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
  723. Case DUPLICATESHEETERROR &apos; SF_Calc.InsertSheet(arg, SheetName, Document)
  724. sMessage = sLocation _
  725. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
  726. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DUPLICATESHEET&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
  727. 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)
  728. sMessage = sLocation _
  729. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;OFFSETADDRESS&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4) _
  730. , pvArgs(5), pvArgs(6), pvArgs(7), pvArgs(8), pvArgs(9), pvArgs(10), pvArgs(11))
  731. Case DIALOGNOTFOUNDERROR &apos; SF_Dialog._NewDialog(Service, DialogName, WindowName)
  732. sMessage = sLocation _
  733. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DIALOGNOTFOUND&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4) _
  734. , pvArgs(5), pvArgs(6), pvArgs(7))
  735. Case DIALOGDEADERROR &apos; SF_Dialog._IsStillAlive(DialogName)
  736. sMessage = sLocation _
  737. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DIALOGDEAD&quot;, pvArgs(0))
  738. Case CONTROLTYPEERROR &apos; SF_DialogControl._SetProperty(ControlName, DialogName, ControlType, Property)
  739. sMessage = sLocation _
  740. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CONTROLTYPE&quot;, pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
  741. Case TEXTFIELDERROR &apos; SF_DialogControl.WriteLine(ControlName, DialogName)
  742. sMessage = sLocation _
  743. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;TEXTFIELD&quot;, pvArgs(0), pvArgs(1))
  744. Case DBREADONLYERROR &apos; SF_Database.RunSql()
  745. sMessage = sLocation _
  746. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;DBREADONLY&quot;, vLocation(2))
  747. Case SQLSYNTAXERROR &apos; SF_Database._ExecuteSql(SQL)
  748. sMessage = sLocation _
  749. &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;SQLSYNTAX&quot;, pvArgs(0))
  750. Case Else
  751. End Select
  752. End With
  753. &apos; Log fatal event
  754. _SF_._AddToConsole(sMessage)
  755. &apos; Display fatal event, if relevant (default)
  756. If _SF_.DisplayEnabled Then
  757. If _SF_.StopWhenError Then sMessage = sMessage &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; L10N.GetText(&quot;STOPEXECUTION&quot;)
  758. MsgBox SF_String.ExpandTabs(SF_String.Unescape(sMessage), cstTabSize) _
  759. , MB_OK + MB_ICONEXCLAMATION _
  760. , L10N.GetText(&quot;ERRORNUMBER&quot;, ErrorCode)
  761. End If
  762. Finally:
  763. SF_Utils._ExitFunction(cstThisSub)
  764. _SF_._StackReset()
  765. If _SF_.StopWhenError Then Stop
  766. Exit Sub
  767. Catch:
  768. GoTo Finally
  769. End Sub &apos; ScriptForge.SF_Exception.RaiseFatal
  770. REM -----------------------------------------------------------------------------
  771. Public Sub RaiseWarning(Optional ByVal Number As Variant _
  772. , Optional ByVal Source As Variant _
  773. , Optional ByVal Description As Variant _
  774. )
  775. &apos;&apos;&apos; Generate a run-time error. An error message is displayed to the user and logged
  776. &apos;&apos;&apos; in the console. The execution is NOT STOPPED
  777. &apos;&apos;&apos; Args:
  778. &apos;&apos;&apos; Number: the error number, may be numeric or string
  779. &apos;&apos;&apos; If numeric and &lt;= 2000, it is considered a LibreOffice Basic run-time error (default = Err)
  780. &apos;&apos;&apos; Source: the line where the error occurred (default = Erl) or any string describing the location of the error
  781. &apos;&apos;&apos; Description: the error message to log in the console and to display to the user
  782. &apos;&apos;&apos; Returns:
  783. &apos;&apos;&apos; True if successful. Anyway, the execution continues
  784. &apos;&apos;&apos; Examples:
  785. &apos;&apos;&apos; On Local Error GoTo Catch
  786. &apos;&apos;&apos; &apos; ...
  787. &apos;&apos;&apos; Catch:
  788. &apos;&apos;&apos; SF_Exception.RaiseWarning() &apos; Standard behaviour
  789. &apos;&apos;&apos; SF_Exception.RaiseWarning(11) &apos; Force division by zero
  790. &apos;&apos;&apos; SF_Exception.RaiseWarning(&quot;MYAPPERROR&quot;, &quot;myFunction&quot;, &quot;Application error&quot;)
  791. &apos;&apos;&apos; SF_Exception.RaiseWarning(,, &quot;To divide by zero is not a good idea !&quot;)
  792. Dim bStop As Boolean &apos; Alias for stop switch
  793. Const cstThisSub = &quot;Exception.RaiseWarning&quot;
  794. Const cstSubArgs = &quot;[Number=Err], [Source=Erl], [Description]&quot;
  795. &apos; Save Err, Erl, .. values before any On Error ... statement
  796. SF_Exception._CaptureSystemError()
  797. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  798. Check:
  799. If IsMissing(Number) Or IsEmpty(Number) Then Number = -1
  800. If IsMissing(Source) Or IsEmpty(Source) Then Source = -1
  801. If IsMissing(Description) Or IsEmpty(Description) Then Description = &quot;&quot;
  802. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  803. If Not SF_Utils._Validate(Number, &quot;Number&quot;, Array(V_STRING, V_NUMERIC, V_EMPTY)) Then GoTo Finally
  804. If Not SF_Utils._Validate(Source, &quot;Source&quot;, Array(V_STRING, V_NUMERIC, V_EMPTY)) Then GoTo Finally
  805. If Not SF_Utils._Validate(Description, &quot;Description&quot;, V_STRING) Then GoTo Finally
  806. End If
  807. Try:
  808. bStop = _SF_.StopWhenError &apos; Store current value to reset it before leaving the Sub
  809. _SF_.StopWhenError = False
  810. SF_Exception.Raise(Number, Source, Description)
  811. Finally:
  812. SF_Utils._ExitFunction(cstThisSub)
  813. _SF_.StopWhenError = bStop
  814. Exit Sub
  815. Catch:
  816. GoTo Finally
  817. End Sub &apos; ScriptForge.SF_Exception.RaiseWarning
  818. REM -----------------------------------------------------------------------------
  819. Public Function SetProperty(Optional ByVal PropertyName As Variant _
  820. , Optional ByRef Value As Variant _
  821. ) As Boolean
  822. &apos;&apos;&apos; Set a new value to the given property
  823. &apos;&apos;&apos; Args:
  824. &apos;&apos;&apos; PropertyName: the name of the property as a string
  825. &apos;&apos;&apos; Value: its new value
  826. &apos;&apos;&apos; Exceptions
  827. &apos;&apos;&apos; ARGUMENTERROR The property does not exist
  828. Const cstThisSub = &quot;Exception.SetProperty&quot;
  829. Const cstSubArgs = &quot;PropertyName, Value&quot;
  830. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  831. SetProperty = False
  832. Check:
  833. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  834. If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  835. End If
  836. Try:
  837. SetProperty = _PropertySet(PropertyName, Value)
  838. Finally:
  839. SF_Utils._ExitFunction(cstThisSub)
  840. Exit Function
  841. Catch:
  842. GoTo Finally
  843. End Function &apos; ScriptForge.SF_Exception.SetProperty
  844. REM =========================================================== PRIVATE FUNCTIONS
  845. REM -----------------------------------------------------------------------------
  846. Private Sub _CaptureSystemError()
  847. &apos;&apos;&apos; Store system error status in system error properties
  848. &apos;&apos;&apos; Called at each invocation of an error management property or method
  849. &apos;&apos;&apos; Reset by SF_Exception.Clear()
  850. If Err &gt; 0 And _SysNumber = 0 Then
  851. _SysNumber = Err
  852. _SysSource = Erl
  853. _SysDescription = Error$
  854. End If
  855. End Sub &apos; ScriptForge.SF_Exception._CaptureSystemError
  856. REM -----------------------------------------------------------------------------
  857. Public Sub _CloseConsole(Optional ByRef poEvent As Object)
  858. &apos;&apos;&apos; Close the console when opened in non-modal mode
  859. &apos;&apos;&apos; Triggered by the CloseNonModalButton from the dlgConsole dialog
  860. On Local Error GoTo Finally
  861. Try:
  862. With _SF_
  863. If Not IsNull(.ConsoleDialog) Then
  864. If .ConsoleDialog._IsStillAlive(False) Then &apos; False to not raise an error
  865. Set .ConsoleControl = .ConsoleControl.Dispose()
  866. Set .ConsoleDialog = .ConsoleDialog.Dispose()
  867. End If
  868. End If
  869. End With
  870. Finally:
  871. Exit Sub
  872. End Sub &apos; ScriptForge.SF_Exception._CloseConsole
  873. REM -----------------------------------------------------------------------------
  874. Private Sub _ConsoleRefresh()
  875. &apos;&apos;&apos; Reload the content of the console in the dialog
  876. &apos;&apos;&apos; Needed when console first loaded or when totally or partially cleared
  877. With _SF_
  878. &apos; Do nothing if console inactive
  879. If IsNull(.ConsoleDialog) Then GoTo Finally
  880. If Not .ConsoleDialog._IsStillAlive(False) Then &apos; False to not generate an error when dead
  881. Set .ConsoleControl = .ConsoleControl.Dispose()
  882. Set .ConsoleDialog = Nothing
  883. GoTo Finally
  884. End If
  885. &apos; Store the relevant text in the control
  886. If IsNull(.ConsoleControl) Then Set .ConsoleControl = .ConsoleDialog.Controls(CONSOLENAME)
  887. .ConsoleControl.Value = &quot;&quot;
  888. If UBound(.ConsoleLines) &gt;= 0 Then .ConsoleControl.WriteLine(Join(.ConsoleLines, SF_String.sfNEWLINE))
  889. End With
  890. Finally:
  891. Exit Sub
  892. End Sub &apos; ScriptForge.SF_Exception._ConsoleRefresh
  893. REM -----------------------------------------------------------------------------
  894. Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
  895. &apos;&apos;&apos; Return the value of the named property
  896. &apos;&apos;&apos; Args:
  897. &apos;&apos;&apos; psProperty: the name of the property
  898. Dim cstThisSub As String
  899. Const cstSubArgs = &quot;&quot;
  900. cstThisSub = &quot;SF_Exception.get&quot; &amp; psProperty
  901. SF_Exception._CaptureSystemError()
  902. Select Case psProperty
  903. Case &quot;Description&quot;
  904. If _Description = &quot;&quot; Then _PropertyGet = _SysDescription Else _PropertyGet = _Description
  905. Case &quot;Number&quot;
  906. If IsEmpty(_Number) Then _PropertyGet = _SysNumber Else _PropertyGet = _Number
  907. Case &quot;Source&quot;
  908. If IsEmpty(_Source) Then _PropertyGet = _SysSource Else _PropertyGet = _Source
  909. Case Else
  910. _PropertyGet = Null
  911. End Select
  912. Finally:
  913. Exit Function
  914. End Function &apos; ScriptForge.SF_Exception._PropertyGet
  915. REM -----------------------------------------------------------------------------
  916. Private Function _PropertySet(Optional ByVal psProperty As String _
  917. , Optional ByVal pvValue As Variant _
  918. ) As Boolean
  919. &apos;&apos;&apos; Set a new value to the named property
  920. &apos;&apos;&apos; Applicable only to user defined errors
  921. &apos;&apos;&apos; Args:
  922. &apos;&apos;&apos; psProperty: the name of the property
  923. &apos;&apos;&apos; pvValue: the new value
  924. Dim cstThisSub As String
  925. Const cstSubArgs = &quot;&quot;
  926. cstThisSub = &quot;SF_Exception.set&quot; &amp; psProperty
  927. _PropertySet = False
  928. SF_Exception._CaptureSystemError()
  929. &apos; Argument validation must be manual to preserve system error status
  930. &apos; If wrong VarType then property set is ignored
  931. Select Case psProperty
  932. Case &quot;Description&quot;
  933. If VarType(pvValue) = V_STRING Then _Description = pvValue
  934. Case &quot;Number&quot;
  935. Select Case SF_Utils._VarTypeExt(pvValue)
  936. Case V_STRING
  937. _Number = pvValue
  938. Case V_NUMERIC
  939. _Number = CLng(pvValue)
  940. If _Number &lt;= RUNTIMEERRORS And Len(_Description) = 0 Then _Description = Error(_Number)
  941. Case V_EMPTY
  942. _Number = Empty
  943. Case Else
  944. End Select
  945. Case &quot;Source&quot;
  946. Select Case SF_Utils._VarTypeExt(pvValue)
  947. Case V_STRING
  948. _Source = pvValue
  949. Case V_NUMERIC
  950. _Source = CLng(pvValue)
  951. Case Else
  952. End Select
  953. Case Else
  954. End Select
  955. _PropertySet = True
  956. Finally:
  957. Exit Function
  958. End Function &apos; ScriptForge.SF_Exception._PropertySet
  959. REM -----------------------------------------------------------------------------
  960. Private Function _Repr() As String
  961. &apos;&apos;&apos; Convert the Exception instance to a readable string, typically for debugging purposes (DebugPrint ...)
  962. &apos;&apos;&apos; Args:
  963. &apos;&apos;&apos; Return:
  964. &apos;&apos;&apos; &quot;[Exception]: A readable string&quot;
  965. _Repr = &quot;[Exception]: &quot; &amp; _Number &amp; &quot; (&quot; &amp; _Description &amp; &quot;)&quot;
  966. End Function &apos; ScriptForge.SF_Exception._Repr
  967. REM ============================================ END OF SCRIPTFORGE.SF_EXCEPTION
  968. </script:module>