Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / wizards / source / sfdatabases / SF_Datasheet.xba
blob775984f60d6f26a608ede7e0a076e67fc4b7c7f5
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 LastRow() As Long
151 &apos;&apos;&apos; Returns the total number of rows
152 &apos;&apos;&apos; The process may imply to move the cursor to the last available row.
153 &apos;&apos;&apos; Afterwards the cursor is reset to the current row.
154 LastRow = _PropertyGet(&quot;LastRow&quot;)
155 End Property &apos; SFDatabases.SF_Datasheet.LastRow
157 REM -----------------------------------------------------------------------------
158 Property Get OrderBy() As Variant
159 &apos;&apos;&apos; The Order is a SQL ORDER BY clause without the ORDER BY keywords
160 OrderBy = _PropertyGet(&quot;OrderBy&quot;)
161 End Property &apos; SFDocuments.SF_Form.OrderBy (get)
163 REM -----------------------------------------------------------------------------
164 Property Let OrderBy(Optional ByVal pvOrderBy As Variant)
165 &apos;&apos;&apos; Set the updatable property OrderBy
166 &apos;&apos;&apos; Table and field names may be surrounded by square brackets
167 &apos;&apos;&apos; When the argument is the zero-length string, the actual sort is removed
168 _PropertySet(&quot;OrderBy&quot;, pvOrderBy)
169 End Property &apos; SFDocuments.SF_Form.OrderBy (let)
171 REM -----------------------------------------------------------------------------
172 Property Get ParentDatabase() As Object
173 &apos;&apos;&apos; Returns the database instance to which the datasheet belongs
174 Set ParentDatabase = _PropertyGet(&quot;ParentDatabase&quot;)
175 End Property &apos; SFDatabases.SF_Datasheet.ParentDatabase
177 REM -----------------------------------------------------------------------------
178 Property Get Source() As String
179 &apos;&apos;&apos; Returns the source of the data: table name, query name or sql statement
180 Source = _PropertyGet(&quot;Source&quot;)
181 End Property &apos; SFDatabases.SF_Datasheet.Source
183 REM -----------------------------------------------------------------------------
184 Property Get SourceType() As String
185 &apos;&apos;&apos; Returns thetype of source of the data: TABLE, QUERY or SQL
186 SourceType = _PropertyGet(&quot;SourceType&quot;)
187 End Property &apos; SFDatabases.SF_Datasheet.SourceType
189 REM -----------------------------------------------------------------------------
190 Property Get XComponent() As Object
191 &apos;&apos;&apos; Returns the com.sun.star.lang.XComponent UNO object representing the datasheet
192 XComponent = _PropertyGet(&quot;XComponent&quot;)
193 End Property &apos; SFDocuments.SF_Document.XComponent
195 REM -----------------------------------------------------------------------------
196 Property Get XControlModel() As Object
197 &apos;&apos;&apos; Returns the com.sun.star.lang.XControl UNO object representing the datasheet
198 XControlModel = _PropertyGet(&quot;XControlModel&quot;)
199 End Property &apos; SFDocuments.SF_Document.XControlModel
201 REM -----------------------------------------------------------------------------
202 Property Get XTabControllerModel() As Object
203 &apos;&apos;&apos; Returns the com.sun.star.lang.XTabControllerModel UNO object representing the datasheet
204 XTabControllerModel = _PropertyGet(&quot;XTabControllerModel&quot;)
205 End Property &apos; SFDocuments.SF_Document.XTabControllerModel
207 REM ===================================================================== METHODS
209 REM -----------------------------------------------------------------------------
210 Public Sub Activate()
211 &apos;&apos;&apos; Make the actual datasheet active
212 &apos;&apos;&apos; Args:
213 &apos;&apos;&apos; Returns:
214 &apos;&apos;&apos; Examples:
215 &apos;&apos;&apos; oSheet.Activate()
217 Dim oContainer As Object &apos; com.sun.star.awt.XWindow
218 Const cstThisSub = &quot;SFDatabases.Datasheet.Activate&quot;
219 Const cstSubArgs = &quot;&quot;
221 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
223 Check:
224 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
225 If Not _IsStillAlive() Then GoTo Finally
227 Try:
228 Set oContainer = _Component.Frame.ContainerWindow
229 With oContainer
230 If .isVisible() = False Then .setVisible(True)
231 .IsMinimized = False
232 .setFocus()
233 .toFront() &apos; Force window change in Linux
234 Wait 1 &apos; Bypass desynchro issue in Linux
235 End With
237 Finally:
238 SF_Utils._ExitFunction(cstThisSub)
239 Exit Sub
240 Catch:
241 GoTo Finally
242 End Sub &apos; SFDatabases.SF_Datasheet.Activate
244 REM -----------------------------------------------------------------------------
245 Public Function CloseDatasheet() As Boolean
246 &apos;&apos;&apos; Close the actual datasheet
247 &apos;&apos;&apos; Args:
248 &apos;&apos;&apos; Returns:
249 &apos;&apos;&apos; True when successful
250 &apos;&apos;&apos; Examples:
251 &apos;&apos;&apos; oSheet.CloseDatasheet()
253 Dim bClose As Boolean &apos; Return value
254 Const cstThisSub = &quot;SFDatabases.Datasheet.CloseDatasheet&quot;
255 Const cstSubArgs = &quot;&quot;
257 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
258 bClose = False
260 Check:
261 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
262 If Not _IsStillAlive() Then GoTo Finally
264 Try:
265 With _TabControllerModel
266 .ApplyFilter = False
267 .Filter = &quot;&quot;
268 .close()
269 End With
270 _Frame.close(True)
271 _Frame.dispose()
272 Dispose()
273 bClose = True
275 Finally:
276 CloseDatasheet = bClose
277 SF_Utils._ExitFunction(cstThisSub)
278 Exit Function
279 Catch:
280 GoTo Finally
281 End Function &apos; SFDatabases.SF_Datasheet.CloseDatasheet
283 REM -----------------------------------------------------------------------------
284 Public Function CreateMenu(Optional ByVal MenuHeader As Variant _
285 , Optional ByVal Before As Variant _
286 , Optional ByVal SubmenuChar As Variant _
287 ) As Object
288 &apos;&apos;&apos; Create a new menu entry in the datasheet&apos;s menubar
289 &apos;&apos;&apos; The menu is not intended to be saved neither in the LibreOffice global environment, nor elsewhere
290 &apos;&apos;&apos; The method returns a SFWidgets.Menu instance. Its methods let define the menu further.
291 &apos;&apos;&apos; Args:
292 &apos;&apos;&apos; MenuHeader: the name/header of the menu
293 &apos;&apos;&apos; Before: the place where to put the new menu on the menubar (string or number &gt;= 1)
294 &apos;&apos;&apos; When not found =&gt; last position
295 &apos;&apos;&apos; SubmenuChar: the delimiter used in menu trees. Default = &quot;&gt;&quot;
296 &apos;&apos;&apos; Returns:
297 &apos;&apos;&apos; A SFWidgets.Menu instance or Nothing
298 &apos;&apos;&apos; Examples:
299 &apos;&apos;&apos; Dim oMenu As Object
300 &apos;&apos;&apos; Set oMenu = oDoc.CreateMenu(&quot;My menu&quot;, Before := &quot;Styles&quot;)
301 &apos;&apos;&apos; With oMenu
302 &apos;&apos;&apos; .AddItem(&quot;Item 1&quot;, Command := &quot;.uno:About&quot;)
303 &apos;&apos;&apos; &apos;...
304 &apos;&apos;&apos; .Dispose() &apos; When definition is complete, the menu instance may be disposed
305 &apos;&apos;&apos; End With
306 &apos;&apos;&apos; &apos; ...
308 Dim oMenu As Object &apos; return value
309 Const cstThisSub = &quot;SFDatabases.Datasheet.CreateMenu&quot;
310 Const cstSubArgs = &quot;MenuHeader, [Before=&quot;&quot;&quot;&quot;], [SubmenuChar=&quot;&quot;&gt;&quot;&quot;]&quot;
312 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
313 Set oMenu = Nothing
315 Check:
316 If IsMissing(Before) Or IsEmpty(Before) Then Before = &quot;&quot;
317 If IsMissing(SubmenuChar) Or IsEmpty(SubmenuChar) Then SubmenuChar = &quot;&quot;
319 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
320 If Not _IsStillAlive() Then GoTo Finally
321 If Not ScriptForge.SF_Utils._Validate(MenuHeader, &quot;MenuHeader&quot;, V_STRING) Then GoTo Finally
322 If Not ScriptForge.SF_Utils._Validate(Before, &quot;Before&quot;, V_STRING) Then GoTo Finally
323 If Not ScriptForge.SF_Utils._Validate(SubmenuChar, &quot;SubmenuChar&quot;, V_STRING) Then GoTo Finally
324 End If
326 Try:
327 Set oMenu = ScriptForge.SF_Services.CreateScriptService(&quot;SFWidgets.Menu&quot;, _Component, MenuHeader, Before, SubmenuChar)
329 Finally:
330 Set CreateMenu = oMenu
331 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
332 Exit Function
333 Catch:
334 GoTo Finally
335 End Function &apos; SFDatabases.SF_Document.CreateMenu
337 REM -----------------------------------------------------------------------------
338 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
339 &apos;&apos;&apos; Return the actual value of the given property
340 &apos;&apos;&apos; Args:
341 &apos;&apos;&apos; PropertyName: the name of the property as a string
342 &apos;&apos;&apos; Returns:
343 &apos;&apos;&apos; The actual value of the propRATTCerty
344 &apos;&apos;&apos; If the property does not exist, returns Null
346 Const cstThisSub = &quot;SFDatabases.Datasheet.GetProperty&quot;
347 Const cstSubArgs = &quot;&quot;
349 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
350 GetProperty = Null
352 Check:
353 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
354 If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
355 End If
357 Try:
358 GetProperty = _PropertyGet(PropertyName)
360 Finally:
361 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
362 Exit Function
363 Catch:
364 GoTo Finally
365 End Function &apos; SFDatabases.SF_Datasheet.GetProperty
367 REM -----------------------------------------------------------------------------
368 Public Function GetText(Optional ByVal Column As Variant) As String
369 &apos;&apos;&apos; Get the text in the given column of the current row.
370 &apos;&apos;&apos; Args:
371 &apos;&apos;&apos; Column: the name of the column as a string or its position (&gt;= 1). Default = the current column
372 &apos;&apos;&apos; If the argument exceeds the number of columns, the last column is selected.
373 &apos;&apos;&apos; Returns:
374 &apos;&apos;&apos; The text in the cell as a string as how it is displayed
375 &apos;&apos;&apos; Note that the position of the cursor is left unchanged.
376 &apos;&apos;&apos; Examples:
377 &apos;&apos;&apos; oSheet.GetText(&quot;ShipCity&quot;)) &apos; Extract the text on the current row from the column &quot;ShipCity&quot;
379 Dim sText As String &apos; Return Text
380 Dim lCol As Long &apos; Numeric index of Column in lists of columns
381 Dim lMaxCol As Long &apos; Index of last column
382 Const cstThisSub = &quot;SFDatabases.Datasheet.GetText&quot;
383 Const cstSubArgs = &quot;[Column=0]&quot;
385 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
386 sText = &quot;&quot;
388 Check:
389 If IsMissing(Column) Or IsEmpty(Column) Then Column = 0
390 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
391 If Not _IsStillAlive() Then GoTo Finally
392 If VarType(Column) &lt;&gt; V_STRING Then
393 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
394 Else
395 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, V_STRING, _ColumnHeaders) Then GoTo Catch
396 End If
397 End If
399 Try:
400 &apos; Position the column - The index to be passed starts at 0
401 With _ControlView
402 If VarType(Column) = V_STRING Then
403 lCol = ScriptForge.SF_Array.IndexOf(_ColumnHeaders, Column, CaseSensitive := False)
404 Else
405 lCol = -1
406 If Column &gt;= 1 Then
407 lMaxCol = .Count - 1
408 If Column &gt; lMaxCol + 1 Then lCol = lMaxCol Else lCol = Column - 1
409 Else
410 lCol = .getCurrentColumnPosition()
411 End If
412 End If
414 If lCol &gt;= 0 Then sText = .getByIndex(lCol).Text
415 End With
417 Finally:
418 GetText = sText
419 SF_Utils._ExitFunction(cstThisSub)
420 Exit Function
421 Catch:
422 GoTo Finally
423 End Function &apos; SFDatabases.SF_Datasheet.GetText
425 REM -----------------------------------------------------------------------------
426 Public Function GetValue(Optional ByVal Column As Variant) As Variant
427 &apos;&apos;&apos; Get the value in the given column of the current row.
428 &apos;&apos;&apos; Args:
429 &apos;&apos;&apos; Column: the name of the column as a string or its position (&gt;= 1). Default = the current column
430 &apos;&apos;&apos; If the argument exceeds the number of columns, the last column is selected.
431 &apos;&apos;&apos; Returns:
432 &apos;&apos;&apos; The value in the cell as a valid Basic type
433 &apos;&apos;&apos; Typical types are: STRING, INTEGER, LONG, FLOAT, DOUBLE, DATE, NULL
434 &apos;&apos;&apos; Binary types are returned as a LONG giving their length, not their content
435 &apos;&apos;&apos; An EMPTY return value means that the value could not be retrieved.
436 &apos;&apos;&apos; Note that the position of the cursor is left unchanged.
437 &apos;&apos;&apos; Examples:
438 &apos;&apos;&apos; oSheet.GetValue(&quot;ShipCity&quot;)) &apos; Extract the value on the current row from the column &quot;ShipCity&quot;
440 Dim vValue As Variant &apos; Return value
441 Dim lCol As Long &apos; Numeric index of Column in lists of columns
442 Dim lMaxCol As Long &apos; Index of last column
443 Const cstThisSub = &quot;SFDatabases.Datasheet.GetValue&quot;
444 Const cstSubArgs = &quot;[Column=0]&quot;
446 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
447 vValue = Empty
449 Check:
450 If IsMissing(Column) Or IsEmpty(Column) Then Column = 0
451 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
452 If Not _IsStillAlive() Then GoTo Finally
453 If VarType(Column) &lt;&gt; V_STRING Then
454 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
455 Else
456 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, V_STRING, _ColumnHeaders) Then GoTo Catch
457 End If
458 End If
460 Try:
461 &apos; Position the column - The index to be passed starts at 1
462 If VarType(Column) = V_STRING Then
463 lCol = ScriptForge.SF_Array.IndexOf(_ColumnHeaders, Column, CaseSensitive := False) + 1
464 Else
465 With _ControlView
466 lCol = 0
467 If Column &gt;= 1 Then
468 lMaxCol = .Count
469 If Column &gt; lMaxCol Then lCol = lMaxCol Else lCol = Column
470 Else
471 lCol = .getCurrentColumnPosition() + 1
472 End If
473 End With
474 End If
476 &apos; The _TabControllerModel acts exactly as a result set, from which the generic _GetColumnValue can extract the searched value
477 If lCol &gt;= 1 Then vValue = _ParentDatabase._GetColumnValue(_TabControllerModel, lCol)
479 Finally:
480 GetValue = vValue
481 SF_Utils._ExitFunction(cstThisSub)
482 Exit Function
483 Catch:
484 GoTo Finally
485 End Function &apos; SFDatabases.SF_Datasheet.GetValue
487 REM -----------------------------------------------------------------------------
488 Public Function GoToCell(Optional ByVal Row As Variant _
489 , Optional ByVal Column As Variant _
490 ) As Boolean
491 &apos;&apos;&apos; Set the cursor on the given row and the given column.
492 &apos;&apos;&apos; If the requested row exceeds the number of available rows, the cursor is set on the last row.
493 &apos;&apos;&apos; If the requested column exceeds the number of available columns, the selected column is the last one.
494 &apos;&apos;&apos; Args:
495 &apos;&apos;&apos; Row: the row number (&gt;= 1) as a numeric value. Default= no change
496 &apos;&apos;&apos; Column: the name of the column as a string or its position (&gt;= 1). Default = the current column
497 &apos;&apos;&apos; Returns:
498 &apos;&apos;&apos; True when successful
499 &apos;&apos;&apos; Examples:
500 &apos;&apos;&apos; oSheet.GoToCell(1000000, &quot;ShipCity&quot;)) &apos; Set the cursor on he last row, column &quot;ShipCity&quot;
502 Dim bGoTo As Boolean &apos; Return value
503 Dim lCol As Long &apos; Numeric index of Column in list of columns
504 Dim lMaxCol As Long &apos; Index of last column
505 Const cstThisSub = &quot;SFDatabases.Datasheet.GoToCell&quot;
506 Const cstSubArgs = &quot;[Row=0], [Column=0]&quot;
508 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
509 bGoTo = False
511 Check:
512 If IsMissing(Row) Or IsEmpty(Row) Then Row = 0
513 If IsMissing(Column) Or IsEmpty(Column) Then Column = 0
514 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
515 If Not _IsStillAlive() Then GoTo Finally
516 If Not ScriptForge.SF_Utils._Validate(Row, &quot;Row&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
517 If VarType(Column) &lt;&gt; V_STRING Then
518 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, ScriptForge.V_NUMERIC) Then GoTo Catch
519 Else
520 If Not ScriptForge.SF_Utils._Validate(Column, &quot;Column&quot;, V_STRING, _ColumnHeaders) Then GoTo Catch
521 End If
522 End If
524 Try:
525 &apos; Position the row
526 With _TabControllerModel
527 If Row &lt;= 0 Then Row = .Row Else .absolute(Row)
528 &apos; Does Row exceed the total number of rows ?
529 If .IsRowCountFinal And Row &gt; .RowCount Then .absolute(.RowCount)
530 End With
532 &apos; Position the column
533 With _ControlView
534 If VarType(Column) = V_STRING Then
535 lCol = ScriptForge.SF_Array.IndexOf(_ColumnHeaders, Column, CaseSensitive := False)
536 Else
537 lCol = -1
538 If Column &gt;= 1 Then
539 lMaxCol = .Count - 1
540 If Column &gt; lMaxCol + 1 Then lCol = lMaxCol Else lCol = Column - 1
541 End If
542 End If
543 If lCol &gt;= 0 Then .setCurrentColumnPosition(lCol)
544 End With
546 bGoTo = True
548 Finally:
549 GoToCell = bGoTo
550 SF_Utils._ExitFunction(cstThisSub)
551 Exit Function
552 Catch:
553 GoTo Finally
554 End Function &apos; SFDatabases.SF_Datasheet.GoToCell
556 REM -----------------------------------------------------------------------------
557 Public Function Methods() As Variant
558 &apos;&apos;&apos; Return the list of public methods of the Model service as an array
560 Methods = Array( _
561 &quot;Activate&quot; _
562 , &quot;CloseDatasheet&quot; _
563 , &quot;CreateMenu&quot; _
564 , &quot;GetText&quot; _
565 , &quot;GetValue&quot; _
566 , &quot;GoToCell&quot; _
567 , &quot;RemoveMenu&quot; _
570 End Function &apos; SFDatabases.SF_Datasheet.Methods
572 REM -----------------------------------------------------------------------------
573 Public Function Properties() As Variant
574 &apos;&apos;&apos; Return the list or properties of the Model class as an array
576 Properties = Array( _
577 &quot;ColumnHeaders&quot; _
578 , &quot;CurrentColumn&quot; _
579 , &quot;CurrentRow&quot; _
580 , &quot;DatabaseFileName&quot; _
581 , &quot;Filter&quot; _
582 , &quot;LastRow&quot; _
583 , &quot;OrderBy&quot; _
584 , &quot;ParentDatabase&quot; _
585 , &quot;Source&quot; _
586 , &quot;SourceType&quot; _
587 , &quot;XComponent&quot; _
588 , &quot;XControlModel&quot; _
589 , &quot;XTabControllerModel&quot; _
592 End Function &apos; SFDatabases.SF_Datasheet.Properties
594 REM -----------------------------------------------------------------------------
595 Public Function RemoveMenu(Optional ByVal MenuHeader As Variant) As Boolean
596 &apos;&apos;&apos; Remove a menu entry in the document&apos;s menubar
597 &apos;&apos;&apos; The removal is not intended to be saved neither in the LibreOffice global environment, nor in the document
598 &apos;&apos;&apos; Args:
599 &apos;&apos;&apos; MenuHeader: the name/header of the menu, without tilde &quot;~&quot;, as a case-sensitive string
600 &apos;&apos;&apos; Returns:
601 &apos;&apos;&apos; True when successful
602 &apos;&apos;&apos; Examples:
603 &apos;&apos;&apos; oDoc.RemoveMenu(&quot;File&quot;)
604 &apos;&apos;&apos; &apos; ...
606 Dim bRemove As Boolean &apos; Return value
607 Dim oLayout As Object &apos; com.sun.star.comp.framework.LayoutManager
608 Dim oMenuBar As Object &apos; com.sun.star.awt.XMenuBar or stardiv.Toolkit.VCLXMenuBar
609 Dim sName As String &apos; Menu name
610 Dim iMenuId As Integer &apos; Menu identifier
611 Dim iMenuPosition As Integer &apos; Menu position &gt;= 0
612 Dim i As Integer
613 Const cstTilde = &quot;~&quot;
615 Const cstThisSub = &quot;SFDatabases.Datasheet.RemoveMenu&quot;
616 Const cstSubArgs = &quot;MenuHeader&quot;
618 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
619 bRemove = False
621 Check:
622 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
623 If Not _IsStillAlive() Then GoTo Finally
624 If Not ScriptForge.SF_Utils._Validate(MenuHeader, &quot;MenuHeader&quot;, V_STRING) Then GoTo Finally
625 End If
627 Try:
628 Set oLayout = _Component.Frame.LayoutManager
629 Set oMenuBar = oLayout.getElement(&quot;private:resource/menubar/menubar&quot;).XMenuBar
631 &apos; Search the menu identifier to remove by its name, Mark its position
632 With oMenuBar
633 iMenuPosition = -1
634 For i = 0 To .ItemCount - 1
635 iMenuId = .getItemId(i)
636 sName = Replace(.getItemText(iMenuId), cstTilde, &quot;&quot;)
637 If MenuHeader= sName Then
638 iMenuPosition = i
639 Exit For
640 End If
641 Next i
642 &apos; Remove the found menu item
643 If iMenuPosition &gt;= 0 Then
644 .removeItem(iMenuPosition, 1)
645 bRemove = True
646 End If
647 End With
649 Finally:
650 RemoveMenu = bRemove
651 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
652 Exit Function
653 Catch:
654 GoTo Finally
655 End Function &apos; SFDatabases.SF_Datasheet.RemoveMenu
657 REM -----------------------------------------------------------------------------
658 Public Function SetProperty(Optional ByVal PropertyName As Variant _
659 , Optional ByRef Value As Variant _
660 ) As Boolean
661 &apos;&apos;&apos; Set a new value to the given property
662 &apos;&apos;&apos; Args:
663 &apos;&apos;&apos; PropertyName: the name of the property as a string
664 &apos;&apos;&apos; Value: its new value
665 &apos;&apos;&apos; Exceptions
666 &apos;&apos;&apos; ARGUMENTERROR The property does not exist
668 Const cstThisSub = &quot;SFDatabases.Datasheet.SetProperty&quot;
669 Const cstSubArgs = &quot;PropertyName, Value&quot;
671 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
672 SetProperty = False
674 Check:
675 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
676 If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
677 End If
679 Try:
680 SetProperty = _PropertySet(PropertyName, Value)
682 Finally:
683 SF_Utils._ExitFunction(cstThisSub)
684 Exit Function
685 Catch:
686 GoTo Finally
687 End Function &apos; SFDatabases.SF_Datasheet.SetProperty
689 REM -----------------------------------------------------------------------------
690 Public Function Toolbars(Optional ByVal ToolbarName As Variant) As Variant
691 &apos;&apos;&apos; Returns either a list of the available toolbar names in the actual document
692 &apos;&apos;&apos; or a Toolbar object instance.
693 &apos;&apos;&apos; [Function identical with SFDocuments.SF_Document.Toolbars()]
694 &apos;&apos;&apos; Args:
695 &apos;&apos;&apos; ToolbarName: the usual name of one of the available toolbars
696 &apos;&apos;&apos; Returns:
697 &apos;&apos;&apos; A zero-based array of toolbar names when the argument is absent,
698 &apos;&apos;&apos; or a new Toolbar object instance from the SF_Widgets library.
700 Const cstThisSub = &quot;SFDatabases.Datasheet.Toolbars&quot;
701 Const cstSubArgs = &quot;[ToolbarName=&quot;&quot;&quot;&quot;]&quot;
703 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
705 Check:
706 If IsMissing(ToolbarName) Or IsEmpty(ToolbarName) Then ToolbarName = &quot;&quot;
707 If IsNull(_Toolbars) Then _Toolbars = ScriptForge.SF_UI._ListToolbars(_Component)
708 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
709 If Not _IsStillAlive() Then GoTo Finally
710 If VarType(ToolbarName) = V_STRING Then
711 If Len(ToolbarName) &gt; 0 Then
712 If Not ScriptForge.SF_Utils._Validate(ToolbarName, &quot;ToolbarName&quot;, V_STRING, _Toolbars.Keys()) Then GoTo Finally
713 End If
714 Else
715 If Not ScriptForge.SF_Utils._Validate(ToolbarName, &quot;ToolbarName&quot;, V_STRING) Then GoTo Finally &apos; Manage here the VarType error
716 End If
717 End If
719 Try:
720 If Len(ToolbarName) = 0 Then
721 Toolbars = _Toolbars.Keys()
722 Else
723 Toolbars = CreateScriptService(&quot;SFWidgets.Toolbar&quot;, _Toolbars.Item(ToolbarName))
724 End If
726 Finally:
727 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
728 Exit Function
729 Catch:
730 GoTo Finally
731 End Function &apos; SF_Databases.SF_Datasheet.Toolbars
733 REM =========================================================== PRIVATE FUNCTIONS
735 REM -----------------------------------------------------------------------------
736 Public Sub _Initialize()
737 &apos;&apos;&apos; Called immediately after instance creation to complete the initial values
738 &apos;&apos;&apos; An eventual error must be trapped in the calling routine to cancel the instance creation
740 Dim iType As Integer &apos; One of the com.sun.star.sdb.CommandType constants
741 Dim oColumn As Object &apos; A single column
742 Dim oColumnDescriptor As Object &apos; A single column descriptor
743 Dim FSO As Object : Set FSO = ScriptForge.SF_FileSystem
744 Dim i As Long
746 Try:
747 If IsNull([_Parent]) Then _ParentType = &quot;&quot; Else _ParentType = [_Parent].ObjectType
749 With _Component
750 &apos; The existence of _Component.Selection must be checked upfront
751 _Command = ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;Command&quot;)
753 iType = ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;CommandType&quot;)
754 Select Case iType
755 Case com.sun.star.sdb.CommandType.TABLE : _SheetType = &quot;TABLE&quot;
756 Case com.sun.star.sdb.CommandType.QUERY : _SheetType = &quot;QUERY&quot;
757 Case com.sun.star.sdb.CommandType.COMMAND : _SheetType = &quot;SQL&quot;
758 End Select
760 _BaseFileName = ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;DataSourceName&quot;)
761 _DirectSql = Not ScriptForge.SF_Utils._GetPropertyValue(.Selection, &quot;EscapeProcessing&quot;)
763 &apos; Useful UNO objects
764 Set _Frame = .Frame
765 Set _ControlView = .CurrentControl
766 Set _TabControllerModel = .com_sun_star_awt_XTabController_getModel()
767 Set _ControlModel = _ControlView.getModel()
768 End With
770 With _TabControllerModel
771 &apos; Retrieve the parent database instance
772 Select Case _ParentType
773 Case &quot;BASE&quot;
774 Set _ParentDatabase = [_Parent].GetDatabase(.User, .Password)
775 Set _ParentBase = [_Parent]
776 Case &quot;DATABASE&quot;
777 Set _ParentDatabase = [_Parent]
778 Set _ParentBase = Nothing
779 Case &quot;&quot; &apos; Derive the DATABASE instance from what can be found in the Component
780 Set _ParentDatabase = ScriptForge.SF_Services.CreateScriptService(&quot;SFDatabases.Database&quot; _
781 , FSO._ConvertFromUrl(_BaseFileName), , , .User, .Password)
782 _ParentType = &quot;DATABASE&quot;
783 Set _ParentBase = Nothing
784 End Select
785 &apos; Load column headers
786 _ColumnHeaders = .getColumns().getElementNames()
787 End With
789 Finally:
790 Exit Sub
791 End Sub &apos; SFDatabases.SF_Datasheet._Initialize
793 REM -----------------------------------------------------------------------------
794 Private Function _IsStillAlive(Optional ByVal pbError As Boolean) As Boolean
795 &apos;&apos;&apos; Returns True if the datasheet has not been closed manually or incidentally since the last use
796 &apos;&apos;&apos; If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
797 &apos;&apos;&apos; Args:
798 &apos;&apos;&apos; pbError: if True (default), raise a fatal error
800 Dim bAlive As Boolean &apos; Return value
801 Dim sName As String &apos; Used in error message
803 On Local Error GoTo Catch &apos; Anticipate DisposedException errors or alike
804 If IsMissing(pbError) Then pbError = True
806 Try:
807 &apos; Check existence of datasheet
808 bAlive = Not IsNull(_Component.ComponentWindow)
810 Finally:
811 If pbError And Not bAlive Then
812 sName = _Command
813 Dispose()
814 If pbError Then ScriptForge.SF_Exception.RaiseFatal(DOCUMENTDEADERROR, sName)
815 End If
816 _IsStillAlive = bAlive
817 Exit Function
818 Catch:
819 bAlive = False
820 On Error GoTo 0
821 GoTo Finally
822 End Function &apos; SFDatabases.SF_Datasheet._IsStillAlive
824 REM -----------------------------------------------------------------------------
825 Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
826 &apos;&apos;&apos; Return the value of the named property
827 &apos;&apos;&apos; Args:
828 &apos;&apos;&apos; psProperty: the name of the property
830 Dim lRow As Long &apos; Actual row number
831 Dim cstThisSub As String
832 Const cstSubArgs = &quot;&quot;
834 cstThisSub = &quot;SFDatabases.Datasheet.get&quot; &amp; psProperty
835 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
837 ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
838 If Not _IsStillAlive(False) Then GoTo Finally
840 Select Case psProperty
841 Case &quot;ColumnHeaders&quot;
842 _PropertyGet = _ColumnHeaders
843 Case &quot;CurrentColumn&quot;
844 _PropertyGet = _ColumnHeaders(_ControlView.getCurrentColumnPosition())
845 Case &quot;CurrentRow&quot;
846 _PropertyGet = _TabControllerModel.Row
847 Case &quot;DatabaseFileName&quot;
848 _PropertyGet = ScriptForge.SF_FileSystem._ConvertFromUrl(_BaseFileName)
849 Case &quot;Filter&quot;
850 _PropertyGet = _TabControllerModel.Filter
851 Case &quot;LastRow&quot;
852 With _TabControllerModel
853 If .IsRowCountFinal Then
854 _PropertyGet = .RowCount
855 Else
856 lRow = .Row
857 If lRow &gt; 0 Then
858 .last()
859 _PropertyGet = .RowCount
860 .absolute(lRow)
861 Else
862 _PropertyGet = 0
863 End If
864 End If
865 End With
866 Case &quot;OrderBy&quot;
867 _PropertyGet = _TabControllerModel.Order
868 Case &quot;ParentDatabase&quot;
869 Set _PropertyGet = _ParentDatabase
870 Case &quot;Source&quot;
871 _PropertyGet = _Command
872 Case &quot;SourceType&quot;
873 _PropertyGet = _SheetType
874 Case &quot;XComponent&quot;
875 Set _PropertyGet = _Component
876 Case &quot;XControlModel&quot;
877 Set _PropertyGet = _ControlModel
878 Case &quot;XTabControllerModel&quot;
879 Set _PropertyGet = _TabControllerModel
880 Case Else
881 _PropertyGet = Null
882 End Select
884 Finally:
885 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
886 Exit Function
887 Catch:
888 GoTo Finally
889 End Function &apos; SFDatabases.SF_Datasheet._PropertyGet
891 REM -----------------------------------------------------------------------------
892 Private Function _PropertySet(Optional ByVal psProperty As String _
893 , Optional ByVal pvValue As Variant _
894 ) As Boolean
895 &apos;&apos;&apos; Set the new value of the named property
896 &apos;&apos;&apos; Args:
897 &apos;&apos;&apos; psProperty: the name of the property
898 &apos;&apos;&apos; pvValue: the new value of the given property
899 &apos;&apos;&apos; Returns:
900 &apos;&apos;&apos; True if successful
902 Dim bSet As Boolean &apos; Return value
903 Dim cstThisSub As String
904 Const cstSubArgs = &quot;Value&quot;
906 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
907 bSet = False
909 cstThisSub = &quot;SFDatabases.Datasheet.set&quot; &amp; psProperty
910 ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
911 If Not _IsStillAlive() Then GoTo Finally
913 bSet = True
914 Select Case UCase(psProperty)
915 Case UCase(&quot;Filter&quot;)
916 If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Filter&quot;, V_STRING) Then GoTo Finally
917 With _TabControllerModel
918 If Len(pvValue) &gt; 0 Then .Filter = _ParentDatabase._ReplaceSquareBrackets(pvValue) Else .Filter = &quot;&quot;
919 .ApplyFilter = ( Len(pvValue) &gt; 0 )
920 .reload()
921 End With
922 Case UCase(&quot;OrderBy&quot;)
923 If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;OrderBy&quot;, V_STRING) Then GoTo Finally
924 With _TabControllerModel
925 If Len(pvValue) &gt; 0 Then .Order = _ParentDatabase._ReplaceSquareBrackets(pvValue) Else .Order = &quot;&quot;
926 .reload()
927 End With
928 Case Else
929 bSet = False
930 End Select
932 Finally:
933 _PropertySet = bSet
934 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
935 Exit Function
936 Catch:
937 GoTo Finally
938 End Function &apos; SFDatabases.SF_Datasheet._PropertySet
940 REM -----------------------------------------------------------------------------
941 Private Function _Repr() As String
942 &apos;&apos;&apos; Convert the Datasheet instance to a readable string, typically for debugging purposes (DebugPrint ...)
943 &apos;&apos;&apos; Args:
944 &apos;&apos;&apos; Return:
945 &apos;&apos;&apos; &quot;[DATASHEET]: tablename,base file url&quot;
947 _Repr = &quot;[DATASHEET]: &quot; &amp; _Command &amp; &quot;,&quot; &amp; _BaseFileName
949 End Function &apos; SFDatabases.SF_Datasheet._Repr
951 REM ============================================ END OF SFDATABASES.SF_DATASHEET
952 </script:module>