docthemes: Save themes def. to a file when added to ColorSets
[LibreOffice.git] / wizards / source / sfdatabases / SF_Datasheet.xba
blobc505dd45f1042d7895a6aab1dc4f2998e4a5e80d
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_Datasheet" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
4 REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
5 REM === The SFDatabases library is one of the associated libraries. ===
6 REM === Full documentation is available on https://help.libreoffice.org/ ===
7 REM =======================================================================================================================
9 Option Compatible
10 Option ClassModule
12 Option Explicit
14 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
15 &apos;&apos;&apos; SF_Datasheet
16 &apos;&apos;&apos; ============
17 &apos;&apos;&apos; A datasheet is the visual representation of tabular data produced by a database.
18 &apos;&apos;&apos; In the user interface of LibreOffice it is the result of the opening of
19 &apos;&apos;&apos; a table or a query. In this case the concerned Base document must be open.
20 &apos;&apos;&apos;
21 &apos;&apos;&apos; In the context of ScriptForge, a datasheet may be opened automatically by script code :
22 &apos;&apos;&apos; - either by reproducing the behaviour of the user interface
23 &apos;&apos;&apos; - or at any moment. In this case the Base document may or may not be opened.
24 &apos;&apos;&apos; Additionally, any SELECT SQL statement may define the datasheet display.
25 &apos;&apos;&apos;
26 &apos;&apos;&apos; The proposed API allows for either datasheets (opened manually of by code) in particular
27 &apos;&apos;&apos; to know which cell is selected and its content.
28 &apos;&apos;&apos;
29 &apos;&apos;&apos; Service invocation:
30 &apos;&apos;&apos; 1) From an open Base document
31 &apos;&apos;&apos; Set ui = CreateScriptService(&quot;UI&quot;)
32 &apos;&apos;&apos; Set oBase = ui.getDocument(&quot;/home/user/Documents/myDb.odb&quot;)
33 &apos;&apos;&apos; Set oSheet = oBase.OpenTable(&quot;Customers&quot;) &apos; or OpenQuery(...)
34 &apos;&apos;&apos; &apos; May be executed also when the given table is already open
35 &apos;&apos;&apos; 2) Independently from a Base document
36 &apos;&apos;&apos; Set oDatabase = CreateScriptService(&quot;Database&quot;, &quot;/home/user/Documents/myDb.odb&quot;)
37 &apos;&apos;&apos; Set oSheet = oDatabase.OpenTable(&quot;Customers&quot;)
38 &apos;&apos;&apos;
39 &apos;&apos;&apos; Detailed user documentation:
40 &apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_datasheet.html?DbPAR=BASIC
41 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
43 REM ================================================================== EXCEPTIONS
45 Private Const DOCUMENTDEADERROR = &quot;DOCUMENTDEADERROR&quot;
47 REM ============================================================= PRIVATE MEMBERS
49 Private [Me] As Object
50 Private [_Parent] As Object &apos; Base instance when opened from a Base document by code
51 &apos; or Database instance when opened without Base document
52 Private ObjectType As String &apos; Must be DATASHEET
53 Private ServiceName As String
55 Private _Component As Object &apos; com.sun.star.lang.XComponent - org.openoffice.comp.dbu.ODatasourceBrowser
56 Private _Frame As Object &apos; com.sun.star.frame.XFrame
57 Private _ParentBase As Object &apos; The parent SF_Base instance (may be void)
58 Private _ParentDatabase As Object &apos; The parent SF_Database instance (must not be void)
59 Private _SheetType As String &apos; TABLE, QUERY or SQL
60 Private _ParentType As String &apos; BASE or DATABASE
61 Private _BaseFileName As String &apos; URL format of parent Base file
62 Private _Command As String &apos; Table name, query name or SQL statement
63 Private _DirectSql As Boolean &apos; When True, SQL processed by RDBMS
64 Private _TabControllerModel As Object &apos; com.sun.star.awt.XTabControllerModel - com.sun.star.comp.forms.ODatabaseForm
65 Private _ControlModel As Object &apos; com.sun.star.awt.XControlModel - com.sun.star.form.OGridControlModel
66 Private _ControlView As Object &apos; com.sun.star.awt.XControl - org.openoffice.comp.dbu.ODatasourceBrowser
67 Private _ColumnHeaders As Variant &apos; List of column headers as an array of strings
69 &apos; Cache for static toolbar descriptions
70 Private _Toolbars As Object &apos; SF_Dictionary instance to hold toolbars stored in application or in document
72 REM ============================================================ MODULE CONSTANTS
74 REM ====================================================== CONSTRUCTOR/DESTRUCTOR
76 REM -----------------------------------------------------------------------------
77 Private Sub Class_Initialize()
78 Set [Me] = Nothing
79 Set [_Parent] = Nothing
80 ObjectType = &quot;DATASHEET&quot;
81 ServiceName = &quot;SFDatabases.Datasheet&quot;
82 Set _Component = Nothing
83 Set _Frame = Nothing
84 Set _ParentBase = Nothing
85 Set _ParentDatabase = Nothing
86 _SheetType = &quot;&quot;
87 _ParentType = &quot;&quot;
88 _BaseFileName = &quot;&quot;
89 _Command = &quot;&quot;
90 _DirectSql = False
91 Set _TabControllerModel = Nothing
92 Set _ControlModel = Nothing
93 Set _ControlView = Nothing
94 _ColumnHeaders = Array()
95 Set _Toolbars = Nothing
96 End Sub &apos; SFDatabases.SF_Datasheet Constructor
98 REM -----------------------------------------------------------------------------
99 Private Sub Class_Terminate()
100 Call Class_Initialize()
101 End Sub &apos; SFDatabases.SF_Datasheet Destructor
103 REM -----------------------------------------------------------------------------
104 Public Function Dispose() As Variant
105 Call Class_Terminate()
106 Set Dispose = Nothing
107 End Function &apos; SFDatabases.SF_Datasheet Explicit Destructor
109 REM ================================================================== PROPERTIES
111 REM -----------------------------------------------------------------------------
112 Property Get ColumnHeaders() As Variant
113 &apos;&apos;&apos; Returns the list of column headers of the datasheet as an array of strings
114 ColumnHeaders = _PropertyGet(&quot;ColumnHeaders&quot;)
115 End Property &apos; SFDatabases.SF_Datasheet.ColumnHeaders
117 REM -----------------------------------------------------------------------------
118 Property Get CurrentColumn() As String
119 &apos;&apos;&apos; Returns the currently selected column by its name
120 CurrentColumn = _PropertyGet(&quot;CurrentColumn&quot;)
121 End Property &apos; SFDatabases.SF_Datasheet.CurrentColumn
123 REM -----------------------------------------------------------------------------
124 Property Get CurrentRow() As Long
125 &apos;&apos;&apos; Returns the currently selected row by its number &gt;= 1
126 CurrentRow = _PropertyGet(&quot;CurrentRow&quot;)
127 End Property &apos; SFDatabases.SF_Datasheet.CurrentRow
129 REM -----------------------------------------------------------------------------
130 Property Get DatabaseFileName() As String
131 &apos;&apos;&apos; Returns the file name of the Base file in FSO.FileNaming format
132 DatabaseFileName = _PropertyGet(&quot;DatabaseFileName&quot;)
133 End Property &apos; SFDatabases.SF_Datasheet.DatabaseFileName
135 REM -----------------------------------------------------------------------------
136 Property Get Filter() As Variant
137 &apos;&apos;&apos; The Filter is a SQL WHERE clause without the WHERE keyword
138 Filter = _PropertyGet(&quot;Filter&quot;)
139 End Property &apos; SFDatabases.SF_Datasheet.Filter (get)
141 REM -----------------------------------------------------------------------------
142 Property Let Filter(Optional ByVal pvFilter As Variant)
143 &apos;&apos;&apos; Set the updatable property Filter
144 &apos;&apos;&apos; Table and field names may be surrounded by square brackets
145 &apos;&apos;&apos; When the argument is the zero-length string, the actual filter is removed
146 _PropertySet(&quot;Filter&quot;, pvFilter)
147 End Property &apos; SFDatabases.SF_Datasheet.Filter (let)
149 REM -----------------------------------------------------------------------------
150 Property Get IsAlive() As Boolean
151 IsAlive = _PropertyGet(&quot;IsAlive&quot;)
152 End Property &apos; SFDatabases.SF_Datasheet.IsAlive
154 REM -----------------------------------------------------------------------------
155 Property Get LastRow() As Long
156 &apos;&apos;&apos; Returns the total number of rows
157 &apos;&apos;&apos; The process may imply to move the cursor to the last available row.
158 &apos;&apos;&apos; Afterwards the cursor is reset to the current row.
159 LastRow = _PropertyGet(&quot;LastRow&quot;)
160 End Property &apos; SFDatabases.SF_Datasheet.LastRow
162 REM -----------------------------------------------------------------------------
163 Property Get OrderBy() As Variant
164 &apos;&apos;&apos; The Order is a SQL ORDER BY clause without the ORDER BY keywords
165 OrderBy = _PropertyGet(&quot;OrderBy&quot;)
166 End Property &apos; SFDocuments.SF_Form.OrderBy (get)
168 REM -----------------------------------------------------------------------------
169 Property Let OrderBy(Optional ByVal pvOrderBy As Variant)
170 &apos;&apos;&apos; Set the updatable property OrderBy
171 &apos;&apos;&apos; Table and field names may be surrounded by square brackets
172 &apos;&apos;&apos; When the argument is the zero-length string, the actual sort is removed
173 _PropertySet(&quot;OrderBy&quot;, pvOrderBy)
174 End Property &apos; SFDocuments.SF_Form.OrderBy (let)
176 REM -----------------------------------------------------------------------------
177 Property Get ParentDatabase() As Object
178 &apos;&apos;&apos; Returns the database instance to which the datasheet belongs
179 Set ParentDatabase = _PropertyGet(&quot;ParentDatabase&quot;)
180 End Property &apos; SFDatabases.SF_Datasheet.ParentDatabase
182 REM -----------------------------------------------------------------------------
183 Property Get Source() As String
184 &apos;&apos;&apos; Returns the source of the data: table name, query name or sql statement
185 Source = _PropertyGet(&quot;Source&quot;)
186 End Property &apos; SFDatabases.SF_Datasheet.Source
188 REM -----------------------------------------------------------------------------
189 Property Get SourceType() As String
190 &apos;&apos;&apos; Returns thetype of source of the data: TABLE, QUERY or SQL
191 SourceType = _PropertyGet(&quot;SourceType&quot;)
192 End Property &apos; SFDatabases.SF_Datasheet.SourceType
194 REM -----------------------------------------------------------------------------
195 Property Get XComponent() As Object
196 &apos;&apos;&apos; Returns the com.sun.star.lang.XComponent UNO object representing the datasheet
197 XComponent = _PropertyGet(&quot;XComponent&quot;)
198 End Property &apos; SFDocuments.SF_Document.XComponent
200 REM -----------------------------------------------------------------------------
201 Property Get XControlModel() As Object
202 &apos;&apos;&apos; Returns the com.sun.star.lang.XControl UNO object representing the datasheet
203 XControlModel = _PropertyGet(&quot;XControlModel&quot;)
204 End Property &apos; SFDocuments.SF_Document.XControlModel
206 REM -----------------------------------------------------------------------------
207 Property Get XTabControllerModel() As Object
208 &apos;&apos;&apos; Returns the com.sun.star.lang.XTabControllerModel UNO object representing the datasheet
209 XTabControllerModel = _PropertyGet(&quot;XTabControllerModel&quot;)
210 End Property &apos; SFDocuments.SF_Document.XTabControllerModel
212 REM ===================================================================== METHODS
214 REM -----------------------------------------------------------------------------
215 Public Sub Activate()
216 &apos;&apos;&apos; Make the actual datasheet active
217 &apos;&apos;&apos; Args:
218 &apos;&apos;&apos; Returns:
219 &apos;&apos;&apos; Examples:
220 &apos;&apos;&apos; oSheet.Activate()
222 Dim oContainer As Object &apos; com.sun.star.awt.XWindow
223 Const cstThisSub = &quot;SFDatabases.Datasheet.Activate&quot;
224 Const cstSubArgs = &quot;&quot;
226 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
228 Check:
229 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
230 If Not _IsStillAlive() Then GoTo Finally
232 Try:
233 Set oContainer = _Component.Frame.ContainerWindow
234 With oContainer
235 If .isVisible() = False Then .setVisible(True)
236 .IsMinimized = False
237 .setFocus()
238 .toFront() &apos; Force window change in Linux
239 Wait 1 &apos; Bypass desynchro issue in Linux
240 End With
242 Finally:
243 SF_Utils._ExitFunction(cstThisSub)
244 Exit Sub
245 Catch:
246 GoTo Finally
247 End Sub &apos; SFDatabases.SF_Datasheet.Activate
249 REM -----------------------------------------------------------------------------
250 Public Function CloseDatasheet() As Boolean
251 &apos;&apos;&apos; Close the actual datasheet
252 &apos;&apos;&apos; Args:
253 &apos;&apos;&apos; Returns:
254 &apos;&apos;&apos; True when successful
255 &apos;&apos;&apos; Examples:
256 &apos;&apos;&apos; oSheet.CloseDatasheet()
258 Dim bClose As Boolean &apos; Return value
259 Const cstThisSub = &quot;SFDatabases.Datasheet.CloseDatasheet&quot;
260 Const cstSubArgs = &quot;&quot;
262 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
263 bClose = False
265 Check:
266 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
267 If Not _IsStillAlive() Then GoTo Finally
269 Try:
270 With _TabControllerModel
271 .ApplyFilter = False
272 .Filter = &quot;&quot;
273 .close()
274 End With
275 _Frame.close(True)
276 _Frame.dispose()
277 Dispose()
278 bClose = True
280 Finally:
281 CloseDatasheet = bClose
282 SF_Utils._ExitFunction(cstThisSub)
283 Exit Function
284 Catch:
285 GoTo Finally
286 End Function &apos; SFDatabases.SF_Datasheet.CloseDatasheet
288 REM -----------------------------------------------------------------------------
289 Public Function CreateMenu(Optional ByVal MenuHeader As Variant _
290 , Optional ByVal Before As Variant _
291 , Optional ByVal SubmenuChar As Variant _
292 ) As Object
293 &apos;&apos;&apos; Create a new menu entry in the datasheet&apos;s menubar
294 &apos;&apos;&apos; The menu is not intended to be saved neither in the LibreOffice global environment, nor elsewhere
295 &apos;&apos;&apos; The method returns a SFWidgets.Menu instance. Its methods let define the menu further.
296 &apos;&apos;&apos; Args:
297 &apos;&apos;&apos; MenuHeader: the name/header of the menu
298 &apos;&apos;&apos; Before: the place where to put the new menu on the menubar (string or number &gt;= 1)
299 &apos;&apos;&apos; When not found =&gt; last position
300 &apos;&apos;&apos; SubmenuChar: the delimiter used in menu trees. Default = &quot;&gt;&quot;
301 &apos;&apos;&apos; Returns:
302 &apos;&apos;&apos; A SFWidgets.Menu instance or Nothing
303 &apos;&apos;&apos; Examples:
304 &apos;&apos;&apos; Dim oMenu As Object
305 &apos;&apos;&apos; Set oMenu = oDoc.CreateMenu(&quot;My menu&quot;, Before := &quot;Styles&quot;)
306 &apos;&apos;&apos; With oMenu
307 &apos;&apos;&apos; .AddItem(&quot;Item 1&quot;, Command := &quot;.uno:About&quot;)
308 &apos;&apos;&apos; &apos;...
309 &apos;&apos;&apos; .Dispose() &apos; When definition is complete, the menu instance may be disposed
310 &apos;&apos;&apos; End With
311 &apos;&apos;&apos; &apos; ...
313 Dim oMenu As Object &apos; return value
314 Const cstThisSub = &quot;SFDatabases.Datasheet.CreateMenu&quot;
315 Const cstSubArgs = &quot;MenuHeader, [Before=&quot;&quot;&quot;&quot;], [SubmenuChar=&quot;&quot;&gt;&quot;&quot;]&quot;
317 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
318 Set oMenu = Nothing
320 Check:
321 If IsMissing(Before) Or IsEmpty(Before) Then Before = &quot;&quot;
322 If IsMissing(SubmenuChar) Or IsEmpty(SubmenuChar) Then SubmenuChar = &quot;&quot;
324 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
325 If Not _IsStillAlive() Then GoTo Finally
326 If Not ScriptForge.SF_Utils._Validate(MenuHeader, &quot;MenuHeader&quot;, V_STRING) Then GoTo Finally
327 If Not ScriptForge.SF_Utils._Validate(Before, &quot;Before&quot;, V_STRING) Then GoTo Finally
328 If Not ScriptForge.SF_Utils._Validate(SubmenuChar, &quot;SubmenuChar&quot;, V_STRING) Then GoTo Finally
329 End If
331 Try:
332 Set oMenu = ScriptForge.SF_Services.CreateScriptService(&quot;SFWidgets.Menu&quot;, _Component, MenuHeader, Before, SubmenuChar)
334 Finally:
335 Set CreateMenu = oMenu
336 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
337 Exit Function
338 Catch:
339 GoTo Finally
340 End Function &apos; SFDatabases.SF_Document.CreateMenu
342 REM -----------------------------------------------------------------------------
343 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
344 &apos;&apos;&apos; Return the actual value of the given property
345 &apos;&apos;&apos; Args:
346 &apos;&apos;&apos; PropertyName: the name of the property as a string
347 &apos;&apos;&apos; Returns:
348 &apos;&apos;&apos; The actual value of the propRATTCerty
349 &apos;&apos;&apos; If the property does not exist, returns Null
351 Const cstThisSub = &quot;SFDatabases.Datasheet.GetProperty&quot;
352 Const cstSubArgs = &quot;&quot;
354 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
355 GetProperty = Null
357 Check:
358 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
359 If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
360 End If
362 Try:
363 GetProperty = _PropertyGet(PropertyName)
365 Finally:
366 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
367 Exit Function
368 Catch:
369 GoTo Finally
370 End Function &apos; SFDatabases.SF_Datasheet.GetProperty
372 REM -----------------------------------------------------------------------------
373 Public Function GetText(Optional ByVal Column As Variant) As String
374 &apos;&apos;&apos; Get the text in the given column of the current row.
375 &apos;&apos;&apos; Args:
376 &apos;&apos;&apos; Column: the name of the column as a string or its position (&gt;= 1). Default = the current column
377 &apos;&apos;&apos; If the argument exceeds the number of columns, the last column is selected.
378 &apos;&apos;&apos; Returns:
379 &apos;&apos;&apos; The text in the cell as a string as how it is displayed
380 &apos;&apos;&apos; Note that the position of the cursor is left unchanged.
381 &apos;&apos;&apos; Examples:
382 &apos;&apos;&apos; oSheet.GetText(&quot;ShipCity&quot;)) &apos; Extract the text on the current row from the column &quot;ShipCity&quot;
384 Dim sText As String &apos; Return Text
385 Dim lCol As Long &apos; Numeric index of Column in lists of columns
386 Dim lMaxCol As Long &apos; Index of last column
387 Const cstThisSub = &quot;SFDatabases.Datasheet.GetText&quot;
388 Const cstSubArgs = &quot;[Column=0]&quot;
390 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
391 sText = &quot;&quot;
393 Check:
394 If IsMissing(Column) Or IsEmpty(Column) Then Column = 0
395 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
396 If Not _IsStillAlive() Then GoTo Finally
397 If VarType(Column) &lt;&gt; V_STRING Then
398 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
399 Else
400 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, V_STRING, _ColumnHeaders) Then GoTo Catch
401 End If
402 End If
404 Try:
405 &apos; Position the column - The index to be passed starts at 0
406 With _ControlView
407 If VarType(Column) = V_STRING Then
408 lCol = ScriptForge.SF_Array.IndexOf(_ColumnHeaders, Column, CaseSensitive := False)
409 Else
410 lCol = -1
411 If Column &gt;= 1 Then
412 lMaxCol = .Count - 1
413 If Column &gt; lMaxCol + 1 Then lCol = lMaxCol Else lCol = Column - 1
414 Else
415 lCol = .getCurrentColumnPosition()
416 End If
417 End If
419 If lCol &gt;= 0 Then sText = .getByIndex(lCol).Text
420 End With
422 Finally:
423 GetText = sText
424 SF_Utils._ExitFunction(cstThisSub)
425 Exit Function
426 Catch:
427 GoTo Finally
428 End Function &apos; SFDatabases.SF_Datasheet.GetText
430 REM -----------------------------------------------------------------------------
431 Public Function GetValue(Optional ByVal Column As Variant) As Variant
432 &apos;&apos;&apos; Get the value in the given column of the current row.
433 &apos;&apos;&apos; Args:
434 &apos;&apos;&apos; Column: the name of the column as a string or its position (&gt;= 1). Default = the current column
435 &apos;&apos;&apos; If the argument exceeds the number of columns, the last column is selected.
436 &apos;&apos;&apos; Returns:
437 &apos;&apos;&apos; The value in the cell as a valid Basic type
438 &apos;&apos;&apos; Typical types are: STRING, INTEGER, LONG, FLOAT, DOUBLE, DATE, NULL
439 &apos;&apos;&apos; Binary types are returned as a LONG giving their length, not their content
440 &apos;&apos;&apos; An EMPTY return value means that the value could not be retrieved.
441 &apos;&apos;&apos; Note that the position of the cursor is left unchanged.
442 &apos;&apos;&apos; Examples:
443 &apos;&apos;&apos; oSheet.GetValue(&quot;ShipCity&quot;)) &apos; Extract the value on the current row from the column &quot;ShipCity&quot;
445 Dim vValue As Variant &apos; Return value
446 Dim lCol As Long &apos; Numeric index of Column in lists of columns
447 Dim lMaxCol As Long &apos; Index of last column
448 Const cstThisSub = &quot;SFDatabases.Datasheet.GetValue&quot;
449 Const cstSubArgs = &quot;[Column=0]&quot;
451 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
452 vValue = Empty
454 Check:
455 If IsMissing(Column) Or IsEmpty(Column) Then Column = 0
456 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
457 If Not _IsStillAlive() Then GoTo Finally
458 If VarType(Column) &lt;&gt; V_STRING Then
459 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
460 Else
461 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, V_STRING, _ColumnHeaders) Then GoTo Catch
462 End If
463 End If
465 Try:
466 &apos; Position the column - The index to be passed starts at 1
467 If VarType(Column) = V_STRING Then
468 lCol = ScriptForge.SF_Array.IndexOf(_ColumnHeaders, Column, CaseSensitive := False) + 1
469 Else
470 With _ControlView
471 lCol = 0
472 If Column &gt;= 1 Then
473 lMaxCol = .Count
474 If Column &gt; lMaxCol Then lCol = lMaxCol Else lCol = Column
475 Else
476 lCol = .getCurrentColumnPosition() + 1
477 End If
478 End With
479 End If
481 &apos; The _TabControllerModel acts exactly as a result set, from which the generic _GetColumnValue can extract the searched value
482 If lCol &gt;= 1 Then vValue = _ParentDatabase._GetColumnValue(_TabControllerModel, lCol)
484 Finally:
485 GetValue = vValue
486 SF_Utils._ExitFunction(cstThisSub)
487 Exit Function
488 Catch:
489 GoTo Finally
490 End Function &apos; SFDatabases.SF_Datasheet.GetValue
492 REM -----------------------------------------------------------------------------
493 Public Function GoToCell(Optional ByVal Row As Variant _
494 , Optional ByVal Column As Variant _
495 ) As Boolean
496 &apos;&apos;&apos; Set the cursor on the given row and the given column.
497 &apos;&apos;&apos; If the requested row exceeds the number of available rows, the cursor is set on the last row.
498 &apos;&apos;&apos; If the requested column exceeds the number of available columns, the selected column is the last one.
499 &apos;&apos;&apos; Args:
500 &apos;&apos;&apos; Row: the row number (&gt;= 1) as a numeric value. Default= no change
501 &apos;&apos;&apos; Column: the name of the column as a string or its position (&gt;= 1). Default = the current column
502 &apos;&apos;&apos; Returns:
503 &apos;&apos;&apos; True when successful
504 &apos;&apos;&apos; Examples:
505 &apos;&apos;&apos; oSheet.GoToCell(1000000, &quot;ShipCity&quot;)) &apos; Set the cursor on he last row, column &quot;ShipCity&quot;
507 Dim bGoTo As Boolean &apos; Return value
508 Dim lCol As Long &apos; Numeric index of Column in list of columns
509 Dim lMaxCol As Long &apos; Index of last column
510 Const cstThisSub = &quot;SFDatabases.Datasheet.GoToCell&quot;
511 Const cstSubArgs = &quot;[Row=0], [Column=0]&quot;
513 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
514 bGoTo = False
516 Check:
517 If IsMissing(Row) Or IsEmpty(Row) Then Row = 0
518 If IsMissing(Column) Or IsEmpty(Column) Then Column = 0
519 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
520 If Not _IsStillAlive() Then GoTo Finally
521 If Not ScriptForge.SF_Utils._Validate(Row, &quot;Row&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
522 If VarType(Column) &lt;&gt; V_STRING Then
523 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
524 Else
525 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, V_STRING, _ColumnHeaders) Then GoTo Catch
526 End If
527 End If
529 Try:
530 &apos; Position the row
531 With _TabControllerModel
532 If Row &lt;= 0 Then Row = .Row Else .absolute(Row)
533 &apos; Does Row exceed the total number of rows ?
534 If .IsRowCountFinal And Row &gt; .RowCount Then .absolute(.RowCount)
535 End With
537 &apos; Position the column
538 With _ControlView
539 If VarType(Column) = V_STRING Then
540 lCol = ScriptForge.SF_Array.IndexOf(_ColumnHeaders, Column, CaseSensitive := False)
541 Else
542 lCol = -1
543 If Column &gt;= 1 Then
544 lMaxCol = .Count - 1
545 If Column &gt; lMaxCol + 1 Then lCol = lMaxCol Else lCol = Column - 1
546 End If
547 End If
548 If lCol &gt;= 0 Then .setCurrentColumnPosition(lCol)
549 End With
551 bGoTo = True
553 Finally:
554 GoToCell = bGoTo
555 SF_Utils._ExitFunction(cstThisSub)
556 Exit Function
557 Catch:
558 GoTo Finally
559 End Function &apos; SFDatabases.SF_Datasheet.GoToCell
561 REM -----------------------------------------------------------------------------
562 Public Function Methods() As Variant
563 &apos;&apos;&apos; Return the list of public methods of the Model service as an array
565 Methods = Array( _
566 &quot;Activate&quot; _
567 , &quot;CloseDatasheet&quot; _
568 , &quot;CreateMenu&quot; _
569 , &quot;GetText&quot; _
570 , &quot;GetValue&quot; _
571 , &quot;GoToCell&quot; _
572 , &quot;RemoveMenu&quot; _
575 End Function &apos; SFDatabases.SF_Datasheet.Methods
577 REM -----------------------------------------------------------------------------
578 Public Function Properties() As Variant
579 &apos;&apos;&apos; Return the list or properties of the Model class as an array
581 Properties = Array( _
582 &quot;ColumnHeaders&quot; _
583 , &quot;CurrentColumn&quot; _
584 , &quot;CurrentRow&quot; _
585 , &quot;DatabaseFileName&quot; _
586 , &quot;Filter&quot; _
587 , &quot;IsAlive&quot; _
588 , &quot;LastRow&quot; _
589 , &quot;OrderBy&quot; _
590 , &quot;ParentDatabase&quot; _
591 , &quot;Source&quot; _
592 , &quot;SourceType&quot; _
593 , &quot;XComponent&quot; _
594 , &quot;XControlModel&quot; _
595 , &quot;XTabControllerModel&quot; _
598 End Function &apos; SFDatabases.SF_Datasheet.Properties
600 REM -----------------------------------------------------------------------------
601 Public Function RemoveMenu(Optional ByVal MenuHeader As Variant) As Boolean
602 &apos;&apos;&apos; Remove a menu entry in the document&apos;s menubar
603 &apos;&apos;&apos; The removal is not intended to be saved neither in the LibreOffice global environment, nor in the document
604 &apos;&apos;&apos; Args:
605 &apos;&apos;&apos; MenuHeader: the name/header of the menu, without tilde &quot;~&quot;, as a case-sensitive string
606 &apos;&apos;&apos; Returns:
607 &apos;&apos;&apos; True when successful
608 &apos;&apos;&apos; Examples:
609 &apos;&apos;&apos; oDoc.RemoveMenu(&quot;File&quot;)
610 &apos;&apos;&apos; &apos; ...
612 Dim bRemove As Boolean &apos; Return value
613 Dim oLayout As Object &apos; com.sun.star.comp.framework.LayoutManager
614 Dim oMenuBar As Object &apos; com.sun.star.awt.XMenuBar or stardiv.Toolkit.VCLXMenuBar
615 Dim sName As String &apos; Menu name
616 Dim iMenuId As Integer &apos; Menu identifier
617 Dim iMenuPosition As Integer &apos; Menu position &gt;= 0
618 Dim i As Integer
619 Const cstTilde = &quot;~&quot;
621 Const cstThisSub = &quot;SFDatabases.Datasheet.RemoveMenu&quot;
622 Const cstSubArgs = &quot;MenuHeader&quot;
624 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
625 bRemove = False
627 Check:
628 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
629 If Not _IsStillAlive() Then GoTo Finally
630 If Not ScriptForge.SF_Utils._Validate(MenuHeader, &quot;MenuHeader&quot;, V_STRING) Then GoTo Finally
631 End If
633 Try:
634 Set oLayout = _Component.Frame.LayoutManager
635 Set oMenuBar = oLayout.getElement(&quot;private:resource/menubar/menubar&quot;).XMenuBar
637 &apos; Search the menu identifier to remove by its name, Mark its position
638 With oMenuBar
639 iMenuPosition = -1
640 For i = 0 To .ItemCount - 1
641 iMenuId = .getItemId(i)
642 sName = Replace(.getItemText(iMenuId), cstTilde, &quot;&quot;)
643 If MenuHeader= sName Then
644 iMenuPosition = i
645 Exit For
646 End If
647 Next i
648 &apos; Remove the found menu item
649 If iMenuPosition &gt;= 0 Then
650 .removeItem(iMenuPosition, 1)
651 bRemove = True
652 End If
653 End With
655 Finally:
656 RemoveMenu = bRemove
657 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
658 Exit Function
659 Catch:
660 GoTo Finally
661 End Function &apos; SFDatabases.SF_Datasheet.RemoveMenu
663 REM -----------------------------------------------------------------------------
664 Public Function SetProperty(Optional ByVal PropertyName As Variant _
665 , Optional ByRef Value As Variant _
666 ) As Boolean
667 &apos;&apos;&apos; Set a new value to the given property
668 &apos;&apos;&apos; Args:
669 &apos;&apos;&apos; PropertyName: the name of the property as a string
670 &apos;&apos;&apos; Value: its new value
671 &apos;&apos;&apos; Exceptions
672 &apos;&apos;&apos; ARGUMENTERROR The property does not exist
674 Const cstThisSub = &quot;SFDatabases.Datasheet.SetProperty&quot;
675 Const cstSubArgs = &quot;PropertyName, Value&quot;
677 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
678 SetProperty = False
680 Check:
681 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
682 If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
683 End If
685 Try:
686 SetProperty = _PropertySet(PropertyName, Value)
688 Finally:
689 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
690 Exit Function
691 Catch:
692 GoTo Finally
693 End Function &apos; SFDatabases.SF_Datasheet.SetProperty
695 REM -----------------------------------------------------------------------------
696 Public Function Toolbars(Optional ByVal ToolbarName As Variant) As Variant
697 &apos;&apos;&apos; Returns either a list of the available toolbar names in the actual document
698 &apos;&apos;&apos; or a Toolbar object instance.
699 &apos;&apos;&apos; [Function identical with SFDocuments.SF_Document.Toolbars()]
700 &apos;&apos;&apos; Args:
701 &apos;&apos;&apos; ToolbarName: the usual name of one of the available toolbars
702 &apos;&apos;&apos; Returns:
703 &apos;&apos;&apos; A zero-based array of toolbar names when the argument is absent,
704 &apos;&apos;&apos; or a new Toolbar object instance from the SF_Widgets library.
706 Const cstThisSub = &quot;SFDatabases.Datasheet.Toolbars&quot;
707 Const cstSubArgs = &quot;[ToolbarName=&quot;&quot;&quot;&quot;]&quot;
709 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
711 Check:
712 If IsMissing(ToolbarName) Or IsEmpty(ToolbarName) Then ToolbarName = &quot;&quot;
713 If IsNull(_Toolbars) Then _Toolbars = ScriptForge.SF_UI._ListToolbars(_Component)
714 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
715 If Not _IsStillAlive() Then GoTo Finally
716 If VarType(ToolbarName) = V_STRING Then
717 If Len(ToolbarName) &gt; 0 Then
718 If Not ScriptForge.SF_Utils._Validate(ToolbarName, &quot;ToolbarName&quot;, V_STRING, _Toolbars.Keys()) Then GoTo Finally
719 End If
720 Else
721 If Not ScriptForge.SF_Utils._Validate(ToolbarName, &quot;ToolbarName&quot;, V_STRING) Then GoTo Finally &apos; Manage here the VarType error
722 End If
723 End If
725 Try:
726 If Len(ToolbarName) = 0 Then
727 Toolbars = _Toolbars.Keys()
728 Else
729 Toolbars = CreateScriptService(&quot;SFWidgets.Toolbar&quot;, _Toolbars.Item(ToolbarName))
730 End If
732 Finally:
733 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
734 Exit Function
735 Catch:
736 GoTo Finally
737 End Function &apos; SF_Databases.SF_Datasheet.Toolbars
739 REM =========================================================== PRIVATE FUNCTIONS
741 REM -----------------------------------------------------------------------------
742 Public Sub _Initialize()
743 &apos;&apos;&apos; Called immediately after instance creation to complete the initial values
744 &apos;&apos;&apos; An eventual error must be trapped in the calling routine to cancel the instance creation
746 Dim iType As Integer &apos; One of the com.sun.star.sdb.CommandType constants
747 Dim oColumn As Object &apos; A single column
748 Dim oColumnDescriptor As Object &apos; A single column descriptor
749 Dim FSO As Object : Set FSO = ScriptForge.SF_FileSystem
750 Dim i As Long
752 Try:
753 If IsNull([_Parent]) Then _ParentType = &quot;&quot; Else _ParentType = [_Parent].ObjectType
755 With _Component
756 &apos; The existence of _Component.Selection must be checked upfront
757 _Command = ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;Command&quot;)
759 iType = ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;CommandType&quot;)
760 Select Case iType
761 Case com.sun.star.sdb.CommandType.TABLE : _SheetType = &quot;TABLE&quot;
762 Case com.sun.star.sdb.CommandType.QUERY : _SheetType = &quot;QUERY&quot;
763 Case com.sun.star.sdb.CommandType.COMMAND : _SheetType = &quot;SQL&quot;
764 End Select
766 _BaseFileName = ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;DataSourceName&quot;)
767 _DirectSql = Not ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;EscapeProcessing&quot;)
769 &apos; Useful UNO objects
770 Set _Frame = .Frame
771 Set _ControlView = .CurrentControl
772 Set _TabControllerModel = .com_sun_star_awt_XTabController_getModel()
773 Set _ControlModel = _ControlView.getModel()
774 End With
776 With _TabControllerModel
777 &apos; Retrieve the parent database instance
778 Select Case _ParentType
779 Case &quot;BASE&quot;
780 Set _ParentDatabase = [_Parent].GetDatabase(.User, .Password)
781 Set _ParentBase = [_Parent]
782 Case &quot;DATABASE&quot;
783 Set _ParentDatabase = [_Parent]
784 Set _ParentBase = Nothing
785 Case &quot;&quot; &apos; Derive the DATABASE instance from what can be found in the Component
786 Set _ParentDatabase = ScriptForge.SF_Services.CreateScriptService(&quot;SFDatabases.Database&quot; _
787 , FSO._ConvertFromUrl(_BaseFileName), , , .User, .Password)
788 _ParentType = &quot;DATABASE&quot;
789 Set _ParentBase = Nothing
790 End Select
791 &apos; Load column headers
792 _ColumnHeaders = .getColumns().getElementNames()
793 End With
795 Finally:
796 Exit Sub
797 End Sub &apos; SFDatabases.SF_Datasheet._Initialize
799 REM -----------------------------------------------------------------------------
800 Private Function _IsStillAlive(Optional ByVal pbError As Boolean) As Boolean
801 &apos;&apos;&apos; Returns True if the datasheet has not been closed manually or incidentally since the last use
802 &apos;&apos;&apos; If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
803 &apos;&apos;&apos; Args:
804 &apos;&apos;&apos; pbError: if True (default), raise a fatal error
806 Dim bAlive As Boolean &apos; Return value
807 Dim sName As String &apos; Used in error message
809 On Local Error GoTo Catch &apos; Anticipate DisposedException errors or alike
810 If IsMissing(pbError) Then pbError = True
812 Try:
813 &apos; Check existence of datasheet
814 bAlive = Not IsNull(_Component.ComponentWindow)
816 Finally:
817 If pbError And Not bAlive Then
818 sName = _Command
819 Dispose()
820 If pbError Then ScriptForge.SF_Exception.RaiseFatal(DOCUMENTDEADERROR, sName)
821 End If
822 _IsStillAlive = bAlive
823 Exit Function
824 Catch:
825 bAlive = False
826 On Error GoTo 0
827 GoTo Finally
828 End Function &apos; SFDatabases.SF_Datasheet._IsStillAlive
830 REM -----------------------------------------------------------------------------
831 Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
832 &apos;&apos;&apos; Return the value of the named property
833 &apos;&apos;&apos; Args:
834 &apos;&apos;&apos; psProperty: the name of the property
836 Dim lRow As Long &apos; Actual row number
837 Dim cstThisSub As String
838 Const cstSubArgs = &quot;&quot;
840 cstThisSub = &quot;SFDatabases.Datasheet.get&quot; &amp; psProperty
841 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
843 ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
844 If psProperty &lt;&gt; &quot;IsAlive&quot; Then
845 If Not _IsStillAlive() Then GoTo Finally
846 End If
848 Select Case psProperty
849 Case &quot;ColumnHeaders&quot;
850 _PropertyGet = _ColumnHeaders
851 Case &quot;CurrentColumn&quot;
852 _PropertyGet = _ColumnHeaders(_ControlView.getCurrentColumnPosition())
853 Case &quot;CurrentRow&quot;
854 _PropertyGet = _TabControllerModel.Row
855 Case &quot;DatabaseFileName&quot;
856 _PropertyGet = ScriptForge.SF_FileSystem._ConvertFromUrl(_BaseFileName)
857 Case &quot;Filter&quot;
858 _PropertyGet = _TabControllerModel.Filter
859 Case &quot;IsAlive&quot;
860 _PropertyGet = _IsStillAlive(False)
861 Case &quot;LastRow&quot;
862 With _TabControllerModel
863 If .IsRowCountFinal Then
864 _PropertyGet = .RowCount
865 Else
866 lRow = .Row
867 If lRow &gt; 0 Then
868 .last()
869 _PropertyGet = .RowCount
870 .absolute(lRow)
871 Else
872 _PropertyGet = 0
873 End If
874 End If
875 End With
876 Case &quot;OrderBy&quot;
877 _PropertyGet = _TabControllerModel.Order
878 Case &quot;ParentDatabase&quot;
879 Set _PropertyGet = _ParentDatabase
880 Case &quot;Source&quot;
881 _PropertyGet = _Command
882 Case &quot;SourceType&quot;
883 _PropertyGet = _SheetType
884 Case &quot;XComponent&quot;
885 Set _PropertyGet = _Component
886 Case &quot;XControlModel&quot;
887 Set _PropertyGet = _ControlModel
888 Case &quot;XTabControllerModel&quot;
889 Set _PropertyGet = _TabControllerModel
890 Case Else
891 _PropertyGet = Null
892 End Select
894 Finally:
895 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
896 Exit Function
897 Catch:
898 GoTo Finally
899 End Function &apos; SFDatabases.SF_Datasheet._PropertyGet
901 REM -----------------------------------------------------------------------------
902 Private Function _PropertySet(Optional ByVal psProperty As String _
903 , Optional ByVal pvValue As Variant _
904 ) As Boolean
905 &apos;&apos;&apos; Set the new value of the named property
906 &apos;&apos;&apos; Args:
907 &apos;&apos;&apos; psProperty: the name of the property
908 &apos;&apos;&apos; pvValue: the new value of the given property
909 &apos;&apos;&apos; Returns:
910 &apos;&apos;&apos; True if successful
912 Dim bSet As Boolean &apos; Return value
913 Dim cstThisSub As String
914 Const cstSubArgs = &quot;Value&quot;
916 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
917 bSet = False
919 cstThisSub = &quot;SFDatabases.Datasheet.set&quot; &amp; psProperty
920 ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
921 If Not _IsStillAlive() Then GoTo Finally
923 bSet = True
924 Select Case UCase(psProperty)
925 Case UCase(&quot;Filter&quot;)
926 If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Filter&quot;, V_STRING) Then GoTo Finally
927 With _TabControllerModel
928 If Len(pvValue) &gt; 0 Then .Filter = _ParentDatabase._ReplaceSquareBrackets(pvValue) Else .Filter = &quot;&quot;
929 .ApplyFilter = ( Len(pvValue) &gt; 0 )
930 .reload()
931 End With
932 Case UCase(&quot;OrderBy&quot;)
933 If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;OrderBy&quot;, V_STRING) Then GoTo Finally
934 With _TabControllerModel
935 If Len(pvValue) &gt; 0 Then .Order = _ParentDatabase._ReplaceSquareBrackets(pvValue) Else .Order = &quot;&quot;
936 .reload()
937 End With
938 Case Else
939 bSet = False
940 End Select
942 Finally:
943 _PropertySet = bSet
944 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
945 Exit Function
946 Catch:
947 GoTo Finally
948 End Function &apos; SFDatabases.SF_Datasheet._PropertySet
950 REM -----------------------------------------------------------------------------
951 Private Function _Repr() As String
952 &apos;&apos;&apos; Convert the Datasheet instance to a readable string, typically for debugging purposes (DebugPrint ...)
953 &apos;&apos;&apos; Args:
954 &apos;&apos;&apos; Return:
955 &apos;&apos;&apos; &quot;[DATASHEET]: tablename,base file url&quot;
957 _Repr = &quot;[DATASHEET]: &quot; &amp; _Command &amp; &quot;,&quot; &amp; _BaseFileName
959 End Function &apos; SFDatabases.SF_Datasheet._Repr
961 REM ============================================ END OF SFDATABASES.SF_DATASHEET
962 </script:module>