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_Calc" 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 SFDocuments library is one of the associated libraries. ===
6 REM === Full documentation is available on https://help.libreoffice.org/ ===
7 REM =======================================================================================================================
14 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
15 ''' SF_Calc
16 ''' =======
18 ''' The SFDocuments library gathers a number of methods and properties making easy
19 ''' managing and manipulating LibreOffice documents
21 ''' Some methods are generic for all types of documents: they are combined in the SF_Document module.
22 ''' Specific properties and methods are implemented in the concerned subclass(es) SF_Calc, SF_Base, ...
24 ''' To workaround the absence of class inheritance in LibreOffice Basic, some redundancy is necessary
25 ''' Each subclass MUST implement also the generic methods and properties, even if they only call
26 ''' the parent methods and properties.
27 ''' They should also duplicate some generic private members as a subset of their own set of members
29 ''' The SF_Calc module is focused on :
30 ''' - management (copy, insert, move, ...) of sheets within a Calc document
31 ''' - exchange of data between Basic data structures and Calc ranges of values
33 ''' The current module is closely related to the
"UI
" service of the ScriptForge library
35 ''' Service invocation examples:
36 ''' 1) From the UI service
37 ''' Dim ui As Object, oDoc As Object
38 ''' Set ui = CreateScriptService(
"UI
")
39 ''' Set oDoc = ui.CreateDocument(
"Calc
", ...)
40 ''' ' or Set oDoc = ui.OpenDocument(
"C:\Me\MyFile.ods
")
41 ''' 2) Directly if the document is already opened
42 ''' Dim oDoc As Object
43 ''' Set oDoc = CreateScriptService(
"SFDocuments.Calc
",
"Untitled
1")
' Default = ActiveWindow
44 ''' ' or Set oDoc = CreateScriptService(
"SFDocuments.Calc
",
"Untitled
1")
' Untitled
1 is presumed a Calc document
45 ''' ' The substring
"SFDocuments.
" in the service name is optional
47 ''' Definitions:
49 ''' Many methods require a
"Sheet
" or a
"Range
" as argument. (NB: a single cell is considered as a special case of a Range)
50 ''' Usually, within a specific Calc instance, sheets and ranges are given as a string:
"SheetX
" and
"D2:F6
"
51 ''' Multiple ranges are not supported in this context.
52 ''' Additionally, the .Sheet and .Range methods return a reference that may be used
53 ''' as argument of a method called from another instance of the Calc service
54 ''' Example:
55 ''' Dim oDocA As Object : Set oDocA = ui.OpenDocument(
"C:\FileA.ods
", Hidden := True, ReadOnly := True)
56 ''' Dim oDocB As Object : Set oDocB = ui.OpenDocument(
"C:\FileB.ods
")
57 ''' oDocB.CopyToRange(oDocA.Range(
"SheetX.D4:F8
"),
"D2:F6
")
' CopyToRange(source, target)
59 ''' Sheet: the sheet name as a string or an object produced by .Sheet()
60 ''' "~
" = current sheet
61 ''' Range: a string designating a set of contiguous cells located in a sheet of the current instance
62 ''' "~
" = current selection (if multiple selections, its
1st component)
63 ''' or an object produced by .Range()
64 ''' The sheet name is optional (default = active sheet). Surrounding quotes and $ signs are optional
65 ''' ~.~, ~ The current selection in the active sheet
66 ''' '$SheetX
'.D2 or $D$
2 A single cell
67 ''' '$SheetX
'.D2:F6, D2:D10 Multiple cells
68 ''' '$SheetX
'.A:A or
3:
5 All cells in the same column or row up to the last active cell
69 ''' SheetX.* All cells up to the last active cell
70 ''' myRange A range name at spreadsheet level
71 ''' ~.yourRange, SheetX.someRange A range name at sheet level
72 ''' myDoc.Range(
"SheetX.D2:F6
")
73 ''' A range within the sheet SheetX in file associated with the myDoc Calc instance
75 ''' Several methods may receive a
"FilterFormula
" as argument.
76 ''' A FilterFormula may be associated with a FilterScope:
"row
",
"column
" or
"cell
".
77 ''' These arguments determines on which rows/columns/cells of a range the method should be applied
78 ''' Examples:
79 ''' oDoc.ClearAll(
"A1:J10
", FilterFormula :=
"=(A1
<=
0)
", FilterScope :=
"CELL
")
' Clear all negative values
80 ''' oDoc.ClearAll(
"A2:J10
", FilterFormula :=
"=(A2
<>A1)
", FilterScope :=
"COLUMN
")
' Clear when identical to above cell
82 ''' FilterFormula: a Calc formula that returns TRUE or FALSE
83 ''' the formula is expressed in terms of
84 ''' - the top-left cell of the range when FilterScope =
"CELL
"
85 ''' - the topmost row of the range when FilterScope =
"ROW
"
86 ''' - the leftmost column of the range when FilterScope =
"COLUMN
"
87 ''' relative and absolute references will be interpreted correctly
88 ''' FilterScope: the way the formula is applied, once by row, by column, or by individual cell
90 ''' Detailed user documentation:
91 ''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/
03/sf_calc.html?DbPAR=BASIC
93 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
95 REM ================================================================== EXCEPTIONS
97 Private Const UNKNOWNFILEERROR =
"UNKNOWNFILEERROR
"
98 Private Const BASEDOCUMENTOPENERROR =
"BASEDOCUMENTOPENERROR
"
99 Private Const CALCADDRESSERROR =
"CALCADDRESSERROR
"
100 Private Const DUPLICATESHEETERROR =
"DUPLICATESHEETERROR
"
101 Private Const OFFSETADDRESSERROR =
"OFFSETADDRESSERROR
"
102 Private Const CALCFORMNOTFOUNDERROR =
"CALCFORMNOTFOUNDERROR
"
103 Private Const DUPLICATECHARTERROR =
"DUPLICATECHARTERROR
"
104 Private Const RANGEEXPORTERROR =
"RANGEEXPORTERROR
"
106 REM ============================================================= PRIVATE MEMBERS
108 Private [Me] As Object
109 Private [_Super] As Object
' Document superclass, which the current instance is a subclass of
110 Private ObjectType As String
' Must be CALC
111 Private ServiceName As String
113 ' Window component
114 Private _Component As Object
' com.sun.star.lang.XComponent
117 ObjectType As String
' Must be
"SF_CalcReference
"
118 ServiceName As String
' Must be
"SFDocuments.CalcReference
"
120 Component As Object
' com.sun.star.lang.XComponent
122 SheetIndex As Integer
126 XSpreadSheet As Object
' com.sun.star.sheet.XSpreadsheet
127 XCellRange As Object
' com.sun.star.table.XCellRange
130 Private _LastParsedAddress As Object
' _Address type - parsed ranges are cached
132 REM ============================================================ MODULE CONSTANTS
134 Private Const cstSHEET =
1
135 Private Const cstRANGE =
2
137 Private Const MAXCOLS =
2^
14 ' Max number of columns in a sheet
138 Private Const MAXROWS =
2^
20 ' Max number of rows in a sheet
140 Private Const CALCREFERENCE =
"SF_CalcReference
" ' Object type of _Address
141 Private Const SERVICEREFERENCE =
"SFDocuments.CalcReference
"
142 ' Service name of _Address (used in Python)
144 Private Const ISCALCFORM =
2 ' Form is stored in a Calc document
146 Private Const cstSPECIALCHARS =
" `~!@#$%^
&()-_=+{}|;,
<.
>"""
147 ' Presence of a special character forces surrounding the sheet name with single quotes in absolute addresses
150 REM ====================================================== CONSTRUCTOR/DESTRUCTOR
152 REM -----------------------------------------------------------------------------
153 Private Sub Class_Initialize()
155 Set [_Super] = Nothing
156 ObjectType =
"CALC
"
157 ServiceName =
"SFDocuments.Calc
"
158 Set _Component = Nothing
159 Set _LastParsedAddress = Nothing
160 End Sub
' SFDocuments.SF_Calc Constructor
162 REM -----------------------------------------------------------------------------
163 Private Sub Class_Terminate()
164 Call Class_Initialize()
165 End Sub
' SFDocuments.SF_Calc Destructor
167 REM -----------------------------------------------------------------------------
168 Public Function Dispose() As Variant
169 If Not IsNull([_Super]) Then Set [_Super] = [_Super].Dispose()
170 Call Class_Terminate()
171 Set Dispose = Nothing
172 End Function
' SFDocuments.SF_Calc Explicit Destructor
174 REM ================================================================== PROPERTIES
176 REM -----------------------------------------------------------------------------
177 Property Get CurrentSelection() As Variant
178 ''' Returns as a string the currently selected range or as an array the list of the currently selected ranges
179 CurrentSelection = _PropertyGet(
"CurrentSelection
")
180 End Property
' SFDocuments.SF_Calc.CurrentSelection (get)
182 REM -----------------------------------------------------------------------------
183 Property Let CurrentSelection(Optional ByVal pvSelection As Variant)
184 ''' Set the selection to a single or a multiple range
185 ''' The argument is a string or an array of strings
187 Dim sRange As String
' A single selection
188 Dim oCellRanges As Object
' com.sun.star.sheet.SheetCellRanges
189 Dim vRangeAddresses As Variant
' Array of com.sun.star.table.CellRangeAddress
191 Const cstThisSub =
"SFDocuments.Calc.setCurrentSelection
"
192 Const cstSubArgs =
"Selection
"
194 On Local Error GoTo Catch
197 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
198 If Not _IsStillAlive(True) Then GoTo Finally
199 If IsArray(pvSelection) Then
200 If Not ScriptForge.SF_Utils._ValidateArray(pvSelection,
"pvSelection
",
1, V_STRING, True) Then GoTo Finally
202 If Not ScriptForge.SF_Utils._Validate(pvSelection,
"pvSelection
", V_STRING) Then GoTo Finally
207 If IsArray(pvSelection) Then
208 Set oCellRanges = _Component.createInstance(
"com.sun.star.sheet.SheetCellRanges
")
209 vRangeAddresses = Array()
210 ReDim vRangeAddresses(
0 To UBound(pvSelection))
211 For i =
0 To UBound(pvSelection)
212 vRangeAddresses(i) = Range(pvSelection(i)).XCellRange.RangeAddress
214 oCellRanges.addRangeAddresses(vRangeAddresses, False)
215 _Component.CurrentController.select(oCellRanges)
217 _Component.CurrentController.select(_ParseAddress(pvSelection).XCellRange)
221 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
225 End Property
' SFDocuments.SF_Calc.CurrentSelection (let)
227 REM -----------------------------------------------------------------------------
228 Property Get FirstCell(Optional ByVal RangeName As Variant) As String
229 ''' Returns the First used cell in a given range or sheet
230 ''' When the argument is a sheet it will always return the
"sheet.$A$
1" cell
231 FirstCell = _PropertyGet(
"FirstCell
", RangeName)
232 End Property
' SFDocuments.SF_Calc.FirstCell
234 REM -----------------------------------------------------------------------------
235 Property Get FirstColumn(Optional ByVal RangeName As Variant) As Long
236 ''' Returns the leftmost column in a given sheet or range
237 ''' When the argument is a sheet it will always return
1
238 FirstColumn = _PropertyGet(
"FirstColumn
", RangeName)
239 End Property
' SFDocuments.SF_Calc.FirstColumn
241 REM -----------------------------------------------------------------------------
242 Property Get FirstRow(Optional ByVal RangeName As Variant) As Long
243 ''' Returns the First used column in a given range
244 ''' When the argument is a sheet it will always return
1
245 FirstRow = _PropertyGet(
"FirstRow
", RangeName)
246 End Property
' SFDocuments.SF_Calc.FirstRow
248 REM -----------------------------------------------------------------------------
249 Property Get Height(Optional ByVal RangeName As Variant) As Long
250 ''' Returns the height in # of rows of the given range
251 Height = _PropertyGet(
"Height
", RangeName)
252 End Property
' SFDocuments.SF_Calc.Height
254 REM -----------------------------------------------------------------------------
255 Property Get LastCell(Optional ByVal RangeName As Variant) As String
256 ''' Returns the last used cell in a given sheet or range
257 LastCell = _PropertyGet(
"LastCell
", RangeName)
258 End Property
' SFDocuments.SF_Calc.LastCell
260 REM -----------------------------------------------------------------------------
261 Property Get LastColumn(Optional ByVal RangeName As Variant) As Long
262 ''' Returns the last used column in a given sheet
263 LastColumn = _PropertyGet(
"LastColumn
", RangeName)
264 End Property
' SFDocuments.SF_Calc.LastColumn
266 REM -----------------------------------------------------------------------------
267 Property Get LastRow(Optional ByVal RangeName As Variant) As Long
268 ''' Returns the last used column in a given sheet
269 LastRow = _PropertyGet(
"LastRow
", RangeName)
270 End Property
' SFDocuments.SF_Calc.LastRow
272 REM -----------------------------------------------------------------------------
273 Property Get Range(Optional ByVal RangeName As Variant) As Variant
274 ''' Returns a (internal) range object
275 Range = _PropertyGet(
"Range
", RangeName)
276 End Property
' SFDocuments.SF_Calc.Range
278 REM -----------------------------------------------------------------------------
279 Property Get Region(Optional ByVal RangeName As Variant) As String
280 ''' Returns the smallest area as a range string that contains the given range
281 ''' and which is completely surrounded with empty cells
282 Region = _PropertyGet(
"Region
", RangeName)
283 End Property
' SFDocuments.SF_Calc.Region
285 REM -----------------------------------------------------------------------------
286 Property Get Sheet(Optional ByVal SheetName As Variant) As Variant
287 ''' Returns a (internal) sheet object
288 Sheet = _PropertyGet(
"Sheet
", SheetName)
289 End Property
' SFDocuments.SF_Calc.Sheet
291 REM -----------------------------------------------------------------------------
292 Property Get SheetName(Optional ByVal RangeName As Variant) As String
293 ''' Returns the sheet name part of a range
294 SheetName = _PropertyGet(
"SheetName
", RangeName)
295 End Property
' SFDocuments.SF_Calc.SheetName
297 REM -----------------------------------------------------------------------------
298 Property Get Sheets() As Variant
299 ''' Returns an array listing the existing sheet names
300 Sheets = _PropertyGet(
"Sheets
")
301 End Property
' SFDocuments.SF_Calc.Sheets
303 REM -----------------------------------------------------------------------------
304 Property Get Width(Optional ByVal RangeName As Variant) As Long
305 ''' Returns the width in # of columns of the given range
306 Width = _PropertyGet(
"Width
", RangeName)
307 End Property
' SFDocuments.SF_Calc.Width
309 REM -----------------------------------------------------------------------------
310 Property Get XCellRange(Optional ByVal RangeName As Variant) As Variant
311 ''' Returns a UNO object of type com.sun.star.Table.CellRange
312 XCellRange = _PropertyGet(
"XCellRange
", RangeName)
313 End Property
' SFDocuments.SF_Calc.XCellRange
315 REM -----------------------------------------------------------------------------
316 Property Get XSheetCellCursor(Optional ByVal RangeName As Variant) As Variant
317 ''' Returns a UNO object of type com.sun.star.sheet.XSheetCellCursor
318 '' After having moved the cursor (gotoNext(), ...) the resulting range can be got
319 ''' back as a string with the cursor.AbsoluteName UNO property.
320 XSheetCellCursor = _PropertyGet(
"XSheetCellCursor
", RangeName)
321 End Property
' SFDocuments.SF_Calc.XSheetCellCursor
323 REM -----------------------------------------------------------------------------
324 Property Get XSpreadsheet(Optional ByVal SheetName As Variant) As Variant
325 ''' Returns a UNO object of type com.sun.star.sheet.XSpreadsheet
326 XSpreadsheet = _PropertyGet(
"XSpreadsheet
", SheetName)
327 End Property
' SFDocuments.SF_Calc.XSpreadsheet
329 REM ===================================================================== METHODS
331 REM -----------------------------------------------------------------------------
332 Public Function A1Style(Optional ByVal Row1 As Variant _
333 , Optional ByVal Column1 As Variant _
334 , Optional ByVal Row2 As Variant _
335 , Optional ByVal Column2 As Variant _
336 , Optional ByVal SheetName As Variant _
338 ''' Returns a range expressed in A1-style as defined by its coordinates
339 ''' If only one pair of coordinates is given, the range will embrace only a single cell
340 ''' Args:
341 ''' Row1 : the row number of the first coordinate
342 ''' Column1 : the column number of the first coordinates
343 ''' Row2 : the row number of the second coordinate
344 ''' Column2 : the column number of the second coordinates
345 ''' SheetName: Default = the current sheet. If present, the sheet must exist.
346 ''' Returns:
347 ''' A range as a string
348 ''' Exceptions:
349 ''' Examples:
350 ''' range = oDoc.A1Style(
5,
2,
10,
4,
"SheetX
")
' "'$SheetX
'.$E$
2:$J$
4"
352 Dim sA1Style As String
' Return value
353 Dim vSheetName As Variant
' Alias of SheetName - necessary see [Bug
145279]
354 Dim lTemp As Long
' To switch
2 values
357 Const cstThisSub =
"SFDocuments.Calc.A1Style
"
358 Const cstSubArgs =
"Row1, Column1, [Row2], [Column2], [SheetName]=
"""""
360 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
361 sA1Style =
""
364 If IsMissing(Row2) Or IsEmpty(Row2) Then Row2 =
0
365 If IsMissing(Column2) Or IsEmpty(Column2) Then Column2 =
0
366 If IsMissing(SheetName) Or IsEmpty(SheetName) Then SheetName =
"~
"
367 vSheetName = SheetName
369 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
370 If Not _IsStillAlive() Then GoTo Finally
371 If Not ScriptForge.SF_Utils._Validate(Row1,
"Row1
", ScriptForge.V_NUMERIC) Then GoTo Finally
372 If Not ScriptForge.SF_Utils._Validate(Column1,
"Column1
", ScriptForge.V_NUMERIC) Then GoTo Finally
373 If Not ScriptForge.SF_Utils._Validate(Row2,
"Row2
", ScriptForge.V_NUMERIC) Then GoTo Finally
374 If Not ScriptForge.SF_Utils._Validate(Column2,
"Column2
", ScriptForge.V_NUMERIC) Then GoTo Finally
375 If Not _ValidateSheet(vSheetName,
"SheetName
", , True, True, , , True) Then GoTo Finally
378 If Row1
> MAXROWS Then Row1 = MAXROWS
379 If Row2
> MAXROWS Then Row2 = MAXROWS
380 If Column1
> MAXCOLS Then Column1 = MAXCOLS
381 If Column2
> MAXCOLS Then Column2 = MAXCOLS
383 If Row2
> 0 And Row2
< Row1 Then
384 lTemp = Row2 : Row2 = Row1 : Row1 = lTemp
386 If Column2
> 0 And Column2
< Column1 Then
387 lTemp = Column2 : Column2 = Column1 : Column1 = lTemp
391 ' Surround the sheet name with single quotes when required by the presence of special characters
392 vSheetName = _QuoteSheetName(vSheetName)
393 ' Define the new range string
394 sA1Style =
"$
" & vSheetName
& ".
" _
395 & "$
" & _GetColumnName(Column1)
& "$
" & CLng(Row1) _
396 & Iif(Row2
> 0 And Column2
> 0,
":$
" & _GetColumnName(Column2)
& "$
" & CLng(Row2),
"")
400 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
404 End Function
' SFDocuments.SF_Calc.A1Style
406 REM -----------------------------------------------------------------------------
407 Public Function Activate(Optional ByVal SheetName As Variant) As Boolean
408 ''' Make the current document or the given sheet active
409 ''' Args:
410 ''' SheetName: Default = the Calc document as a whole
411 ''' Returns:
412 ''' True if the document or the sheet could be made active
413 ''' Otherwise, there is no change in the actual user interface
414 ''' Examples:
415 ''' oDoc.Activate(
"SheetX
")
417 Dim bActive As Boolean
' Return value
418 Dim oSheet As Object
' Reference to sheet
419 Const cstThisSub =
"SFDocuments.Calc.Activate
"
420 Const cstSubArgs =
"[SheetName]
"
422 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
426 If IsMissing(SheetName) Or IsEmpty(SheetName) Then SheetName =
""
427 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
428 If Not _IsStillAlive() Then GoTo Finally
429 If Not _ValidateSheet(SheetName,
"SheetName
", , , True) Then GoTo Finally
433 ' Sheet activation, to do only when meaningful, precedes document activation
434 If Len(SheetName)
> 0 Then
436 Set oSheet = .getSheets.getByName(SheetName)
437 Set .CurrentController.ActiveSheet = oSheet
440 bActive = [_Super].Activate()
444 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
448 End Function
' SFDocuments.SF_Calc.Activate
450 REM -----------------------------------------------------------------------------
451 Public Function Charts(Optional ByVal SheetName As Variant _
452 , Optional ByVal ChartName As Variant _
454 ''' Return either the list of charts present in the given sheet or a chart object
455 ''' Args:
456 ''' SheetName: The name of an existing sheet
457 ''' ChartName: The user-defined name of the targeted chart or the zero-length string
458 ''' Returns:
459 ''' When ChartName =
"", return the list of the charts present in the sheet,
460 ''' otherwise, return a new chart service instance
461 ''' Examples:
462 ''' Dim oChart As Object
463 ''' Set oChart = oDoc.Charts(
"SheetX
",
"myChart
")
465 Dim vCharts As Variant
' Return value when array of chart names
466 Dim oChart As Object
' Return value when new chart instance
467 Dim oSheet As Object
' Alias of SheetName as reference
468 Dim oDrawPage As Object
' com.sun.star.drawing.XDrawPage
469 Dim oNextShape As Object
' com.sun.star.drawing.XShape
470 Dim sChartName As String
' Some chart name
471 Dim lCount As Long
' Counter for charts among all drawing objects
473 Const cstChartShape =
"com.sun.star.drawing.OLE2Shape
"
475 Const cstThisSub =
"SFDocuments.Calc.Charts
"
476 Const cstSubArgs =
"SheetName, [ChartName=
""""]
"
478 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
482 If IsMissing(ChartName) Or IsEmpty(ChartName) Then ChartName =
""
483 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
484 If Not _IsStillAlive(True) Then GoTo Finally
485 If Not _ValidateSheet(SheetName,
"SheetName
", , True) Then GoTo Finally
486 If Not ScriptForge.SF_Utils._Validate(ChartName,
"ChartName
", V_STRING) Then GoTo Finally
490 ' Because the user can change it constantly, the list of valid charts has to be rebuilt at each time
491 ' Explore charts starting from the draw page
492 Set oSheet = _Component.getSheets.getByName(SheetName)
493 Set oDrawPage = oSheet.getDrawPage()
497 For i =
0 To oDrawPage.Count -
1
498 Set oNextShape = oDrawPage.getByIndex(i)
499 if oNextShape.supportsService(cstChartShape) Then
' Ignore other shapes
500 sChartName = oNextShape.Name
' User-defined name
501 If Len(sChartName) =
0 Then sChartName = oNextShape.PersistName
' Internal name
502 ' Is chart found ?
503 If Len(ChartName)
> 0 Then
504 If ChartName = sChartName Then
505 Set oChart = New SF_Chart
508 Set .[_Parent] = [Me]
509 ._SheetName = SheetName
511 ._ChartName = ChartName
512 ._PersistentName = oNextShape.PersistName
513 Set ._Shape = oNextShape
514 Set ._Chart = oSheet.getCharts().getByName(._PersistentName)
515 Set ._ChartObject = ._Chart.EmbeddedObject
516 Set ._Diagram = ._ChartObject.Diagram
521 ' Build stack of chart names
523 If UBound(vCharts)
< 0 Then
524 vCharts = Array(sChartName)
526 ReDim Preserve vCharts(
0 To UBound(vCharts) +
1)
527 vCharts(lCount) = sChartName
532 ' Raise error when chart not found
533 If Len(ChartName)
> 0 And IsNull(oChart) Then
534 If Not ScriptForge.SF_Utils._Validate(ChartName,
"ChartName
", V_STRING, vCharts) Then GoTo Finally
538 If Len(ChartName) =
0 Then Charts = vCharts Else Set Charts = oChart
539 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
543 End Function
' SFDocuments.SF_Calc.Charts
545 REM -----------------------------------------------------------------------------
546 Public Sub ClearAll(Optional ByVal Range As Variant _
547 , Optional FilterFormula As Variant _
548 , Optional FilterScope As Variant _
550 ''' Clear entirely the given range
551 ''' Args:
552 ''' Range : the cell or the range as a string that should be cleared
553 ''' FilterFormula: a Calc formula to select among the given Range
554 ''' When left empty, all the cells of the range are cleared
555 ''' FilterScope:
"CELL
" (default value),
"ROW
" or
"COLUMN
"
556 ''' When FilterFormula is present, FilterScope is mandatory
557 ''' Examples:
558 ''' oDoc.ClearAll(
"SheetX
")
' Clears the used area of the sheet
559 ''' oDoc.ClearAll(
"A1:J20
",
"=($A1=
0)
",
"ROW
")
' Clears all rows when
1st cell is zero
561 _ClearRange(
"All
", Range, FilterFormula, FilterScope)
563 End Sub
' SFDocuments.SF_Calc.ClearAll
565 REM -----------------------------------------------------------------------------
566 Public Sub ClearFormats(Optional ByVal Range As Variant _
567 , Optional FilterFormula As Variant _
568 , Optional FilterScope As Variant _
570 ''' Clear all the formatting elements of the given range
571 ''' Args:
572 ''' Range : the cell or the range as a string that should be cleared
573 ''' FilterFormula: a Calc formula to select among the given Range
574 ''' When left empty, all the cells of the range are cleared
575 ''' FilterScope:
"CELL
" (default value),
"ROW
" or
"COLUMN
"
576 ''' When FilterFormula is present, FilterScope is mandatory
577 ''' Examples:
578 ''' oDoc.ClearFormats(
"SheetX.*
")
' Clears the used area of the sheet
579 ''' oDoc.ClearFormats(
"A1:J20
",
"=(MOD(A1;
0)=
0)
",
"CELL
")
' Clears all even cells
581 _ClearRange(
"Formats
", Range, FilterFormula, FilterScope)
583 End Sub
' SFDocuments.SF_Calc.ClearFormats
585 REM -----------------------------------------------------------------------------
586 Public Sub ClearValues(Optional ByVal Range As Variant _
587 , Optional FilterFormula As Variant _
588 , Optional FilterScope As Variant _
590 ''' Clear values and formulas in the given range
591 ''' Args:
592 ''' Range : the cell or the range as a string that should be cleared
593 ''' FilterFormula: a Calc formula to select among the given Range
594 ''' When left empty, all the cells of the range are cleared
595 ''' FilterScope:
"CELL
" (default value),
"ROW
" or
"COLUMN
"
596 ''' When FilterFormula is present, FilterScope is mandatory
597 ''' Examples:
598 ''' oDoc.ClearValues(
"SheetX.*
")
' Clears the used area of the sheet
599 ''' oDoc.ClearValues(
"A2:A20
",
"=(A2=A1)
",
"CELL
")
' Clears all duplicate cells
601 _ClearRange(
"Values
", Range, FilterFormula, FilterScope)
603 End Sub
' SFDocuments.SF_Calc.ClearValues
605 REM -----------------------------------------------------------------------------
606 Public Function CompactLeft(Optional ByVal Range As Variant _
607 , Optional ByVal WholeColumn As Variant _
608 , Optional ByVal FilterFormula As Variant _
610 ''' Delete the columns of a specified range matching a filter expressed as a formula
611 ''' applied on each column.
612 ''' The deleted cells can span whole columns or be limited to the height of the range
613 ''' The execution of the method has no effect on the current selection
614 ''' Args:
615 ''' Range: the range in which cells have to be erased, as a string
616 ''' WholeColumn: when True (default = False), erase whole columns
617 ''' FilterFormula: the formula to be applied on each column.
618 ''' The column is erased when the formula results in True,
619 ''' The formula shall probably involve one or more cells of the first column of the range.
620 ''' By default, a column is erased when all the cells of the column are empty,
621 ''' i.e. suppose the range is
"A1:J200
" (height =
200) the default value becomes
622 ''' "=(COUNTBLANK(A1:A200)=
200)
"
623 ''' Returns:
624 ''' A string representing the location of the initial range after compaction,
625 ''' or the zero-length string if the whole range has been deleted
626 ''' Examples:
627 ''' newrange = oDoc.CompactLeft(
"SheetX.G1:L10
")
' All empty columns of the range are suppressed
628 ''' newrange = oDoc.CompactLeft(
"SheetX.G1:L10
", WholeColumn := True, FilterFormula :=
"=(G$
7=
""X
"")
")
629 ''' ' The columns having a
"X
" in row
7 are completely suppressed
631 Dim sCompact As String
' Return value
632 Dim oCompact As Object
' Return value as an _Address type
633 Dim lCountDeleted As Long
' Count the deleted columns
634 Dim vCompactRanges As Variant
' Array of ranges to be compacted based on the formula
635 Dim oSourceAddress As Object
' Alias of Range as _Address
636 Dim oPartialRange As Object
' Contiguous columns to be deleted
637 Dim sShiftRange As String
' Contiguous columns to be shifted
640 Const cstThisSub =
"SFDocuments.Calc.CompactLeft
"
641 Const cstSubArgs =
"Range, [WholeColumn=False], [FilterFormula=
""""]
"
643 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
644 sCompact =
""
647 If IsMissing(WholeColumn) Or IsEmpty(WholeColumn) Then WholeColumn = False
648 If IsMissing(FilterFormula) Or IsEmpty(FilterFormula) Then FilterFormula =
""
649 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
650 If Not _IsStillAlive(True) Then GoTo Finally
651 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
652 If Not ScriptForge.SF_Utils._Validate(WholeColumn,
"WholeColumn
", ScriptForge.V_BOOLEAN) Then GoTo Finally
653 If Not ScriptForge.SF_Utils._Validate(FilterFormula,
"FilterFormula
", V_STRING) Then GoTo Finally
657 Set oSourceAddress = _ParseAddress(Range)
662 ' Set the default formula =
> all cells are blank
663 If FilterFormula =
"" Then FilterFormula = Printf(
"=(COUNTBLANK(%C1%R1:%C1%R2)-
" & .Height
& "=
0)
", Range)
665 ' Identify the ranges to compact based on the given formula
666 vCompactRanges = _ComputeFilter(oSourceAddress, FilterFormula,
"COLUMN
")
668 ' Iterate through the ranges from bottom to top and shift them up
669 For i = UBound(vCompactRanges) To
0 Step -
1
670 Set oPartialRange = vCompactRanges(i)
671 ShiftLeft(oPartialRange.RangeName, WholeColumn)
672 lCountDeleted = lCountDeleted + oPartialRange.Width
675 ' Compute the final range position
676 If lCountDeleted
< .Width Then sCompact = Offset(Range,
0,
0,
0, .Width - lCountDeleted)
678 ' Push to the right the cells that migrated leftwards irrelevantly
679 If Not WholeColumn Then
680 If Len(sCompact)
> 0 Then
681 sShiftRange = Offset(sCompact,
0, .Width - lCountDeleted, , lCountDeleted)
683 sShiftRange = .RangeName
685 ShiftRight(sShiftRange, WholeColumn := False)
691 CompactLeft = sCompact
692 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
695 ' When error, return the original range
696 If Not IsNull(oSourceAddress) Then sCompact = oSourceAddress.RangeName
698 End Function
' SFDocuments.SF_Calc.CompactLeft
700 REM -----------------------------------------------------------------------------
701 Public Function CompactUp(Optional ByVal Range As Variant _
702 , Optional ByVal WholeRow As Variant _
703 , Optional ByVal FilterFormula As Variant _
705 ''' Delete the rows of a specified range matching a filter expressed as a formula
706 ''' applied on each row.
707 ''' The deleted cells can span whole rows or be limited to the width of the range
708 ''' The execution of the method has no effect on the current selection
709 ''' Args:
710 ''' Range: the range in which cells have to be erased, as a string
711 ''' WholeRow: when True (default = False), erase whole rows
712 ''' FilterFormula: the formula to be applied on each row.
713 ''' The row is erased when the formula results in True,
714 ''' The formula shall probably involve one or more cells of the first row of the range.
715 ''' By default, a row is erased when all the cells of the row are empty,
716 ''' i.e. suppose the range is
"A1:J200
" (width =
10) the default value becomes
717 ''' "=(COUNTBLANK(A1:J1)=
10)
"
718 ''' Returns:
719 ''' A string representing the location of the initial range after compaction,
720 ''' or the zero-length string if the whole range has been deleted
721 ''' Examples:
722 ''' newrange = oDoc.CompactUp(
"SheetX.G1:L10
")
' All empty rows of the range are suppressed
723 ''' newrange = oDoc.CompactUp(
"SheetX.G1:L10
", WholeRow := True, FilterFormula :=
"=(G1=
""X
"")
")
724 ''' ' The rows having a
"X
" in column G are completely suppressed
726 Dim sCompact As String
' Return value
727 Dim oCompact As Object
' Return value as an _Address type
728 Dim lCountDeleted As Long
' Count the deleted rows
729 Dim vCompactRanges As Variant
' Array of ranges to be compacted based on the formula
730 Dim oSourceAddress As Object
' Alias of Range as _Address
731 Dim oPartialRange As Object
' Contiguous rows to be deleted
732 Dim sShiftRange As String
' Contiguous rows to be shifted
735 Const cstThisSub =
"SFDocuments.Calc.CompactUp
"
736 Const cstSubArgs =
"Range, [WholeRow=False], [FilterFormula=
""""]
"
738 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
739 sCompact =
""
742 If IsMissing(WholeRow) Or IsEmpty(WholeRow) Then WholeRow = False
743 If IsMissing(FilterFormula) Or IsEmpty(FilterFormula) Then FilterFormula =
""
744 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
745 If Not _IsStillAlive(True) Then GoTo Finally
746 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
747 If Not ScriptForge.SF_Utils._Validate(WholeRow,
"WholeRow
", ScriptForge.V_BOOLEAN) Then GoTo Finally
748 If Not ScriptForge.SF_Utils._Validate(FilterFormula,
"FilterFormula
", V_STRING) Then GoTo Finally
752 Set oSourceAddress = _ParseAddress(Range)
757 ' Set the default formula =
> all cells are blank
758 If FilterFormula =
"" Then FilterFormula = Printf(
"=(COUNTBLANK(%C1%R1:%C2%R1)-
" & .Width
& "=
0)
", Range)
760 ' Identify the ranges to compact based on the given formula
761 vCompactRanges = _ComputeFilter(oSourceAddress, FilterFormula,
"ROW
")
763 ' Iterate through the ranges from bottom to top and shift them up
764 For i = UBound(vCompactRanges) To
0 Step -
1
765 Set oPartialRange = vCompactRanges(i)
766 ShiftUp(oPartialRange.RangeName, WholeRow)
767 lCountDeleted = lCountDeleted + oPartialRange.Height
770 ' Compute the final range position
771 If lCountDeleted
< .Height Then sCompact = Offset(Range,
0,
0, .Height - lCountDeleted,
0)
773 ' Push downwards the cells that migrated upwards irrelevantly
775 If Len(sCompact)
> 0 Then
776 sShiftRange = Offset(sCompact, .Height - lCountDeleted,
0, lCountDeleted)
778 sShiftRange = .RangeName
780 ShiftDown(sShiftRange, WholeRow := False)
787 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
790 ' When error, return the original range
791 If Not IsNull(oSourceAddress) Then sCompact = oSourceAddress.RangeName
793 End Function
' SFDocuments.SF_Calc.CompactUp
795 REM -----------------------------------------------------------------------------
796 Public Function CopySheet(Optional ByVal SheetName As Variant _
797 , Optional ByVal NewName As Variant _
798 , Optional ByVal BeforeSheet As Variant _
800 ''' Copy a specified sheet before an existing sheet or at the end of the list of sheets
801 ''' The sheet to copy may be inside any open Calc document
802 ''' Args:
803 ''' SheetName: The name of the sheet to copy or its reference
804 ''' NewName: Must not exist
805 ''' BeforeSheet: The name (string) or index (numeric, starting from
1) of the sheet before which to insert
806 ''' Returns:
807 ''' True if the sheet could be copied successfully
808 ''' Exceptions:
809 ''' DUPLICATESHEETERROR A sheet with the given name exists already
810 ''' Examples:
811 ''' oDoc.CopySheet(
"SheetX
",
"SheetY
")
812 ''' ' Copy within the same document
813 ''' Dim oDocA As Object : Set oDocA = ui.OpenDocument(
"C:\Temp\FileA.ods
", Hidden := True, ReadOnly := True)
814 ''' Dim oDocB As Object : Set oDocB = ui.OpenDocument(
"C:\Temp\FileB.ods
")
815 ''' oDocB.CopySheet(oDocA.Sheet(
"SheetX
"),
"SheetY
")
816 ''' ' Copy from
1 file to another and put the new sheet at the end
818 Dim bCopy As Boolean
' Return value
819 Dim oSheets As Object
' com.sun.star.sheet.XSpreadsheets
820 Dim vSheets As Variant
' List of existing sheets
821 Dim lSheetIndex As Long
' Index of a sheet
822 Dim oSheet As Object
' Alias of SheetName as reference
823 Dim lRandom As Long
' Output of random number generator
824 Dim sRandom
' Random sheet name
825 Const cstThisSub =
"SFDocuments.Calc.CopySheet
"
826 Const cstSubArgs =
"SheetName, NewName, [BeforeSheet=
""""]
"
828 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
832 If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet =
32768
833 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
834 If Not _IsStillAlive(True) Then GoTo Finally
835 If Not _ValidateSheet(SheetName,
"SheetName
", , True, , , True) Then GoTo Finally
836 If Not _ValidateSheet(NewName,
"NewName
", True) Then GoTo Finally
837 If Not _ValidateSheet(BeforeSheet,
"BeforeSheet
", , True, , True) Then GoTo Finally
841 ' Determine the index of the sheet before which to insert the copy
842 Set oSheets = _Component.getSheets
843 vSheets = oSheets.getElementNames()
844 If VarType(BeforeSheet) = V_STRING Then
845 lSheetIndex = ScriptForge.SF_Array.IndexOf(vSheets, BeforeSheet)
847 lSheetIndex = BeforeSheet -
1
848 If lSheetIndex
< 0 Then lSheetIndex =
0
849 If lSheetIndex
> UBound(vSheets) Then lSheetIndex = UBound(vSheets) +
1
852 ' Copy sheet inside the same document OR import from another document
853 If VarType(SheetName) = V_STRING Then
854 _Component.getSheets.copyByName(SheetName, NewName, lSheetIndex)
856 Set oSheet = SheetName
858 ' If a sheet with same name as input exists in the target sheet, rename it first with a random name
859 sRandom =
""
860 If ScriptForge.SF_Array.Contains(vSheets, .SheetName) Then
861 lRandom = ScriptForge.SF_Session.ExecuteCalcFunction(
"RANDBETWEEN.NV
",
1,
9999999)
862 sRandom =
"SF_
" & Right(
"0000000" & lRandom,
7)
863 oSheets.getByName(.SheetName).setName(sRandom)
865 ' Import i.o. Copy
866 oSheets.importSheet(oSheet.Component, .SheetName, lSheetIndex)
867 ' Rename to new sheet name
868 oSheets.getByName(.SheetName).setName(NewName)
869 ' Reset random name
870 If Len(sRandom)
> 0 Then oSheets.getByName(sRandom).setName(.SheetName)
877 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
882 ScriptForge.SF_Exception.RaiseFatal(DUPLICATESHEETERROR,
"NewName
", NewName,
"Document
", [_Super]._FileIdent())
884 End Function
' SFDocuments.SF_Calc.CopySheet
886 REM -----------------------------------------------------------------------------
887 Public Function CopySheetFromFile(Optional ByVal FileName As Variant _
888 , Optional ByVal SheetName As Variant _
889 , Optional ByVal NewName As Variant _
890 , Optional ByVal BeforeSheet As Variant _
892 ''' Copy a specified sheet before an existing sheet or at the end of the list of sheets
893 ''' The sheet to copy is located inside any closed Calc document
894 ''' Args:
895 ''' FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
896 ''' The file must not be protected with a password
897 ''' SheetName: The name of the sheet to copy
898 ''' NewName: Must not exist
899 ''' BeforeSheet: The name (string) or index (numeric, starting from
1) of the sheet before which to insert
900 ''' Returns:
901 ''' True if the sheet could be created
902 ''' The created sheet is blank when the input file is not a Calc file
903 ''' The created sheet contains an error message when the input sheet was not found
904 ''' Exceptions:
905 ''' DUPLICATESHEETERROR A sheet with the given name exists already
906 ''' UNKNOWNFILEERROR The input file is unknown
907 ''' Examples:
908 ''' oDoc.CopySheetFromFile(
"C:\MyFile.ods
",
"SheetX
",
"SheetY
",
3)
910 Dim bCopy As Boolean
' Return value
911 Dim oSheet As Object
' com.sun.star.sheet.XSpreadsheet
912 Dim sFileName As String
' URL alias of FileName
913 Dim FSO As Object
' SF_FileSystem
914 Const cstThisSub =
"SFDocuments.Calc.CopySheetFromFile
"
915 Const cstSubArgs =
"FileName, SheetName, NewName, [BeforeSheet=
""""]
"
917 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
921 If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet =
32768
922 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
923 If Not _IsStillAlive(True) Then GoTo Finally
924 If Not ScriptForge.SF_Utils._ValidateFile(FileName,
"FileName
") Then GoTo Finally
925 If Not ScriptForge.SF_Utils._Validate(SheetName,
"SheetName
", V_STRING) Then GoTo Finally
926 If Not _ValidateSheet(NewName,
"NewName
", True) Then GoTo Finally
927 If Not _ValidateSheet(BeforeSheet,
"BeforeSheet
", , True, , True) Then GoTo Finally
931 Set FSO = ScriptForge.SF_FileSystem
932 ' Does the input file exist ?
933 If Not FSO.FileExists(FileName) Then GoTo CatchNotExists
934 sFileName = FSO._ConvertToUrl(FileName)
936 ' Insert a blank new sheet and import sheet from file via link setting and deletion
937 If Not InsertSheet(Newname, BeforeSheet) Then GoTo Finally
938 Set oSheet = _Component.getSheets.getByName(NewName)
940 .link(sFileName,SheetName,
"",
"", com.sun.star.sheet.SheetLinkMode.NORMAL)
941 .LinkMode = com.sun.star.sheet.SheetLinkMode.NONE
942 .LinkURL =
""
947 CopySheetFromFile = bCopy
948 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
953 ScriptForge.SF_Exception.RaiseFatal(UNKNOWNFILEERROR,
"FileName
", FileName)
955 End Function
' SFDocuments.SF_Calc.CopySheetFromFile
957 REM -----------------------------------------------------------------------------
958 Public Function CopyToCell(Optional ByVal SourceRange As Variant _
959 , Optional ByVal DestinationCell As Variant _
961 ''' Copy a specified source range to a destination range or cell
962 ''' The source range may belong to another open document
963 ''' The method imitates the behaviour of a Copy/Paste from a range to a single cell
964 ''' Args:
965 ''' SourceRange: the source range as a string if it belongs to the same document
966 ''' or as a reference if it belongs to another open Calc document
967 ''' DestinationCell: the destination of the copied range of cells, as a string
968 ''' If given as a range of cells, the destination will be reduced to its top-left cell
969 ''' Returns:
970 ''' A string representing the modified range of cells
971 ''' The modified area depends only on the size of the source area
972 ''' Examples:
973 ''' oDoc.CopyToCell(
"SheetX.A1:F10
",
"SheetY.C5
")
974 ''' ' Copy within the same document
975 ''' Dim oDocA As Object : Set oDocA = ui.OpenDocument(
"C:\Temp\FileA.ods
", Hidden := True, ReadOnly := True)
976 ''' Dim oDocB As Object : Set oDocB = ui.OpenDocument(
"C:\Temp\FileB.ods
")
977 ''' oDocB.CopyToCell(oDocA.Range(
"SheetX.A1:F10
"),
"SheetY.C5
")
978 ''' ' Copy from
1 file to another
980 Dim sCopy As String
' Return value
981 Dim oSource As Object
' Alias of SourceRange to avoid
"Object variable not set
" run-time error
982 Dim oSourceAddress As Object
' com.sun.star.table.CellRangeAddress
983 Dim oDestRange As Object
' Destination as a range
984 Dim oDestAddress As Object
' com.sun.star.table.CellRangeAddress
985 Dim oDestCell As Object
' com.sun.star.table.CellAddress
986 Dim oSelect As Object
' Current selection in source
987 Dim oClipboard As Object
' com.sun.star.datatransfer.XTransferable
989 Const cstThisSub =
"SFDocuments.Calc.CopyToCell
"
990 Const cstSubArgs =
"SourceRange, DestinationCell
"
992 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
996 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
997 If Not _IsStillAlive(True) Then GoTo Finally
998 If Not ScriptForge.SF_Utils._Validate(SourceRange,
"SourceRange
", Array(V_STRING, ScriptForge.V_OBJECT), , , CALCREFERENCE) Then GoTo Finally
999 If Not ScriptForge.SF_Utils._Validate(DestinationCell,
"DestinationCell
", V_STRING) Then GoTo Finally
1003 If VarType(SourceRange) = V_STRING Then
' Same document - Use UNO copyRange method
1004 Set oSourceAddress = _ParseAddress(SourceRange).XCellRange.RangeAddress
1005 Set oDestRange = _ParseAddress(DestinationCell)
1006 Set oDestAddress = oDestRange.XCellRange.RangeAddress
1007 Set oDestCell = New com.sun.star.table.CellAddress
1009 oDestCell.Sheet = .Sheet
1010 oDestCell.Column = .StartColumn
1011 oDestCell.Row = .StartRow
1013 oDestRange.XSpreadsheet.copyRange(oDestCell, oSourceAddress)
1014 Else
' Use clipboard to copy - current selection in Source should be preserved
1015 Set oSource = SourceRange
1017 ' Keep current selection in source document
1018 Set oSelect = .Component.CurrentController.getSelection()
1019 ' Select, copy the source range and paste in the top-left cell of the destination
1020 .Component.CurrentController.select(.XCellRange)
1021 Set oClipboard = .Component.CurrentController.getTransferable()
1022 _Component.CurrentController.select(_Offset(DestinationCell,
0,
0,
1,
1).XCellRange)
1023 _Component.CurrentController.insertTransferable(oClipBoard)
1024 ' Restore previous selection in Source
1025 _RestoreSelections(.Component, oSelect)
1026 Set oSourceAddress = .XCellRange.RangeAddress
1031 sCopy = _Offset(DestinationCell,
0,
0, .EndRow - .StartRow +
1, .EndColumn - .StartColumn +
1).RangeName
1036 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1040 End Function
' SFDocuments.SF_Calc.CopyToCell
1042 REM -----------------------------------------------------------------------------
1043 Public Function CopyToRange(Optional ByVal SourceRange As Variant _
1044 , Optional ByVal DestinationRange As Variant _
1046 ''' Copy downwards and/or rightwards a specified source range to a destination range
1047 ''' The source range may belong to another open document
1048 ''' The method imitates the behaviour of a Copy/Paste from a range to a larger range
1049 ''' If the height (resp. width) of the destination area is
> 1 row (resp. column)
1050 ''' then the height (resp. width) of the source must be
<= the height (resp. width)
1051 ''' of the destination. Otherwise nothing happens
1052 ''' If the height (resp.width) of the destination is =
1 then the destination
1053 ''' is expanded downwards (resp. rightwards) up to the height (resp. width)
1054 ''' of the source range
1055 ''' Args:
1056 ''' SourceRange: the source range as a string if it belongs to the same document
1057 ''' or as a reference if it belongs to another open Calc document
1058 ''' DestinationRange: the destination of the copied range of cells, as a string
1059 ''' Returns:
1060 ''' A string representing the modified range of cells
1061 ''' Examples:
1062 ''' oDoc.CopyToRange(
"SheetX.A1:F10
",
"SheetY.C5:J5
")
1063 ''' ' Copy within the same document
1064 ''' ' Returned range: $SheetY.$C$
5:$J$
14
1065 ''' Dim oDocA As Object : Set oDocA = ui.OpenDocument(
"C:\Temp\FileA.ods
", Hidden := True, ReadOnly := True)
1066 ''' Dim oDocB As Object : Set oDocB = ui.OpenDocument(
"C:\Temp\FileB.ods
")
1067 ''' oDocB.CopyToRange(oDocA.Range(
"SheetX.A1:F10
"),
"SheetY.C5:J5
")
1068 ''' ' Copy from
1 file to another
1070 Dim sCopy As String
' Return value
1071 Dim oSource As Object
' Alias of SourceRange to avoid
"Object variable not set
" run-time error
1072 Dim oDestRange As Object
' Destination as a range
1073 Dim oDestCell As Object
' com.sun.star.table.CellAddress
1074 Dim oSelect As Object
' Current selection in source
1075 Dim oClipboard As Object
' com.sun.star.datatransfer.XTransferable
1076 Dim bSameDocument As Boolean
' True when source in same document as destination
1077 Dim lHeight As Long
' Height of destination
1078 Dim lWidth As Long
' Width of destination
1080 Const cstThisSub =
"SFDocuments.Calc.CopyToRange
"
1081 Const cstSubArgs =
"SourceRange, DestinationRange
"
1083 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1084 sCopy =
""
1087 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1088 If Not _IsStillAlive(True) Then GoTo Finally
1089 If Not ScriptForge.SF_Utils._Validate(SourceRange,
"SourceRange
", Array(V_STRING, ScriptForge.V_OBJECT), , , CALCREFERENCE) Then GoTo Finally
1090 If Not ScriptForge.SF_Utils._Validate(DestinationRange,
"DestinationRange
", V_STRING) Then GoTo Finally
1094 ' Copy done via clipboard
1096 ' Check Height/Width destination =
1 or
> Height/Width of source
1097 bSameDocument = ( VarType(SourceRange) = V_STRING )
1098 If bSameDocument Then Set oSource = _ParseAddress(SourceRange) Else Set oSource = SourceRange
1099 Set oDestRange = _ParseAddress(DestinationRange)
1104 lHeight = oSource.Height
' Future height
1105 ElseIf lHeight
< oSource.Height Then
1109 lWidth = oSource.Width
' Future width
1110 ElseIf lWidth
< oSource.Width Then
1116 ' Store actual selection in source
1117 Set oSelect = .Component.CurrentController.getSelection()
1118 ' Select, copy the source range and paste in the destination
1119 .Component.CurrentController.select(.XCellRange)
1120 Set oClipboard = .Component.CurrentController.getTransferable()
1121 _Component.CurrentController.select(oDestRange.XCellRange)
1122 _Component.CurrentController.insertTransferable(oClipBoard)
1123 ' Restore selection in source
1124 _RestoreSelections(.Component, oSelect)
1127 sCopy = _Offset(oDestRange,
0,
0, lHeight, lWidth).RangeName
1131 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1135 End Function
' SFDocuments.SF_Calc.CopyToRange
1137 REM -----------------------------------------------------------------------------
1138 Public Function CreateChart(Optional ByVal ChartName As Variant _
1139 , Optional ByVal SheetName As Variant _
1140 , Optional ByVal Range As Variant _
1141 , Optional ColumnHeader As Variant _
1142 , Optional RowHeader As Variant _
1144 ''' Return a new chart instance initialized with default values
1145 ''' Args:
1146 ''' ChartName: The user-defined name of the new chart
1147 ''' SheetName: The name of an existing sheet
1148 ''' Range: the cell or the range as a string that should be drawn
1149 ''' ColumnHeader: when True, the topmost row of the range will be used to set labels for the category axis or the legend.
1150 ''' Default = False
1151 ''' RowHeader: when True, the leftmost column of the range will be used to set labels for the category axis or the legend.
1152 ''' Default = False
1153 ''' Returns:
1154 ''' A new chart service instance
1155 ''' Exceptions:
1156 ''' DUPLICATECHARTERROR A chart with the same name exists already in the given sheet
1157 ''' Examples:
1158 ''' Dim oChart As Object
1159 ''' Set oChart = oDoc.CreateChart(
"myChart
",
"SheetX
",
"A1:C8
", ColumnHeader := True)
1161 Dim oChart As Object
' Return value
1162 Dim vCharts As Variant
' List of pre-existing charts
1163 Dim oSheet As Object
' Alias of SheetName as reference
1164 Dim oRange As Object
' Alias of Range
1165 Dim oRectangle as new com.sun.star.awt.Rectangle
' Simple shape
1167 Const cstThisSub =
"SFDocuments.Calc.CreateChart
"
1168 Const cstSubArgs =
"ChartName, SheetName, Range, [ColumnHeader=False], [RowHeader=False]
"
1170 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1171 Set oChart = Nothing
1174 If IsMissing(RowHeader) Or IsEmpty(RowHeader) Then Rowheader = False
1175 If IsMissing(ColumnHeader) Or IsEmpty(ColumnHeader) Then ColumnHeader = False
1176 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1177 If Not _IsStillAlive(True) Then GoTo Finally
1178 If Not ScriptForge.SF_Utils._Validate(ChartName,
"ChartName
", V_STRING) Then GoTo Finally
1179 If Not _ValidateSheet(SheetName,
"SheetName
", , True) Then GoTo Finally
1180 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
1181 If Not ScriptForge.SF_Utils._Validate(ColumnHeader,
"ColumnHeader
", ScriptForge.V_BOOLEAN) Then GoTo Finally
1182 If Not ScriptForge.SF_Utils._Validate(RowHeader,
"RowHeader
", ScriptForge.V_BOOLEAN) Then GoTo Finally
1185 vCharts = Charts(SheetName)
1186 If ScriptForge.SF_Array.Contains(vCharts, ChartName, CaseSensitive := True) Then GoTo CatchDuplicate
1189 ' The rectangular shape receives arbitrary values. User can Resize() it later
1192 .Width =
8000 : .Height =
6000
1194 ' Initialize sheet and range
1195 Set oSheet = _Component.getSheets.getByName(SheetName)
1196 Set oRange = _ParseAddress(Range)
1197 ' Create the chart and get ihe corresponding chart instance
1198 oSheet.getCharts.addNewByName(ChartName, oRectangle, Array(oRange.XCellRange.RangeAddress), ColumnHeader, RowHeader)
1199 Set oChart = Charts(SheetName, ChartName)
1200 oChart._Shape.Name = ChartName
' Both user-defined and internal names match ChartName
1201 oChart._Diagram.Wall.FillColor = RGB(
255,
255,
255)
' Align on background color set by the user interface by default
1204 Set CreateChart = oChart
1205 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1210 ScriptForge.SF_Exception.RaiseFatal(DUPLICATECHARTERROR,
"ChartName
", ChartName,
"SheetName
", SheetName,
"Document
", [_Super]._FileIdent())
1212 End Function
' SFDocuments.SF_Calc.CreateChart
1214 REM -----------------------------------------------------------------------------
1215 Public Function CreatePivotTable(Optional ByVal PivotTableName As Variant _
1216 , Optional ByVal SourceRange As Variant _
1217 , Optional ByVal TargetCell As Variant _
1218 , Optional ByRef DataFields As Variant _
1219 , Optional ByRef RowFields As Variant _
1220 , Optional ByRef ColumnFields As Variant _
1221 , Optional ByVal FilterButton As Variant _
1222 , Optional ByVal RowTotals As Variant _
1223 , Optional ByVal ColumnTotals As Variant _
1225 ''' Create a new pivot table with the properties defined by the arguments.
1226 ''' If a pivot table with the same name exists already in the targeted sheet, it will be erased without warning.
1227 ''' Args:
1228 ''' PivotTableName: The user-defined name of the new pivottable
1229 ''' SourceRange: The range as a string containing the raw data.
1230 ''' The first row of the range is presumed to contain the field names of the new pivot table
1231 ''' TargetCell: the top left cell or the range as a string where to locate the pivot table.
1232 ''' Only the top left cell of the range will be considered.
1233 ''' DataFields: A single string or an array of field name + function to apply, formatted like:
1234 ''' Array(
"FieldName[;Function]
", ...)
1235 ''' The allowed functions are: Sum, Count, Average, Max, Min, Product, CountNums, StDev, StDevP, Var, VarP and Median.
1236 ''' The default function is: When the values are all numerical, Sum is used, otherwise Count
1237 ''' RowFields: A single string or an array of the field names heading the pivot table rows
1238 ''' ColumnFields: A single string or an array of the field names heading the pivot table columns
1239 ''' FilterButton: When True (default), display a
"Filter
" button above the pivot table
1240 ''' RowTotals: When True (default), display a separate column for row totals
1241 ''' ColumnTotals: When True (default), display a separate row for column totals
1242 ''' Returns:
1243 ''' Return the range where the new pivot table is deployed.
1244 ''' Examples:
1245 ''' Dim vData As Variant, oDoc As Object, sTable As String, sPivot As String
1246 ''' vData = Array(Array(
"Item
",
"State
",
"Team
",
"2002",
"2003",
"2004"), _
1247 ''' Array(
"Books
",
"Michigan
",
"Jean
",
14788,
30222,
23490), _
1248 ''' Array(
"Candy
",
"Michigan
",
"Jean
",
26388,
15641,
32849), _
1249 ''' Array(
"Pens
",
"Michigan
",
"Jean
",
16569,
32675,
25396), _
1250 ''' Array(
"Books
",
"Michigan
",
"Volker
",
21961,
21242,
29009), _
1251 ''' Array(
"Candy
",
"Michigan
",
"Volker
",
26142,
22407,
32841))
1252 ''' Set oDoc = ui.CreateDocument(
"Calc
")
1253 ''' sTable = oDoc.SetArray(
"A1
", vData)
1254 ''' sPivot = oDoc.CreatePivotTable(
"PT1
", sTable,
"H1
", Array(
"2002",
"2003;count
",
"2004;average
"),
"Item
", Array(
"State
",
"Team
"), False)
1256 Dim sPivotTable As String
' Return value
1257 Dim vData As Variant
' Alias of DataFields
1258 Dim vRows As Variant
' Alias of RowFields
1259 Dim vColumns As Variant
' Alias of ColumnFields
1260 Dim oSourceAddress As Object
' Source as an _Address
1261 Dim oTargetAddress As Object
' Target as an _Address
1262 Dim vHeaders As Variant
' Array of header fields in the source range
1263 Dim oPivotTables As Object
' com.sun.star.sheet.XDataPilotTables
1264 Dim oDescriptor As Object
' com.sun.star.sheet.DataPilotDescriptor
1265 Dim oFields As Object
' ScDataPilotFieldsObj - Collection of fields
1266 Dim oField As Object
' ScDataPilotFieldsObj - A single field
1267 Dim sField As String
' A single field name
1268 Dim sData As String
' A single data field name + function
1269 Dim vDataField As Variant
' A single vData element, split on semicolon
1270 Dim sFunction As String
' Function to apply on a data field (string)
1271 Dim iFunction As Integer
' Equivalent of sFunction as com.sun.star.sheet.GeneralFunction2 constant
1272 Dim oOutputRange As Object
' com.sun.star.table.CellRangeAddress
1275 Const cstThisSub =
"SFDocuments.Calc.CreatePivotTable
"
1276 Const cstSubArgs =
"PivotTableName, SourceRange, TargetCell, DataFields, [RowFields], [ColumnFields]
" _
1277 & ", [FilterButton=True], [RowTotals=True], [ColumnTotals=True]
"
1279 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1280 sPivotTable =
""
1283 If IsMissing(RowFields) Or IsEmpty(RowFields) Then RowFields = Array()
1284 If IsMissing(ColumnFields) Or IsEmpty(ColumnFields) Then ColumnFields = Array()
1285 If IsMissing(FilterButton) Or IsEmpty(FilterButton) Then FilterButton = True
1286 If IsMissing(RowTotals) Or IsEmpty(RowTotals) Then RowTotals = True
1287 If IsMissing(ColumnTotals) Or IsEmpty(ColumnTotals) Then ColumnTotals = True
1288 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1289 If Not _IsStillAlive(True) Then GoTo Finally
1290 If Not ScriptForge.SF_Utils._Validate(PivotTableName,
"PivotTableName
", V_STRING) Then GoTo Finally
1291 If Not ScriptForge.SF_Utils._Validate(SourceRange,
"SourceRange
", V_STRING) Then GoTo Finally
1292 If Not ScriptForge.SF_Utils._Validate(TargetCell,
"TargetCell
", V_STRING) Then GoTo Finally
1293 If IsArray(DataFields) Then
1294 If Not ScriptForge.SF_Utils._ValidateArray(DataFields,
"DataFields
",
1, V_STRING, True) Then GoTo Finally
1296 If Not ScriptForge.SF_Utils._Validate(DataFields,
"DataFields
", V_STRING) Then GoTo Finally
1298 If IsArray(RowFields) Then
1299 If Not ScriptForge.SF_Utils._ValidateArray(RowFields,
"RowFields
",
1, V_STRING, True) Then GoTo Finally
1301 If Not ScriptForge.SF_Utils._Validate(RowFields,
"RowFields
", V_STRING) Then GoTo Finally
1303 If IsArray(ColumnFields) Then
1304 If Not ScriptForge.SF_Utils._ValidateArray(ColumnFields,
"ColumnFields
",
1, V_STRING, True) Then GoTo Finally
1306 If Not ScriptForge.SF_Utils._Validate(ColumnFields,
"ColumnFields
", V_STRING) Then GoTo Finally
1308 If Not ScriptForge.SF_Utils._Validate(FilterButton,
"FilterButton
", ScriptForge.V_BOOLEAN) Then GoTo Finally
1309 If Not ScriptForge.SF_Utils._Validate(RowTotals,
"RowTotals
", ScriptForge.V_BOOLEAN) Then GoTo Finally
1310 If Not ScriptForge.SF_Utils._Validate(ColumnTotals,
"ColumnTotals
", ScriptForge.V_BOOLEAN) Then GoTo Finally
1312 ' Next statements must be outside previous If-block to force their execution even in case of internal call
1313 If IsArray(DataFields) Then vData = DataFields Else vData = Array(DataFields)
1314 If IsArray(RowFields) Then vRows = RowFields Else vRows = Array(RowFields)
1315 If IsArray(ColumnFields) Then vColumns = ColumnFields Else vColumns = Array(ColumnFields)
1319 Set oSourceAddress = _ParseAddress(SourceRange)
1320 vHeaders = GetValue(Offset(SourceRange,
0,
0,
1))
' Content of the first row of the source
1321 Set oTargetAddress = _Offset(TargetCell,
0,
0,
1,
1)
' Retain the top left cell only
1322 Set oPivotTables = oTargetAddress.XSpreadsheet.getDataPilotTables()
1324 ' Initialize new pivot table
1325 Set oDescriptor = oPivotTables.createDataPilotDescriptor()
1326 oDescriptor.setSourceRange(oSourceAddress.XCellRange.RangeAddress)
1327 Set oFields = oDescriptor.getDataPilotFields()
1329 ' Set row fields
1330 For i =
0 To UBound(vRows)
1332 If Len(sField)
> 0 Then
1333 If Not ScriptForge.SF_Utils._Validate(sField,
"RowFields
", V_STRING, vHeaders) Then GoTo Finally
1334 Set oField = oFields.getByName(sField)
1335 oField.Orientation = com.sun.star.sheet.DataPilotFieldOrientation.ROW
1339 ' Set column fields
1340 For i =
0 To UBound(vColumns)
1341 sField = vColumns(i)
1342 If Len(sField)
> 0 Then
1343 If Not ScriptForge.SF_Utils._Validate(sField,
"ColumnFields
", V_STRING, vHeaders) Then GoTo Finally
1344 Set oField = oFields.getByName(sField)
1345 oField.Orientation = com.sun.star.sheet.DataPilotFieldOrientation.COLUMN
1349 ' Set data fields
1350 For i =
0 To UBound(vData)
1352 ' Minimal parsing
1353 If Right(sData,
1) =
";
" Then sData = Left(sData, Len(sData) -
1)
1354 vDataField = Split(sData,
";
")
1355 sField = vDataField(
0)
1356 If UBound(vDataField)
> 0 Then sFunction = vDataField(
1) Else sFunction =
""
1357 ' Define field properties
1358 If Len(sField)
> 0 Then
1359 If Not ScriptForge.SF_Utils._Validate(sField,
"DataFields
", V_STRING, vHeaders) Then GoTo Finally
1360 Set oField = oFields.getByName(sField)
1361 oField.Orientation = com.sun.star.sheet.DataPilotFieldOrientation.DATA
1362 ' Associate the correct function
1363 With com.sun.star.sheet.GeneralFunction2
1364 Select Case UCase(sFunction)
1365 Case
"" : iFunction = .AUTO
1366 Case
"SUM
" : iFunction = .SUM
1367 Case
"COUNT
" : iFunction = .COUNT
1368 Case
"AVERAGE
" : iFunction = .AVERAGE
1369 Case
"MAX
" : iFunction = .MAX
1370 Case
"MIN
" : iFunction = .MIN
1371 Case
"PRODUCT
" : iFunction = .PRODUCT
1372 Case
"COUNTNUMS
": iFunction = .COUNTNUMS
1373 Case
"STDEV
" : iFunction = .STDEV
1374 Case
"STDEVP
" : iFunction = .STDEVP
1375 Case
"VAR
" : iFunction = .VAR
1376 Case
"VARP
" : iFunction = .VARP
1377 Case
"MEDIAN
" : iFunction = .MEDIAN
1379 If Not ScriptForge.SF_Utils._Validate(sFunction,
"DataFields/Function
", V_STRING _
1380 , Array(
"Sum
",
"Count
",
"Average
",
"Max
",
"Min
",
"Product
",
"CountNums
" _
1381 ,
"StDev
",
"StDevP
",
"Var
",
"VarP
",
"Median
") _
1385 oField.Function2 = iFunction
1389 ' Remove any pivot table with same name
1390 If oPivotTables.hasByName(PivotTableName) Then oPivotTables.removeByName(PivotTableName)
1392 ' Finalize the new pivot table
1393 oDescriptor.ShowFilterButton = FilterButton
1394 oDescriptor.RowGrand = RowTotals
1395 oDescriptor.ColumnGrand = ColumnTotals
1396 oPivotTables.insertNewByName(PivotTableName, oTargetAddress.XCellRange.getCellByPosition(
0,
0).CellAddress, oDescriptor)
1398 ' Determine the range of the new pivot table
1399 Set oOutputRange = oPivotTables.getByName(PivotTableName).OutputRange
1401 sPivotTable = _Component.getSheets().getCellRangeByPosition(.StartColumn, .StartRow, .EndColumn, .EndRow, .Sheet).AbsoluteName
1405 CreatePivotTable = sPivotTable
1406 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1410 End Function
' SFDocuments.SF_Calc.CreatePivotTable
1412 REM -----------------------------------------------------------------------------
1413 Public Function DAvg(Optional ByVal Range As Variant) As Double
1414 ''' Get the average of the numeric values stored in the given range
1415 ''' Args:
1416 ''' Range : the range as a string where to get the values from
1417 ''' Returns:
1418 ''' The average of the numeric values as a double
1419 ''' Examples:
1420 ''' Val = oDoc.DAvg(
"~.A1:A1000
")
1423 DAvg = _DFunction(
"DAvg
", Range)
1427 End Function
' SFDocuments.SF_Calc.DAvg
1429 REM -----------------------------------------------------------------------------
1430 Public Function DCount(Optional ByVal Range As Variant) As Long
1431 ''' Get the number of numeric values stored in the given range
1432 ''' Args:
1433 ''' Range : the range as a string where to get the values from
1434 ''' Returns:
1435 ''' The number of numeric values as a Long
1436 ''' Examples:
1437 ''' Val = oDoc.DCount(
"~.A1:A1000
")
1440 DCount = _DFunction(
"DCount
", Range)
1444 End Function
' SFDocuments.SF_Calc.DCount
1446 REM -----------------------------------------------------------------------------
1447 Public Function DMax(Optional ByVal Range As Variant) As Double
1448 ''' Get the greatest of the numeric values stored in the given range
1449 ''' Args:
1450 ''' Range : the range as a string where to get the values from
1451 ''' Returns:
1452 ''' The greatest of the numeric values as a double
1453 ''' Examples:
1454 ''' Val = oDoc.DMax(
"~.A1:A1000
")
1457 DMax = _DFunction(
"DMax
", Range)
1461 End Function
' SFDocuments.SF_Calc.DMax
1463 REM -----------------------------------------------------------------------------
1464 Public Function DMin(Optional ByVal Range As Variant) As Double
1465 ''' Get the smallest of the numeric values stored in the given range
1466 ''' Args:
1467 ''' Range : the range as a string where to get the values from
1468 ''' Returns:
1469 ''' The smallest of the numeric values as a double
1470 ''' Examples:
1471 ''' Val = oDoc.DMin(
"~.A1:A1000
")
1474 DMin = _DFunction(
"DMin
", Range)
1478 End Function
' SFDocuments.SF_Calc.DMin
1480 REM -----------------------------------------------------------------------------
1481 Public Function DSum(Optional ByVal Range As Variant) As Double
1482 ''' Get sum of the numeric values stored in the given range
1483 ''' Args:
1484 ''' Range : the range as a string where to get the values from
1485 ''' Returns:
1486 ''' The sum of the numeric values as a double
1487 ''' Examples:
1488 ''' Val = oDoc.DSum(
"~.A1:A1000
")
1491 DSum = _DFunction(
"DSum
", Range)
1495 End Function
' SFDocuments.SF_Calc.DSum
1497 REM -----------------------------------------------------------------------------
1498 Public Function ExportRangeToFile(Optional ByVal Range As Variant _
1499 , Optional ByVal FileName As Variant _
1500 , Optional ByVal ImageType As Variant _
1501 , Optional ByVal Overwrite As Variant _
1503 ''' Store the given range as an image to the given file location
1504 ''' Actual selections are not impacted
1505 ''' Inspired by https://stackoverflow.com/questions/
30509532/how-to-export-cell-range-to-pdf-file
1506 ''' Args:
1507 ''' Range: sheet name or cell range to be exported, as a string
1508 ''' FileName: Identifies the file where to save. It must follow the SF_FileSystem.FileNaming notation
1509 ''' ImageType: the name of the targeted media type
1510 ''' Allowed values: jpeg, pdf (default) and png
1511 ''' Overwrite: True if the destination file may be overwritten (default = False)
1512 ''' Returns:
1513 ''' False if the document could not be saved
1514 ''' Exceptions:
1515 ''' RANGEEXPORTERROR The destination has its readonly attribute set or overwriting rejected
1516 ''' Examples:
1517 ''' oDoc.ExportRangeToFile(
'SheetX.B2:J15
",
"C:\Me\Range2.png
", ImageType :=
"png
", Overwrite := True)
1519 Dim bSaved As Boolean
' return value
1520 Dim oSfa As Object
' com.sun.star.ucb.SimpleFileAccess
1521 Dim sFile As String
' Alias of FileName
1522 Dim vStoreArguments As Variant
' Array of com.sun.star.beans.PropertyValue
1523 Dim vFilterData As Variant
' Array of com.sun.star.beans.PropertyValue
1524 Dim FSO As Object
' SF_FileSystem
1525 Dim vImageTypes As Variant
' Array of permitted image types
1526 Dim vFilters As Variant
' Array of corresponding filters in the same order as vImageTypes
1527 Dim sFilter As String
' The filter to apply
1528 Dim oSelect As Object
' Currently selected range(s)
1529 Dim oAddress As Object
' Alias of Range
1531 Const cstImageTypes =
"jpeg,pdf,png
"
1532 Const cstFilters =
"calc_jpg_Export,calc_pdf_Export,calc_png_Export
"
1534 Const cstThisSub =
"SFDocuments.Calc.ExportRangeToFile
"
1535 Const cstSubArgs =
"Range, FileName, [ImageType=
""pdf
""|
""jpeg
""|
""png
""], [Overwrite=False]
"
1537 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo CatchError
1541 If IsMissing(ImageType) Or IsEmpty(ImageType) Then ImageType =
"pdf
"
1542 If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
1544 vImageTypes = Split(cstImageTypes,
",
")
1545 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1546 If Not _IsStillAlive() Then GoTo Finally
1547 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
1548 If Not ScriptForge.SF_Utils._ValidateFile(FileName,
"FileName
") Then GoTo Finally
1549 If Not ScriptForge.SF_Utils._Validate(ImageType,
"ImageType
", V_STRING, vImageTypes) Then GoTo Finally
1550 If Not ScriptForge.SF_Utils._Validate(Overwrite,
"Overwrite
", ScriptForge.V_BOOLEAN) Then GoTo Finally
1553 ' Check destination file overwriting
1554 Set FSO = CreateScriptService(
"FileSystem
")
1555 sFile = FSO._ConvertToUrl(FileName)
1556 If FSO.FileExists(FileName) Then
1557 If Overwrite = False Then GoTo CatchError
1558 Set oSfa = ScriptForge.SF_Utils._GetUNOService(
"FileAccess
")
1559 If oSfa.isReadonly(sFile) Then GoTo CatchError
1563 ' Setup arguments
1564 vFilters = Split(cstFilters,
",
")
1565 sFilter = vFilters(ScriptForge.SF_Array.IndexOf(vImageTypes, ImageType, CaseSensitive := False))
1566 Set oAddress = _ParseAddress(Range)
1568 ' The filter arguments differ between
1569 ' 1) pdf : store range in Selection property value
1570 ' 2) png, jpeg : save current selection, select range, restore initial selection
1571 If LCase(ImageType) =
"pdf
" Then
1572 vFilterData = Array(ScriptForge.SF_Utils._MakePropertyValue(
"Selection
", oAddress.XCellRange) )
1573 vStoreArguments = Array( _
1574 ScriptForge.SF_Utils._MakePropertyValue(
"FilterName
", sFilter) _
1575 , ScriptForge.SF_Utils._MakePropertyValue(
"FilterData
", vFilterData) _
1577 Else
' png, jpeg
1578 ' Save the current selection(s)
1579 Set oSelect = _Component.CurrentController.getSelection()
1580 _Component.CurrentController.select(oAddress.XCellRange)
1581 vStoreArguments = Array( _
1582 ScriptForge.SF_Utils._MakePropertyValue(
"FilterName
", sFilter) _
1583 , ScriptForge.SF_Utils._MakePropertyValue(
"SelectionOnly
", True) _
1587 ' Apply the filter and export
1588 _Component.storeToUrl(sFile, vStoreArguments)
1589 If LCase(ImageType)
<> "pdf
" Then _RestoreSelections(_Component, oSelect)
1594 ExportRangeToFile = bSaved
1595 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1600 ScriptForge.SF_Exception.RaiseFatal(RANGEEXPORTERROR,
"FileName
", FileName,
"Overwrite
", Overwrite)
1602 End Function
' SFDocuments.SF_Chart.ExportRangeToFile
1604 REM -----------------------------------------------------------------------------
1605 Public Function Forms(Optional ByVal SheetName As Variant _
1606 , Optional ByVal Form As Variant _
1608 ''' Return either
1609 ''' - the list of the Forms contained in the given sheet
1610 ''' - a SFDocuments.Form object based on its name or its index
1611 ''' Args:
1612 ''' SheetName: the name of the sheet containing the requested form or forms
1613 ''' Form: a form stored in the document given by its name or its index
1614 ''' When absent, the list of available forms is returned
1615 ''' To get the first (unique ?) form stored in the form document, set Form =
0
1616 ''' Exceptions:
1617 ''' CALCFORMNOTFOUNDERROR Form not found
1618 ''' Returns:
1619 ''' A zero-based array of strings if Form is absent
1620 ''' An instance of the SF_Form class if Form exists
1621 ''' Example:
1622 ''' Dim myForm As Object, myList As Variant
1623 ''' myList = oDoc.Forms(
"ThisSheet
")
1624 ''' Set myForm = oDoc.Forms(
"ThisSheet
",
0)
1626 Dim oForm As Object
' The new Form class instance
1627 Dim oMainForm As Object
' com.sun.star.comp.sdb.Content
1628 Dim oXForm As Object
' com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
1629 Dim vFormNames As Variant
' Array of form names
1630 Dim oForms As Object
' Forms collection
1631 Const cstDrawPage = -
1 ' There is no DrawPages collection in Calc sheets
1633 Const cstThisSub =
"SFDocuments.Calc.Forms
"
1634 Const cstSubArgs =
"SheetName, [Form=
""""]
"
1636 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1639 If IsMissing(Form) Or IsEmpty(Form) Then Form =
""
1640 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1641 If Not _IsStillAlive() Then GoTo Finally
1642 If Not _ValidateSheet(SheetName,
"SheetName
", , True) Then GoTo Finally
1643 If Not ScriptForge.SF_Utils._Validate(Form,
"Form
", Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally
1647 ' Start from the Calc sheet and go down to forms
1648 Set oForms = _Component.getSheets.getByName(SheetName).DrawPage.Forms
1649 vFormNames = oForms.getElementNames()
1651 If Len(Form) =
0 Then
' Return the list of valid form names
1654 If VarType(Form) = V_STRING Then
' Find the form by name
1655 If Not ScriptForge.SF_Utils._Validate(Form,
"Form
", V_STRING, vFormNames) Then GoTo Finally
1656 Set oXForm = oForms.getByName(Form)
1657 Else
' Find the form by index
1658 If Form
< 0 Or Form
>= oForms.Count Then GoTo CatchNotFound
1659 Set oXForm = oForms.getByIndex(Form)
1661 ' Create the new Form class instance
1662 Set oForm = SF_Register._NewForm(oXForm)
1664 Set .[_Parent] = [Me]
1665 ._SheetName = SheetName
1666 ._FormType = ISCALCFORM
1667 Set ._Component = _Component
1674 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1679 ScriptForge.SF_Exception.RaiseFatal(CALCFORMNOTFOUNDERROR, Form, _FileIdent())
1680 End Function
' SFDocuments.SF_Calc.Forms
1682 REM -----------------------------------------------------------------------------
1683 Function GetColumnName(Optional ByVal ColumnNumber As Variant) As String
1684 ''' Convert a column number (range
1,
2,.
.1024) into its letter counterpart (range
'A
',
'B
',..
'AMJ
').
1685 ''' Args:
1686 ''' ColumnNumber: the column number, must be in the interval
1 ...
1024
1687 ''' Returns:
1688 ''' a string representation of the column name, in range
'A
'..
'AMJ
'
1689 ''' If ColumnNumber is not in the allowed range, returns a zero-length string
1690 ''' Example:
1691 ''' MsgBox oDoc.GetColumnName(
1022)
' "AMH
"
1692 ''' Adapted from a Python function by sundar nataraj
1693 ''' http://stackoverflow.com/questions/
23861680/convert-spreadsheet-number-to-column-letter
1695 Dim sCol As String
' Return value
1696 Const cstThisSub =
"SFDocuments.Calc.GetColumnName
"
1697 Const cstSubArgs =
"ColumnNumber
"
1699 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1703 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1704 If Not SF_Utils._Validate(ColumnNumber,
"ColumnNumber
", V_NUMERIC) Then GoTo Finally
1708 If (ColumnNumber
> 0) And (ColumnNumber
<= MAXCOLS) Then sCol = _GetColumnName(ColumnNumber)
1711 GetColumnName = sCol
1712 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1716 End Function
' SFDocuments.SF_Calc.GetColumnName
1718 REM -----------------------------------------------------------------------------
1719 Public Function GetFormula(Optional ByVal Range As Variant) As Variant
1720 ''' Get the formula(e) stored in the given range of cells
1721 ''' Args:
1722 ''' Range : the range as a string where to get the formula from
1723 ''' Returns:
1724 ''' A scalar, a zero-based
1D array or a zero-based
2D array of strings
1725 ''' Examples:
1726 ''' Val = oDoc.GetFormula(
"~.A1:A1000
")
1728 Dim vGet As Variant
' Return value
1729 Dim oAddress As Object
' Alias of Range
1730 Dim vDataArray As Variant
' DataArray compatible with .DataArray UNO property
1731 Const cstThisSub =
"SFDocuments.Calc.GetFormula
"
1732 Const cstSubArgs =
"Range
"
1734 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1738 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1739 If Not _IsStillAlive() Then GoTo Finally
1740 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
1745 Set oAddress = _ParseAddress(Range)
1746 vDataArray = oAddress.XCellRange.getFormulaArray()
1748 ' Convert the data array to scalar, vector or array
1749 vGet = _ConvertFromDataArray(vDataArray)
1753 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1757 End Function
' SFDocuments.SF_Calc.GetFormula
1759 REM -----------------------------------------------------------------------------
1760 Public Function GetProperty(Optional ByVal PropertyName As Variant _
1761 , Optional ObjectName As Variant _
1763 ''' Return the actual value of the given property
1764 ''' Args:
1765 ''' PropertyName: the name of the property as a string
1766 ''' ObjectName: a sheet or range name
1767 ''' Returns:
1768 ''' The actual value of the property
1769 ''' Exceptions:
1770 ''' ARGUMENTERROR The property does not exist
1772 Const cstThisSub =
"SFDocuments.Calc.GetProperty
"
1773 Const cstSubArgs =
""
1775 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1779 If IsMissing(ObjectName) Or IsEMpty(ObjectName) Then ObjectName =
""
1780 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1781 If Not ScriptForge.SF_Utils._Validate(PropertyName,
"PropertyName
", V_STRING, Properties()) Then GoTo Catch
1782 If Not ScriptForge.SF_Utils._Validate(ObjectName,
"ObjectName
", V_STRING) Then GoTo Catch
1786 ' Superclass or subclass property ?
1787 If ScriptForge.SF_Array.Contains([_Super].Properties(), PropertyName) Then
1788 GetProperty = [_Super].GetProperty(PropertyName)
1789 ElseIf Len(ObjectName) =
0 Then
1790 GetProperty = _PropertyGet(PropertyName)
1792 GetProperty = _PropertyGet(PropertyName, ObjectName)
1796 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1800 End Function
' SFDocuments.SF_Calc.GetProperty
1802 REM -----------------------------------------------------------------------------
1803 Public Function GetValue(Optional ByVal Range As Variant) As Variant
1804 ''' Get the value(s) stored in the given range of cells
1805 ''' Args:
1806 ''' Range : the range as a string where to get the value from
1807 ''' Returns:
1808 ''' A scalar, a zero-based
1D array or a zero-based
2D array of strings and doubles
1809 ''' To convert doubles to dates, use the CDate builtin function
1810 ''' Examples:
1811 ''' Val = oDoc.GetValue(
"~.A1:A1000
")
1813 Dim vGet As Variant
' Return value
1814 Dim oAddress As Object
' Alias of Range
1815 Dim vDataArray As Variant
' DataArray compatible with .DataArray UNO property
1816 Const cstThisSub =
"SFDocuments.Calc.GetValue
"
1817 Const cstSubArgs =
"Range
"
1819 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1823 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1824 If Not _IsStillAlive() Then GoTo Finally
1825 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
1830 Set oAddress = _ParseAddress(Range)
1831 vDataArray = oAddress.XCellRange.getDataArray()
1833 ' Convert the data array to scalar, vector or array
1834 vGet = _ConvertFromDataArray(vDataArray)
1838 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1842 End Function
' SFDocuments.SF_Calc.GetValue
1844 REM -----------------------------------------------------------------------------
1845 Public Function ImportFromCSVFile(Optional ByVal FileName As Variant _
1846 , Optional ByVal DestinationCell As Variant _
1847 , Optional ByVal FilterOptions As Variant _
1849 ''' Import the content of a CSV-formatted text file starting from a given cell
1850 ''' Beforehand the destination area will be cleared from any content and format
1851 ''' Args:
1852 ''' FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
1853 ''' DestinationCell: the destination of the copied range of cells, as a string
1854 ''' If given as range, the destination will be reduced to its top-left cell
1855 ''' FilterOptions: The arguments of the CSV input filter.
1856 ''' Read https://wiki.documentfoundation.org/Documentation/DevGuide/Spreadsheet_Documents#Filter_Options_for_the_CSV_Filter
1857 ''' Default: input file encoding is UTF8
1858 ''' separator = comma, semi-colon or tabulation
1859 ''' string delimiter = double quote
1860 ''' all lines are included
1861 ''' quoted strings are formatted as texts
1862 ''' special numbers are detected
1863 ''' all columns are presumed texts
1864 ''' language = english/US =
> decimal separator is
".
", thousands separator =
",
"
1865 ''' Returns:
1866 ''' A string representing the modified range of cells
1867 ''' The modified area depends only on the content of the source file
1868 ''' Exceptions:
1869 ''' DOCUMENTOPENERROR The csv file could not be opened
1870 ''' Examples:
1871 ''' oDoc.ImportFromCSVFile(
"C:\Temp\myCsvFile.csv
",
"SheetY.C5
")
1873 Dim sImport As String
' Return value
1874 Dim oUI As Object
' UI service
1875 Dim oSource As Object
' New Calc document with csv loaded
1876 Dim oSelect As Object
' Current selection in destination
1878 Const cstFilter =
"Text - txt - csv (StarCalc)
"
1879 Const cstFilterOptions =
"9/
44/
59/MRG,
34,
76,
1,,
1033,true,true
"
1880 Const cstThisSub =
"SFDocuments.Calc.ImportFromCSVFile
"
1881 Const cstSubArgs =
"FileName, DestinationCell, [FilterOptions]=
""9/
44/
59/MRG,
34,
76,
1,,
1033,true,true
"""
1883 ' If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1884 sImport =
""
1887 If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = cstFilterOptions
1888 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1889 If Not _IsStillAlive(True) Then GoTo Finally
1890 If Not ScriptForge.SF_Utils._ValidateFile(FileName,
"FileName
") Then GoTo Finally
1891 If Not ScriptForge.SF_Utils._Validate(DestinationCell,
"DestinationCell
", V_STRING) Then GoTo Finally
1895 ' Input file is loaded in an empty worksheet. Data are copied to destination cell
1896 Set oUI = CreateScriptService(
"UI
")
1897 Set oSource = oUI.OpenDocument(FileName _
1898 , ReadOnly := True _
1900 , FilterName := cstFilter _
1901 , FilterOptions := FilterOptions _
1903 ' Remember current selection and restore it after copy
1904 Set oSelect = _Component.CurrentController.getSelection()
1905 sImport = CopyToCell(oSource.Range(
"*
"), DestinationCell)
1906 _RestoreSelections(_Component, oSelect)
1909 If Not IsNull(oSource) Then oSource.CloseDocument(False)
1910 ImportFromCSVFile = sImport
1911 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
1915 End Function
' SFDocuments.SF_Calc.ImportFromCSVFile
1917 REM -----------------------------------------------------------------------------
1918 Public Sub ImportFromDatabase(Optional ByVal FileName As Variant _
1919 , Optional ByVal RegistrationName As Variant _
1920 , Optional ByVal DestinationCell As Variant _
1921 , Optional ByVal SQLCommand As Variant _
1922 , Optional ByVal DirectSQL As Variant _
1924 ''' Import the content of a database table, query or resultset, i.e. the result of a SELECT SQL command,
1925 ''' starting from a given cell
1926 ''' Beforehand the destination area will be cleared from any content and format
1927 ''' The modified area depends only on the content of the source data
1928 ''' Args:
1929 ''' FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
1930 ''' RegistrationName: the name of a registered database
1931 ''' It is ignored if FileName
<> ""
1932 ''' DestinationCell: the destination of the copied range of cells, as a string
1933 ''' If given as a range of cells, the destination will be reduced to its top-left cell
1934 ''' SQLCommand: either a table or query name (without square brackets)
1935 ''' or a full SQL commands where table and fieldnames are preferably surrounded with square brackets
1936 ''' Returns:
1937 ''' Implemented as a Sub because the doImport UNO method does not return any error
1938 ''' Exceptions:
1939 ''' BASEDOCUMENTOPENERROR The database file could not be opened
1940 ''' Examples:
1941 ''' oDoc.ImportFromDatabase(
"C:\Temp\myDbFile.odb
", ,
"SheetY.C5
",
"SELECT * FROM [Employees] ORDER BY [LastName]
")
1943 Dim oDBContext As Object
' com.sun.star.sdb.DatabaseContext
1944 Dim oDatabase As Object
' SFDatabases.Database service
1945 Dim lCommandType As Long
' A com.sun.star.sheet.DataImportMode.xxx constant
1946 Dim oQuery As Object
' com.sun.star.ucb.XContent
1947 Dim bDirect As Boolean
' Alias of DirectSQL
1948 Dim oDestRange As Object
' Destination as a range
1949 Dim oDestAddress As Object
' com.sun.star.table.CellRangeAddress
1950 Dim oDestCell As Object
' com.sun.star.table.XCell
1951 Dim oSelect As Object
' Current selection in destination
1952 Dim vImportOptions As Variant
' Array of PropertyValues
1954 Const cstThisSub =
"SFDocuments.Calc.ImportFromDatabase
"
1955 Const cstSubArgs =
"[FileName=
""""], [RegistrationName=
""""], DestinationCell, SQLCommand, [DirectSQL=False]
"
1957 ' If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1961 If IsMissing(FileName) Or IsEmpty(FileName) Then FileName =
""
1962 If IsMissing(RegistrationName) Or IsEmpty(RegistrationName) Then RegistrationName =
""
1963 If IsMissing(DirectSQL) Or IsEmpty(DirectSQL) Then DirectSQL = False
1964 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1965 If Not _IsStillAlive(True) Then GoTo Finally
1966 If Not ScriptForge.SF_Utils._ValidateFile(FileName,
"FileName
", , True) Then GoTo Finally
1967 If Not ScriptForge.SF_Utils._Validate(DestinationCell,
"DestinationCell
", V_STRING) Then GoTo Finally
1968 If Not ScriptForge.SF_Utils._Validate(SQLCommand,
"SQLCommand
", V_STRING) Then GoTo Finally
1969 If Not ScriptForge.SF_Utils._Validate(DirectSQL,
"DirectSQL
", ScriptForge.V_BOOLEAN) Then GoTo Finally
1972 ' Check the existence of FileName
1973 If Len(FileName) =
0 Then
' FileName has precedence over RegistrationName
1974 If Len(RegistrationName) =
0 Then GoTo CatchError
1975 Set oDBContext = ScriptForge.SF_Utils._GetUNOService(
"DatabaseContext
")
1976 If Not oDBContext.hasRegisteredDatabase(RegistrationName) Then GoTo CatchError
1977 FileName = ScriptForge.SF_FileSystem._ConvertFromUrl(oDBContext.getDatabaseLocation(RegistrationName))
1979 If Not ScriptForge.SF_FileSystem.FileExists(FileName) Then GoTo CatchError
1982 ' Check command type
1983 Set oDatabase = ScriptForge.SF_Services.CreateScriptService(
"SFDatabases.Database
", FileName, , True)
' Read-only
1984 If IsNull(oDatabase) Then GoTo CatchError
1986 If ScriptForge.SF_Array.Contains(.Tables, SQLCommand) Then
1988 lCommandType = com.sun.star.sheet.DataImportMode.TABLE
1989 ElseIf ScriptForge.SF_Array.Contains(.Queries, SQLCommand) Then
1990 Set oQuery = .XConnection.Queries.getByName(SQLCommand)
1991 bDirect = Not oQuery.EscapeProcessing
1992 lCommandType = com.sun.star.sheet.DataImportMode.QUERY
1995 lCommandType = com.sun.star.sheet.DataImportMode.SQL
1996 SQLCommand = ._ReplaceSquareBrackets(SQLCommand)
1999 Set oDatabase = oDatabase.Dispose()
2002 ' Determine the destination cell as the top-left coordinates of the given range
2003 Set oDestRange = _ParseAddress(DestinationCell)
2004 Set oDestAddress = oDestRange.XCellRange.RangeAddress
2005 Set oDestCell = oDestRange.XSpreadsheet.getCellByPosition(oDestAddress.StartColumn, oDestAddress.StartRow)
2007 ' Remember current selection
2008 Set oSelect = _Component.CurrentController.getSelection()
2009 ' Import arguments
2010 vImportOptions = Array(_
2011 ScriptForge.SF_Utils._MakePropertyValue(
"DatabaseName
", ScriptForge.SF_FileSystem._ConvertToUrl(FileName)) _
2012 , ScriptForge.SF_Utils._MakePropertyValue(
"SourceObject
", SQLCommand) _
2013 , ScriptForge.SF_Utils._MakePropertyValue(
"SourceType
", lCommandType) _
2014 , ScriptForge.SF_Utils._MakePropertyValue(
"IsNative
", bDirect) _
2016 oDestCell.doImport(vImportOptions)
2017 ' Restore selection after import_
2018 _RestoreSelections(_Component, oSelect)
2021 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2026 SF_Exception.RaiseFatal(BASEDOCUMENTOPENERROR,
"FileName
", FileName,
"RegistrationName
", RegistrationName)
2028 End Sub
' SFDocuments.SF_Calc.ImportFromDatabase
2030 REM -----------------------------------------------------------------------------
2031 Public Function InsertSheet(Optional ByVal SheetName As Variant _
2032 , Optional ByVal BeforeSheet As Variant _
2034 ''' Insert a new empty sheet before an existing sheet or at the end of the list of sheets
2035 ''' Args:
2036 ''' SheetName: The name of the new sheet
2037 ''' BeforeSheet: The name (string) or index (numeric, starting from
1) of the sheet before which to insert
2038 ''' Returns:
2039 ''' True if the sheet could be inserted successfully
2040 ''' Examples:
2041 ''' oDoc.InsertSheet(
"SheetX
",
"SheetY
")
2043 Dim bInsert As Boolean
' Return value
2044 Dim vSheets As Variant
' List of existing sheets
2045 Dim lSheetIndex As Long
' Index of a sheet
2046 Const cstThisSub =
"SFDocuments.Calc.InsertSheet
"
2047 Const cstSubArgs =
"SheetName, [BeforeSheet=
""""]
"
2049 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2053 If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet =
32768
2054 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2055 If Not _IsStillAlive(True) Then GoTo Finally
2056 If Not _ValidateSheet(SheetName,
"SheetName
", True) Then GoTo Finally
2057 If Not _ValidateSheet(BeforeSheet,
"BeforeSheet
", , True, , True) Then GoTo Finally
2059 vSheets = _Component.getSheets.getElementNames()
2062 If VarType(BeforeSheet) = V_STRING Then
2063 lSheetIndex = ScriptForge.SF_Array.IndexOf(vSheets, BeforeSheet)
2065 lSheetIndex = BeforeSheet -
1
2066 If lSheetIndex
< 0 Then lSheetIndex =
0
2067 If lSheetIndex
> UBound(vSheets) Then lSheetIndex = UBound(vSheets) +
1
2069 _Component.getSheets.insertNewByName(SheetName, lSheetIndex)
2073 InsertSheet = binsert
2074 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2078 End Function
' SFDocuments.SF_Calc.InsertSheet
2080 REM -----------------------------------------------------------------------------
2081 Public Function Methods() As Variant
2082 ''' Return the list of public methods of the Calc service as an array
2085 "A1Style
" _
2086 ,
"Charts
" _
2087 ,
"ClearAll
" _
2088 ,
"ClearFormats
" _
2089 ,
"ClearValues
" _
2090 ,
"CopySheet
" _
2091 ,
"CopySheetFromFile
" _
2092 ,
"CopyToCell
" _
2093 ,
"CopyToRange
" _
2094 ,
"CreateChart
" _
2095 ,
"DAvg
" _
2096 ,
"DCount
" _
2097 ,
"DMax
" _
2098 ,
"DMin
" _
2099 ,
"DSum
" _
2100 ,
"ExportRangeToFile
" _
2101 ,
"GetColumnName
" _
2102 ,
"GetFormula
" _
2103 ,
"GetValue
" _
2104 ,
"ImportFromCSVFile
" _
2105 ,
"ImportFromDatabase
" _
2106 ,
"InsertSheet
" _
2107 ,
"MoveRange
" _
2108 ,
"MoveSheet
" _
2109 ,
"Offset
" _
2110 ,
"OpenRangeSelector
" _
2111 ,
"Printf
" _
2112 ,
"PrintOut
" _
2113 ,
"RemoveSheet
" _
2114 ,
"RenameSheet
" _
2115 ,
"SetArray
" _
2116 ,
"SetCellStyle
" _
2117 ,
"SetFormula
" _
2118 ,
"SetValue
" _
2119 ,
"ShiftDown
" _
2120 ,
"ShiftLeft
" _
2121 ,
"ShiftRight
" _
2122 ,
"ShiftUp
" _
2123 ,
"SortRange
" _
2126 End Function
' SFDocuments.SF_Calc.Methods
2128 REM -----------------------------------------------------------------------------
2129 Public Function MoveRange(Optional ByVal Source As Variant _
2130 , Optional ByVal Destination As Variant _
2132 ''' Move a specified source range to a destination range
2133 ''' Args:
2134 ''' Source: the source range of cells as a string
2135 ''' Destination: the destination of the moved range of cells, as a string
2136 ''' If given as a range of cells, the destination will be reduced to its top-left cell
2137 ''' Returns:
2138 ''' A string representing the modified range of cells
2139 ''' The modified area depends only on the size of the source area
2140 ''' Examples:
2141 ''' oDoc.MoveRange(
"SheetX.A1:F10
",
"SheetY.C5
")
2143 Dim sMove As String
' Return value
2144 Dim oSource As Object
' Alias of Source to avoid
"Object variable not set
" run-time error
2145 Dim oSourceAddress As Object
' com.sun.star.table.CellRangeAddress
2146 Dim oDestRange As Object
' Destination as a range
2147 Dim oDestAddress As Object
' com.sun.star.table.CellRangeAddress
2148 Dim oDestCell As Object
' com.sun.star.table.CellAddress
2149 Dim oSelect As Object
' Current selection in source
2150 Dim oClipboard As Object
' com.sun.star.datatransfer.XTransferable
2151 Dim oCellRanges As Object
' com.sun.star.sheet.SheetCellRanges
2152 Dim vRangeAddresses As Variant
' Array of com.sun.star.table.CellRangeAddress
2155 Const cstThisSub =
"SFDocuments.Calc.MoveRange
"
2156 Const cstSubArgs =
"Source, Destination
"
2158 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2159 sMove =
""
2162 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2163 If Not _IsStillAlive(True) Then GoTo Finally
2164 If Not _Validate(Source,
"Source
", V_STRING) Then GoTo Finally
2165 If Not _Validate(Destination,
"Destination
", V_STRING) Then GoTo Finally
2169 Set oSourceAddress = _ParseAddress(Source).XCellRange.RangeAddress
2170 Set oDestRange = _ParseAddress(Destination)
2171 Set oDestAddress = oDestRange.XCellRange.RangeAddress
2172 Set oDestCell = New com.sun.star.table.CellAddress
2174 oDestCell.Sheet = .Sheet
2175 oDestCell.Column = .StartColumn
2176 oDestCell.Row = .StartRow
2178 oDestRange.XSpreadsheet.moveRange(oDestCell, oSourceAddress)
2181 sMove = _Offset(Destination,
0,
0, .EndRow - .StartRow +
1, .EndColumn - .StartColumn +
1).RangeName
2186 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2190 End Function
' SFDocuments.SF_Calc.MoveRange
2192 REM -----------------------------------------------------------------------------
2193 Public Function MoveSheet(Optional ByVal SheetName As Variant _
2194 , Optional ByVal BeforeSheet As Variant _
2196 ''' Move a sheet before an existing sheet or at the end of the list of sheets
2197 ''' Args:
2198 ''' SheetName: The name of the sheet to move
2199 ''' BeforeSheet: The name (string) or index (numeric, starting from
1) of the sheet before which to move the sheet
2200 ''' Returns:
2201 ''' True if the sheet could be moved successfully
2202 ''' Examples:
2203 ''' oDoc.MoveSheet(
"SheetX
",
"SheetY
")
2205 Dim bMove As Boolean
' Return value
2206 Dim vSheets As Variant
' List of existing sheets
2207 Dim lSheetIndex As Long
' Index of a sheet
2208 Const cstThisSub =
"SFDocuments.Calc.MoveSheet
"
2209 Const cstSubArgs =
"SheetName, [BeforeSheet=
""""]
"
2211 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2215 If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet =
32768
2216 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2217 If Not _IsStillAlive(True) Then GoTo Finally
2218 If Not _ValidateSheet(SheetName,
"SheetName
", , True) Then GoTo Finally
2219 If Not _ValidateSheet(BeforeSheet,
"BeforeSheet
", , True, , True) Then GoTo Finally
2221 vSheets = _Component.getSheets.getElementNames()
2224 If VarType(BeforeSheet) = V_STRING Then
2225 lSheetIndex = ScriptForge.SF_Array.IndexOf(vSheets, BeforeSheet)
2227 lSheetIndex = BeforeSheet -
1
2228 If lSheetIndex
< 0 Then lSheetIndex =
0
2229 If lSheetIndex
> UBound(vSheets) Then lSheetIndex = UBound(vSheets) +
1
2231 _Component.getSheets.MoveByName(SheetName, lSheetIndex)
2236 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2240 End Function
' SFDocuments.SF_Calc.MoveSheet
2242 REM -----------------------------------------------------------------------------
2243 Public Function Offset(Optional ByRef Range As Variant _
2244 , Optional ByVal Rows As Variant _
2245 , Optional ByVal Columns As Variant _
2246 , Optional ByVal Height As Variant _
2247 , Optional ByVal Width As Variant _
2249 ''' Returns a new range offset by a certain number of rows and columns from a given range
2250 ''' Args:
2251 ''' Range : the range, as a string, from which the function searches for the new range
2252 ''' Rows : the number of rows by which the reference was corrected up (negative value) or down.
2253 ''' Use
0 (default) to stay in the same row.
2254 ''' Columns : the number of columns by which the reference was corrected to the left (negative value) or to the right.
2255 ''' Use
0 (default) to stay in the same column
2256 ''' Height : the vertical height for an area that starts at the new reference position.
2257 ''' Default = no vertical resizing
2258 ''' Width : the horizontal width for an area that starts at the new reference position.
2259 ''' Default - no horizontal resizing
2260 ''' Arguments Rows and Columns must not lead to zero or negative start row or column.
2261 ''' Arguments Height and Width must not lead to zero or negative count of rows or columns.
2262 ''' Returns:
2263 ''' A new range as a string
2264 ''' Exceptions:
2265 ''' OFFSETADDRESSERROR The computed range of cells falls beyond the sheet boundaries
2266 ''' Examples:
2267 ''' oDoc.Offset(
"A1
",
2,
2)
' "'SheetX
'.$C$
3" (A1 moved by two rows and two columns down)
2268 ''' oDoc.Offset(
"A1
",
2,
2,
5,
6)
' "'SheetX
'.$C$
3:$H$
7"
2270 Dim sOffset As String
' Return value
2271 Dim oAddress As Object
' Alias of Range
2272 Const cstThisSub =
"SFDocuments.Calc.Offset
"
2273 Const cstSubArgs =
"Range, [Rows=
0], [Columns=
0], [Height], [Width]
"
2275 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2276 sOffset =
""
2279 If IsMissing(Rows) Or IsEmpty(Rows) Then Rows =
0
2280 If IsMissing(Columns) Or IsEmpty(Columns) Then Columns =
0
2281 If IsMissing(Height) Or IsEmpty(Height) Then Height =
0
2282 If IsMissing(Width) Or IsEmpty(Width) Then Width =
0
2283 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2284 If Not _IsStillAlive() Then GoTo Finally
2285 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
2286 If Not ScriptForge.SF_Utils._Validate(Rows,
"Rows
", ScriptForge.V_NUMERIC) Then GoTo Finally
2287 If Not ScriptForge.SF_Utils._Validate(Columns,
"Columns
", ScriptForge.V_NUMERIC) Then GoTo Finally
2288 If Not ScriptForge.SF_Utils._Validate(Height,
"Height
", ScriptForge.V_NUMERIC) Then GoTo Finally
2289 If Not ScriptForge.SF_Utils._Validate(Width,
"Width
", ScriptForge.V_NUMERIC) Then GoTo Finally
2293 ' Define the new range string
2294 Set oAddress = _Offset(Range, Rows, Columns, Height, Width)
2295 sOffset = oAddress.RangeName
2299 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2303 End Function
' SFDocuments.SF_Calc.Offset
2305 REM -----------------------------------------------------------------------------
2306 Public Function OpenRangeSelector(Optional ByVal Title As Variant _
2307 , Optional ByVal Selection As Variant _
2308 , Optional ByVal SingleCell As Variant _
2309 , Optional ByVal CloseAfterSelect As Variant _
2311 ''' Activates the Calc document, opens a non-modal dialog with a text box,
2312 ''' let the user make a selection in the current or another sheet and
2313 ''' returns the selected area as a string.
2314 ''' This method does not change the current selection.
2315 ''' Args:
2316 ''' Title: the title to display on the top of the dialog
2317 ''' Selection: a default preselection as a String. When absent, the first element of the
2318 ''' current selection is preselected.
2319 ''' SingleCell: When True, only a single cell may be selected. Default = False
2320 ''' CloseAfterSelect: When True (default-, the dialog is closed immediately after
2321 ''' the selection. When False, the user may change his/her mind and must close
2322 ''' the dialog manually.
2323 ''' Returns:
2324 ''' The selected range as a string, or the empty string when the user cancelled the request (close window button)
2325 ''' Exceptions:
2326 ''' Examples:
2327 ''' Dim sSelect As String, vValues As Variant
2328 ''' sSelect = oDoc.OpenRangeSelector(
"Select a range ...
")
2329 ''' If sSelect =
"" Then Exit Function
2330 ''' vValues = oDoc.GetValue(sSelect)
2332 Dim sSelector As String
' Return value
2333 Dim vPropertyValues As Variant
' Array of com.sun.star.beans.PropertyValue
2334 Dim oSelection As Object
' The current selection before opening the selector
2335 Dim oAddress As Object
' Preselected address as _Address
2337 Const cstThisSub =
"SFDocuments.Calc.OpenRangeSelector
"
2338 Const cstSubArgs =
"[Title=
""""], [Selection=
""~
""], [SingleCell=False], [CloseAfterSelect=True]
"
2340 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2341 sSelector =
""
2344 If IsMissing(Title) Or IsEmpty(Title) Then Title =
""
2345 If IsMissing(Selection) Or IsEmpty(Selection) Then Selection =
"~
"
2346 If IsMissing(SingleCell) Or IsEmpty(SingleCell) Then SingleCell = False
2347 If IsMissing(CloseAfterSelect) Or IsEmpty(CloseAfterSelect) Then CloseAfterSelect = True
2348 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2349 If Not _IsStillAlive() Then GoTo Finally
2350 If Not ScriptForge.SF_Utils._Validate(Title,
"Title
", V_STRING) Then GoTo Finally
2351 If Not ScriptForge.SF_Utils._Validate(Selection,
"Selection
", V_STRING) Then GoTo Finally
2352 If Not ScriptForge.SF_Utils._Validate(SingleCell,
"SingleCell
", ScriptForge.V_BOOLEAN) Then GoTo Finally
2353 If Not ScriptForge.SF_Utils._Validate(CloseAfterSelect,
"CloseAfterSelect
", ScriptForge.V_BOOLEAN) Then GoTo Finally
2357 ' Save the current selections
2358 Set oSelection = _Component.CurrentController.getSelection()
2360 ' Process preselection and select its containing sheet
2361 Set oAddress = _ParseAddress(Selection)
2362 Activate(oAddress.SheetName)
2364 ' Build arguments array and execute the dialog box
2365 With ScriptForge.SF_Utils
2366 vPropertyValues = Array( _
2367 ._MakePropertyValue(
"Title
", Title) _
2368 , ._MakePropertyValue(
"CloseOnMouseRelease
", CloseAfterSelect) _
2369 , ._MakePropertyValue(
"InitialValue
", oAddress.XCellRange.AbsoluteName) _
2370 , ._MakePropertyValue(
"SingleCellMode
", SingleCell) _
2373 sSelector = SF_DocumentListener.RunRangeSelector(_Component, vPropertyValues)
2375 ' Restore the saved selections
2376 _RestoreSelections(_Component, oSelection)
2379 OpenRangeSelector = sSelector
2380 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2384 End Function
' SFDocuments.SF_Calc.OpenRangeSelector
2386 REM -----------------------------------------------------------------------------
2387 Public Function Printf(Optional ByVal InputStr As Variant _
2388 , Optional ByVal Range As Variant _
2389 , Optional ByVal TokenCharacter As Variant _
2391 ''' Returns the input string after substitution of its tokens by
2392 ''' their values in the given range
2393 ''' This method is usually used in combination with SetFormula()
2394 ''' The accepted tokens are:
2395 ''' - %S The sheet name containing the range, including single quotes when necessary
2396 ''' - %R1 The row number of the topleft part of the range
2397 ''' - %C1 The column letter of the topleft part of the range
2398 ''' - %R2 The row number of the bottomright part of the range
2399 ''' - %C2 The column letter of the bottomright part of the range
2400 ''' Args:
2401 ''' InputStr: usually a Calc formula or a part of a formula, but may be any string
2402 ''' Range: the range, as a string from which the values of the tokens are derived
2403 ''' TokenCharacter: the character identifying tokens. Default =
"%
".
2404 ''' Double the TokenCharacter to not consider it as a token.
2405 ''' Returns:
2406 ''' The input string after substitution of the contained tokens
2407 ''' Exceptions:
2408 ''' Examples:
2409 ''' Assume we have in A1:E10 a matrix of numbers. To obtain the sum by row in F1:F10 ...
2410 ''' Dim range As String, formula As String
2411 ''' range =
"$A$
1:$E$
10")
2412 ''' formula =
"=SUM($%C1%R1:$%C2%R1)
" ' "=SUM($A1:$E1)
", note the relative references
2413 ''' oDoc.SetFormula(
"$F$
1:$F$
10", formula)
2414 ''' 'F1 will contain =Sum($A1:$E1)
2415 ''' 'F2 =Sum($A2:$E2)
2416 ''' ' ...
2418 Dim sPrintf As String
' Return value
2419 Dim vSubstitute As Variants
' Array of strings representing the token values
2420 Dim oAddress As Object
' A range as an _Address object
2421 Dim sSheetName As String
' The %S token value
2422 Dim sC1 As String
' The %C1 token value
2423 Dim sR1 As String
' The %R1 token value
2424 Dim sC2 As String
' The %C2 token value
2425 Dim sR2 As String
' The %R2 token value
2427 Const cstPseudoToken =
"@#@
"
2429 Const cstThisSub =
"SFDocuments.Calc.Printf
"
2430 Const cstSubArgs =
"InputStr, Range, TokenCharacter=
""%
"""
2432 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2433 sPrintf =
""
2436 If IsMissing(TokenCharacter) Or IsEmpty(TokenCharacter) Then TokenCharacter =
"%
"
2437 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2438 If Not _IsStillAlive() Then GoTo Finally
2439 If Not ScriptForge.SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2440 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
2441 If Not ScriptForge.SF_Utils._Validate(TokenCharacter,
"TokenCharacter
", V_STRING) Then GoTo Finally
2445 ' Define the token values
2446 Set oAddress = _ParseAddress(Range)
2447 With oAddress.XCellRange
2448 sC1 = _GetColumnName(.RangeAddress.StartColumn +
1)
2449 sR1 = CStr(.RangeAddress.StartRow +
1)
2450 sC2 = _GetColumnName(.RangeAddress.EndColumn +
1)
2451 sR2 = CStr(.RangeAddress.EndRow +
1)
2452 sSheetName = _QuoteSheetName(oAddress.XSpreadsheet.Name)
2455 ' Substitute tokens by their values
2456 sPrintf = ScriptForge.SF_String.ReplaceStr(InputStr _
2457 , Array(TokenCharacter
& TokenCharacter _
2458 , TokenCharacter
& "R1
" _
2459 , TokenCharacter
& "C1
" _
2460 , TokenCharacter
& "R2
" _
2461 , TokenCharacter
& "C2
" _
2462 , TokenCharacter
& "S
" _
2465 , Array(cstPseudoToken _
2477 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2481 End Function
' SFDocuments.SF_Calc.Printf
2483 REM -----------------------------------------------------------------------------
2484 Public Function PrintOut(Optional ByVal SheetName As Variant _
2485 , Optional ByVal Pages As Variant _
2486 , Optional ByVal Copies As Variant _
2488 ''' Send the content of the given sheet to the printer.
2489 ''' The printer might be defined previously by default, by the user or by the SetPrinter() method
2490 ''' Args:
2491 ''' SheetName: the sheet to print. Default = the active sheet
2492 ''' Pages: the pages to print as a string, like in the user interface. Example:
"1-
4;
10;
15-
18". Default = all pages
2493 ''' Copies: the number of copies
2494 ''' Returns:
2495 ''' True when successful
2496 ''' Examples:
2497 ''' oDoc.PrintOut(
"SheetX
",
"1-
4;
10;
15-
18", Copies :=
2)
2499 Dim bPrint As Boolean
' Return value
2500 Dim oSheet As Object
' SheetName as a reference
2502 Const cstThisSub =
"SFDocuments.Calc.PrintOut
"
2503 Const cstSubArgs =
"[SheetName=
""~
""], [Pages=
""""], [Copies=
1]
"
2505 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2509 If IsMissing(SheetName) Or IsEmpty(SheetName) Then SheetName =
""
2510 If IsMissing(Pages) Or IsEmpty(Pages) Then Pages =
""
2511 If IsMissing(Copies) Or IsEmpty(Copies) Then Copies =
1
2513 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2514 If Not _IsStillAlive() Then GoTo Finally
2515 If Not _ValidateSheet(SheetName,
"SheetName
", , True, True) Then GoTo Finally
2516 If Not ScriptForge.SF_Utils._Validate(Pages,
"Pages
", V_STRING) Then GoTo Finally
2517 If Not ScriptForge.SF_Utils._Validate(Copies,
"Copies
", ScriptForge.V_NUMERIC) Then GoTo Finally
2521 If SheetName =
"~
" Then SheetName =
""
2522 ' Make given sheet active
2523 If Len(SheetName)
> 0 Then
2525 Set oSheet = .getSheets.getByName(SheetName)
2526 Set .CurrentController.ActiveSheet = oSheet
2530 bPrint = [_Super].PrintOut(Pages, Copies, _Component)
2534 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2538 End Function
' SFDocuments.SF_Calc.PrintOut
2540 REM -----------------------------------------------------------------------------
2541 Public Function Properties() As Variant
2542 ''' Return the list or properties of the Calc class as an array
2544 Properties = Array( _
2545 "CurrentSelection
" _
2546 ,
"CustomProperties
" _
2547 ,
"Description
" _
2548 ,
"DocumentProperties
" _
2549 ,
"DocumentType
" _
2550 ,
"ExportFilters
" _
2551 ,
"FirstCell
" _
2552 ,
"FirstColumn
" _
2553 ,
"FirstRow
" _
2554 ,
"Height
" _
2555 ,
"ImportFilters
" _
2556 ,
"IsBase
" _
2557 ,
"IsCalc
" _
2558 ,
"IsDraw
" _
2559 ,
"IsImpress
" _
2560 ,
"IsMath
" _
2561 ,
"IsWriter
" _
2562 ,
"Keywords
" _
2563 ,
"LastCell
" _
2564 ,
"LastColumn
" _
2565 ,
"LastRow
" _
2566 ,
"Range
" _
2567 ,
"Readonly
" _
2568 ,
"Region
" _
2569 ,
"Sheet
" _
2570 ,
"SheetName
" _
2571 ,
"Sheets
" _
2572 ,
"Subject
" _
2573 ,
"Title
" _
2574 ,
"Width
" _
2575 ,
"XCellRange
" _
2576 ,
"XComponent
" _
2577 ,
"XSheetCellCursor
" _
2578 ,
"XSpreadsheet
" _
2581 End Function
' SFDocuments.SF_Calc.Properties
2583 REM -----------------------------------------------------------------------------
2584 Public Function RemoveSheet(Optional ByVal SheetName As Variant) As Boolean
2585 ''' Remove an existing sheet from the document
2586 ''' Args:
2587 ''' SheetName: The name of the sheet to remove
2588 ''' Returns:
2589 ''' True if the sheet could be removed successfully
2590 ''' Examples:
2591 ''' oDoc.RemoveSheet(
"SheetX
")
2593 Dim bRemove As Boolean
' Return value
2594 Const cstThisSub =
"SFDocuments.Calc.RemoveSheet
"
2595 Const cstSubArgs =
"SheetName
"
2597 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2601 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2602 If Not _IsStillAlive(True) Then GoTo Finally
2603 If Not _ValidateSheet(SheetName,
"SheetName
", , True) Then GoTo Finally
2607 _Component.getSheets.RemoveByName(SheetName)
2611 RemoveSheet = bRemove
2612 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2616 End Function
' SFDocuments.SF_Calc.RemoveSheet
2618 REM -----------------------------------------------------------------------------
2619 Public Function RenameSheet(Optional ByVal SheetName As Variant _
2620 , Optional ByVal NewName As Variant _
2622 ''' Rename a specified sheet
2623 ''' Args:
2624 ''' SheetName: The name of the sheet to rename
2625 ''' NewName: Must not exist
2626 ''' Returns:
2627 ''' True if the sheet could be renamed successfully
2628 ''' Exceptions:
2629 ''' DUPLICATESHEETERROR A sheet with the given name exists already
2630 ''' Examples:
2631 ''' oDoc.RenameSheet(
"SheetX
",
"SheetY
")
2633 Dim bRename As Boolean
' Return value
2634 Const cstThisSub =
"SFDocuments.Calc.RenameSheet
"
2635 Const cstSubArgs =
"SheetName, NewName
"
2637 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2641 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2642 If Not _IsStillAlive(True) Then GoTo Finally
2643 If Not _ValidateSheet(SheetName,
"SheetName
", , True) Then GoTo Finally
2644 If Not _ValidateSheet(NewName,
"NewName
", True) Then GoTo Finally
2648 _Component.getSheets.getByName(SheetName).setName(NewName)
2652 RenameSheet = bRename
2653 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2657 End Function
' SFDocuments.SF_Calc.RenameSheet
2659 REM -----------------------------------------------------------------------------
2660 Public Function SetArray(Optional ByVal TargetCell As Variant _
2661 , Optional ByRef Value As Variant _
2663 ''' Set the given (array of) values starting from the target cell
2664 ''' The updated area expands itself from the target cell or from the top-left corner of the given range
2665 ''' as far as determined by the size of the input Value.
2666 ''' Vectors are always expanded vertically
2667 ''' Args:
2668 ''' TargetCell : the cell or the range as a string that should receive a new value
2669 ''' Value: a scalar, a vector or an array with the new values
2670 ''' The new values should be strings, numeric values or dates. Other types empty the corresponding cell
2671 ''' Returns:
2672 ''' A string representing the updated range
2673 ''' Exceptions:
2674 ''' OFFSETADDRESSERROR The computed range of cells falls beyond the sheet boundaries
2675 ''' Examples:
2676 ''' oDoc.SetArray(
"SheetX.A1
", SF_Array.RangeInit(
1,
1000))
2678 Dim sSet As String
' Return value
2679 Dim oSet As Object
' _Address alias of sSet
2680 Dim vDataArray As Variant
' DataArray compatible with .DataArray UNO property
2681 Const cstThisSub =
"SFDocuments.Calc.SetArray
"
2682 Const cstSubArgs =
"TargetCell, Value
"
2684 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2688 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2689 If Not _IsStillAlive() Then GoTo Finally
2690 If Not ScriptForge.SF_Utils._Validate(TargetCell,
"TargetCell
", V_STRING) Then GoTo Finally
2691 If IsArray(Value) Then
2692 If Not ScriptForge.SF_Utils._ValidateArray(Value,
"Value
") Then GoTo Finally
2694 If Not ScriptForge.SF_Utils._Validate(Value,
"Value
") Then GoTo Finally
2699 ' Convert argument to data array and derive new range from its size
2700 vDataArray = _ConvertToDataArray(Value)
2701 If UBound(vDataArray)
< LBound(vDataArray) Then GoTo Finally
2702 Set oSet = _Offset(TargetCell,
0,
0, plHeight := UBound(vDataArray) +
1, plWidth := UBound(vDataArray(
0)) +
1)
' +
1 : vDataArray is zero-based
2704 .XCellRange.setDataArray(vDataArray)
2710 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2714 End Function
' SFDocuments.SF_Calc.SetArray
2716 REM -----------------------------------------------------------------------------
2717 Public Function SetCellStyle(Optional ByVal TargetRange As Variant _
2718 , Optional ByVal Style As Variant _
2719 , Optional ByVal FilterFormula As Variant _
2720 , Optional ByVal FilterScope As Variant _
2722 ''' Apply the given cell style in the given range
2723 ''' If the cell style does not exist, an error is raised
2724 ''' The range is updated and the remainder of the sheet is left untouched
2725 ''' Either the full range is updated or a selection based on a FilterFormula
2726 ''' Args:
2727 ''' TargetRange : the range as a string that should receive a new cell style
2728 ''' Style: the style name as a string
2729 ''' FilterFormula: a Calc formula to select among the given Range
2730 ''' When left empty, all the cells of the range are formatted with the new style
2731 ''' FilterScope:
"CELL
" (default value),
"ROW
" or
"COLUMN
"
2732 ''' When FilterFormula is present, FilterScope is mandatory
2733 ''' Returns:
2734 ''' A string representing the updated range
2735 ''' Examples:
2736 ''' oDoc.SetCellStyle(
"A1:F1
",
"Heading
2")
2737 ''' oDoc.SetCellStype(
"A1:J20
",
"Wrong
",
"=(A1
<0)
",
"CELL
")
2739 Dim sSet As String
' Return value
2740 Dim oAddress As _Address
' Alias of TargetRange
2741 Dim oStyleFamilies As Object
' com.sun.star.container.XNameAccess
2742 Dim vStyles As Variant
' Array of existing cell styles
2743 Dim vRanges() As Variant
' Array of filtered ranges
2746 Const cstStyle =
"CellStyles
"
2747 Const cstThisSub =
"SFDocuments.Calc.SetCellStyle
"
2748 Const cstSubArgs =
"TargetRange, Style, [FilterFormula=
""], [FilterScope=
""CELL
""|
""ROW
""|
""COLUMN
""]
"
2750 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2754 If IsMissing(FilterFormula) Or IsEmpty(FilterFormula) Then FilterFormula =
""
2755 If IsMissing(FilterScope) Or IsEmpty(FilterScope) Then FilterScope =
"CELL
"
2756 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2757 If Not _IsStillAlive() Then GoTo Finally
2758 If Not ScriptForge.SF_Utils._Validate(TargetRange,
"TargetRange
", Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
2759 ' Check that the given style really exists
2760 Set oStyleFamilies = _Component.StyleFamilies
2761 If oStyleFamilies.hasByName(cstStyle) Then vStyles = oStyleFamilies.getByName(cstStyle).getElementNames() Else vStyles = Array()
2762 If Not ScriptForge.SF_Utils._Validate(Style,
"Style
", V_STRING, vStyles) Then GoTo Finally
2763 ' Filter formula
2764 If Not ScriptForge.SF_Utils._Validate(FilterFormula,
"FilterFormula
", V_STRING) Then GoTo Finally
2765 If Len(FilterFormula)
> 0 Then
2766 If Not ScriptForge.SF_Utils._Validate(FilterScope,
"FilterScope
", V_STRING, Array(
"CELL
",
"ROW
",
"COLUMN
")) Then GoTo Finally
2768 If Not ScriptForge.SF_Utils._Validate(FilterScope,
"FilterScope
", V_STRING) Then GoTo Finally
2773 If VarType(TargetRange) = V_STRING Then Set oAddress = _ParseAddress(TargetRange) Else Set oAddress = TargetRange
2775 If Len(FilterFormula) =
0 Then
' When the full range should be updated
2776 .XCellRange.CellStyle = Style
2777 Else
' When the range has to be cut in subranges
2778 vRanges() = _ComputeFilter(oAddress, FilterFormula, UCase(FilterScope))
2779 For i =
0 To UBound(vRanges)
2780 vRanges(i).XCellRange.CellStyle = Style
2788 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2792 End Function
' SFDocuments.SF_Calc.SetCellStyle
2794 REM -----------------------------------------------------------------------------
2795 Public Function SetFormula(Optional ByVal TargetRange As Variant _
2796 , Optional ByRef Formula As Variant _
2798 ''' Set the given (array of) formulae in the given range
2799 ''' The full range is updated and the remainder of the sheet is left untouched
2800 ''' If the given formula is a string:
2801 ''' the unique formula is pasted across the whole range with adjustment of the relative references
2802 ''' Otherwise
2803 ''' If the size of Formula
< the size of Range, then the other cells are emptied
2804 ''' If the size of Formula
> the size of Range, then Formula is only partially copied
2805 ''' Vectors are always expanded vertically, except if the range has a height of exactly
1 row
2806 ''' Args:
2807 ''' TargetRange : the range as a string that should receive a new Formula
2808 ''' Formula: a scalar, a vector or an array with the new formula(e) as strings for each cell of the range.
2809 ''' Returns:
2810 ''' A string representing the updated range
2811 ''' Examples:
2812 ''' oDoc.SetFormula(
"A1
",
"=A2
")
2813 ''' oDoc.SetFormula(
"A1:F1
", Array(
"=A2
",
"=B2
",
"=C2+
10"))
' Horizontal vector, partially empty
2814 ''' oDoc.SetFormula(
"A1:D2
",
"=E1
")
' D2 contains the formula
"=H2
"
2816 Dim sSet As String
' Return value.XSpreadsheet.Name)
2817 Dim oAddress As Object
' Alias of TargetRange
2818 Dim vDataArray As Variant
' DataArray compatible with .DataArray UNO property
2819 Const cstThisSub =
"SFDocuments.Calc.SetFormula
"
2820 Const cstSubArgs =
"TargetRange, Formula
"
2822 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2826 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2827 If Not _IsStillAlive() Then GoTo Finally
2828 If Not ScriptForge.SF_Utils._Validate(TargetRange,
"TargetRange
", Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
2829 If IsArray(Formula) Then
2830 If Not ScriptForge.SF_Utils._ValidateArray(Formula,
"Formula
",
0, V_STRING) Then GoTo Finally
2832 If Not ScriptForge.SF_Utils._Validate(Formula,
"Formula
", V_STRING) Then GoTo Finally
2837 If VarType(TargetRange) = V_STRING Then Set oAddress = _ParseAddress(TargetRange) Else Set oAddress = TargetRange
2839 If IsArray(Formula) Then
2840 ' Convert to data array and limit its size to the size of the initial range
2841 vDataArray = _ConvertToDataArray(Formula, .Height -
1, .Width -
1)
2842 If UBound(vDataArray)
< LBound(vDataArray) Then GoTo Finally
2843 .XCellRange.setFormulaArray(vDataArray)
2846 ' Store formula in top-left cell and paste it along the whole range
2847 .getCellByPosition(
0,
0).setFormula(Formula)
2848 .fillSeries(com.sun.star.sheet.FillDirection.TO_BOTTOM, com.sun.star.sheet.FillMode.SIMPLE,
0,
0,
0)
2849 .fillSeries(com.sun.star.sheet.FillDirection.TO_RIGHT, com.sun.star.sheet.FillMode.SIMPLE,
0,
0,
0)
2857 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2861 End Function
' SFDocuments.SF_Calc.SetFormula
2863 REM -----------------------------------------------------------------------------
2864 Private Function SetProperty(Optional ByVal psProperty As String _
2865 , Optional ByVal pvValue As Variant _
2867 ''' Set the new value of the named property
2868 ''' Args:
2869 ''' psProperty: the name of the property
2870 ''' pvValue: the new value of the given property
2871 ''' Returns:
2872 ''' True if successful
2874 Dim bSet As Boolean
' Return value
2875 Static oSession As Object
' Alias of SF_Session
2876 Dim cstThisSub As String
2877 Const cstSubArgs =
"Value
"
2879 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2882 cstThisSub =
"SFDocuments.Calc.set
" & psProperty
2883 If IsMissing(pvValue) Then pvValue = Empty
2884 'ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
' Validation done in Property Lets
2886 If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(
"Session
")
2888 Select Case UCase(psProperty)
2889 Case UCase(
"CurrentSelection
")
2890 CurrentSelection = pvValue
2891 Case UCase(
"CustomProperties
")
2892 CustomProperties = pvValue
2893 Case UCase(
"Description
")
2894 Description = pvValue
2895 Case UCase(
"Keywords
")
2897 Case UCase(
"Subject
")
2899 Case UCase(
"Title
")
2907 'ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2911 End Function
' SFDocuments.SF_Calc.SetProperty
2913 REM -----------------------------------------------------------------------------
2914 Public Function SetValue(Optional ByVal TargetRange As Variant _
2915 , Optional ByRef Value As Variant _
2917 ''' Set the given value in the given range
2918 ''' The full range is updated and the remainder of the sheet is left untouched
2919 ''' If the size of Value
< the size of Range, then the other cells are emptied
2920 ''' If the size of Value
> the size of Range, then Value is only partially copied
2921 ''' Vectors are always expanded vertically, except if the range has a height of exactly
1 row
2922 ''' Args:
2923 ''' TargetRange : the range as a string that should receive a new value
2924 ''' Value: a scalar, a vector or an array with the new values for each cell o.XSpreadsheet.Name)f the range.
2925 ''' The new values should be strings, numeric values or dates. Other types empty the corresponding cell
2926 ''' Returns:
2927 ''' A string representing the updated range
2928 ''' Examples:
2929 ''' oDoc.SetValue(
"A1
",
2)
2930 ''' oDoc.SetValue(
"A1:F1
", Array(
1,
2,
3))
' Horizontal vector, partially empty
2931 ''' oDoc.SetValue(
"A1:D2
", SF_Array.AppendRow(Array(
1,
2,
3,
4), Array(
5,
6,
7,
8)))
2933 Dim sSet As String
' Return value
2934 Dim oAddress As Object
' Alias of TargetRange
2935 Dim vDataArray As Variant
' DataArray compatible with .DataArray UNO property
2936 Const cstThisSub =
"SFDocuments.Calc.SetValue
"
2937 Const cstSubArgs =
"TargetRange, Value
"
2939 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2943 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2944 If Not _IsStillAlive() Then GoTo Finally
2945 If Not ScriptForge.SF_Utils._Validate(TargetRange,
"TargetRange
", V_STRING) Then GoTo Finally
2946 If IsArray(Value) Then
2947 If Not ScriptForge.SF_Utils._ValidateArray(Value,
"Value
") Then GoTo Finally
2949 If Not ScriptForge.SF_Utils._Validate(Value,
"Value
") Then GoTo Finally
2954 Set oAddress = _ParseAddress(TargetRange)
2956 ' Convert to data array and limit its size to the size of the initial range
2957 vDataArray = _ConvertToDataArray(Value, .Height -
1, .Width -
1)
2958 If UBound(vDataArray)
< LBound(vDataArray) Then GoTo Finally
2959 .XCellRange.setDataArray(vDataArray)
2965 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
2969 End Function
' SFDocuments.SF_Calc.SetValue
2971 REM -----------------------------------------------------------------------------
2972 Public Function ShiftDown(Optional ByVal Range As Variant _
2973 , Optional ByVal WholeRow As Variant _
2974 , Optional ByVal Rows As Variant _
2976 ''' Move a specified range and all cells below in the same columns downwards by inserting empty cells
2977 ''' The inserted cells can span whole rows or be limited to the width of the range
2978 ''' The height of the inserted area is provided by the Rows argument
2979 ''' Nothing happens if the range shift crosses one of the edges of the worksheet
2980 ''' The execution of the method has no effect on the current selection
2981 ''' Args:
2982 ''' Range: the range above which cells have to be inserted, as a string
2983 ''' WholeRow: when True (default = False), insert whole rows
2984 ''' Rows: the height of the area to insert. Default = the height of the Range argument
2985 ''' Returns:
2986 ''' A string representing the new location of the initial range
2987 ''' Examples:
2988 ''' newrange = oDoc.ShiftDown(
"SheetX.A1:F10
")
' "$SheetX.$A$
11:$F$
20"
2989 ''' newrange = oDoc.ShiftDown(
"SheetX.A1:F10
", Rows :=
3)
' "$SheetX.$A$
4:$F$
13"
2991 Dim sShift As String
' Return value
2992 Dim oSourceAddress As Object
' Alias of Range as _Address
2993 Dim lHeight As Long
' Range height
2994 Dim oShiftAddress As Object
' com.sun.star.table.CellRangeAddress - Range adjusted to the right width
2995 Dim lShiftMode As Long
' One of the com.sun.star.sheet.CellInsertMode enum values
2997 Const cstThisSub =
"SFDocuments.Calc.ShiftDown
"
2998 Const cstSubArgs =
"Range, [WholeRow=False], [Rows]
"
3000 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
3001 sShift =
""
3004 If IsMissing(WholeRow) Or IsEmpty(WholeRow) Then WholeRow = False
3005 If IsMissing(Rows) Or IsEmpty(Rows) Then Rows =
0
3006 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
3007 If Not _IsStillAlive(True) Then GoTo Finally
3008 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
3009 If Not ScriptForge.SF_Utils._Validate(WholeRow,
"WholeRow
", ScriptForge.V_BOOLEAN) Then GoTo Finally
3010 If Not ScriptForge.SF_Utils._Validate(Rows,
"Rows
", ScriptForge.V_NUMERIC) Then GoTo Finally
3014 Set oSourceAddress = _ParseAddress(Range)
3018 ' Manage the height of the area to shift
3019 ' The insertCells() method inserts a number of rows equal to the height of the cell range to shift
3021 If Rows
<=
0 Then Rows = lHeight
3022 If _LastCell(.XSpreadsheet)(
1) + Rows
> MAXROWS Then GoTo Catch
3023 If Rows
<> lHeight Then
3024 Set oShiftAddress = _Offset(oSourceAddress,
0,
0, Rows,
0).XCellRange.RangeAddress
3026 Set oShiftAddress = .XCellRange.RangeAddress
3029 ' Determine the shift mode
3030 With com.sun.star.sheet.CellInsertMode
3031 If WholeRow Then lShiftMode = .ROWS Else lShiftMode = .DOWN
3034 ' Move the cells as requested. This modifies .XCellRange
3035 .XSpreadsheet.insertCells(oShiftAddress, lShiftMode)
3037 ' Determine the receiving area
3038 sShift = .XCellRange.AbsoluteName
3044 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
3047 ' When error, return the original range
3048 If Not IsNull(oSourceAddress) Then sShift = oSourceAddress.RangeName
3050 End Function
' SFDocuments.SF_Calc.ShiftDown
3052 REM -----------------------------------------------------------------------------
3053 Public Function ShiftLeft(Optional ByVal Range As Variant _
3054 , Optional ByVal WholeColumn As Variant _
3055 , Optional ByVal Columns As Variant _
3057 ''' Delete the leftmost columns of a specified range and move all cells at their right leftwards
3058 ''' The deleted cells can span whole columns or be limited to the height of the range
3059 ''' The width of the deleted area is provided by the Columns argument
3060 ''' The execution of the method has no effect on the current selection
3061 ''' Args:
3062 ''' Range: the range in which cells have to be erased, as a string
3063 ''' WholeColumn: when True (default = False), erase whole columns
3064 ''' Columns: the width of the area to delete.
3065 ''' Default = the width of the Range argument, it is also its maximum value
3066 ''' Returns:
3067 ''' A string representing the location of the remaining part of the initial range,
3068 ''' or the zero-length string if the whole range has been deleted
3069 ''' Examples:
3070 ''' newrange = oDoc.ShiftLeft(
"SheetX.G1:L10
")
' """
3071 ''' newrange = oDoc.ShiftLeft(
"SheetX.G1:L10
", Columns :=
3)
' "$SheetX.$G$
1:$I$
10"
3073 Dim sShift As String
' Return value
3074 Dim oSourceAddress As Object
' Alias of Range as _Address
3075 Dim lWidth As Long
' Range width
3076 Dim oShiftAddress As Object
' com.sun.star.table.CellRangeAddress - Range adjusted to the right width
3077 Dim lShiftMode As Long
' One of the com.sun.star.sheet.CellDeleteMode enum values
3079 Const cstThisSub =
"SFDocuments.Calc.ShiftLeft
"
3080 Const cstSubArgs =
"Range, [WholeColumn=False], [Columns]
"
3082 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
3083 sShift =
""
3086 If IsMissing(WholeColumn) Or IsEmpty(WholeColumn) Then WholeColumn = False
3087 If IsMissing(Columns) Or IsEmpty(Columns) Then Columns =
0
3088 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
3089 If Not _IsStillAlive(True) Then GoTo Finally
3090 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
3091 If Not ScriptForge.SF_Utils._Validate(WholeColumn,
"WholeColumn
", ScriptForge.V_BOOLEAN) Then GoTo Finally
3092 If Not ScriptForge.SF_Utils._Validate(Columns,
"Columns
", ScriptForge.V_NUMERIC) Then GoTo Finally
3096 Set oSourceAddress = _ParseAddress(Range)
3097 Set _LastParsedAddress = Nothing
' Range will be erased. Force re-parsing next time
3101 ' Manage the width of the area to delete
3102 ' The removeRange() method erases a number of columns equal to the width of the cell range to delete
3104 If Columns
<=
0 Then Columns = lWidth
3105 If Columns
< lWidth Then
3106 Set oShiftAddress = _Offset(oSourceAddress,
0,
0,
0, Columns).XCellRange.RangeAddress
3107 Else
' Columns is capped at the range width
3108 Set oShiftAddress = .XCellRange.RangeAddress
3111 ' Determine the Delete mode
3112 With com.sun.star.sheet.CellDeleteMode
3113 If WholeColumn Then lShiftMode = .COLUMNS Else lShiftMode = .LEFT
3116 ' Move the cells as requested. This modifies .XCellRange
3117 .XSpreadsheet.removeRange(oShiftAddress, lShiftMode)
3119 ' Determine the remaining area
3120 If Columns
< lWidth Then sShift = .XCellRange.AbsoluteName
3126 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
3129 ' When error, return the original range
3130 If Not IsNull(oSourceAddress) Then sShift = oSourceAddress.RangeName
3132 End Function
' SFDocuments.SF_Calc.ShiftLeft
3134 REM -----------------------------------------------------------------------------
3135 Public Function ShiftRight(Optional ByVal Range As Variant _
3136 , Optional ByVal WholeColumn As Variant _
3137 , Optional ByVal Columns As Variant _
3139 ''' Move a specified range and all next cells in the same rows to the right by inserting empty cells
3140 ''' The inserted cells can span whole columns or be limited to the height of the range
3141 ''' The width of the inserted area is provided by the Columns argument
3142 ''' Nothing happens if the range shift crosses one of the edges of the worksheet
3143 ''' The execution of the method has no effect on the current selection
3144 ''' Args:
3145 ''' Range: the range before which cells have to be inserted, as a string
3146 ''' WholeColumn: when True (default = False), insert whole columns
3147 ''' Columns: the width of the area to insert. Default = the width of the Range argument
3148 ''' Returns:
3149 ''' A string representing the new location of the initial range
3150 ''' Examples:
3151 ''' newrange = oDoc.ShiftRight(
"SheetX.A1:F10
")
' "$SheetX.$G$
1:$L$
10"
3152 ''' newrange = oDoc.ShiftRight(
"SheetX.A1:F10
", Columns :=
3)
' "$SheetX.$D$
1:$I$
10"
3154 Dim sShift As String
' Return value
3155 Dim oSourceAddress As Object
' Alias of Range as _Address
3156 Dim lWidth As Long
' Range width
3157 Dim oShiftAddress As Object
' com.sun.star.table.CellRangeAddress - Range adjusted to the right width
3158 Dim lShiftMode As Long
' One of the com.sun.star.sheet.CellInsertMode enum values
3160 Const cstThisSub =
"SFDocuments.Calc.ShiftRight
"
3161 Const cstSubArgs =
"Range, [WholeColumn=False], [Columns]
"
3163 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
3164 sShift =
""
3167 If IsMissing(WholeColumn) Or IsEmpty(WholeColumn) Then WholeColumn = False
3168 If IsMissing(Columns) Or IsEmpty(Columns) Then Columns =
0
3169 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
3170 If Not _IsStillAlive(True) Then GoTo Finally
3171 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
3172 If Not ScriptForge.SF_Utils._Validate(WholeColumn,
"WholeColumn
", ScriptForge.V_BOOLEAN) Then GoTo Finally
3173 If Not ScriptForge.SF_Utils._Validate(Columns,
"Columns
", ScriptForge.V_NUMERIC) Then GoTo Finally
3177 Set oSourceAddress = _ParseAddress(Range)
3181 ' Manage the width of the area to Shift
3182 ' The insertCells() method inserts a number of columns equal to the width of the cell range to Shift
3184 If Columns
<=
0 Then Columns = lWidth
3185 If _LastCell(.XSpreadsheet)(
0) + Columns
> MAXCOLS Then GoTo Catch
3186 If Columns
<> lWidth Then
3187 Set oShiftAddress = _Offset(oSourceAddress,
0,
0,
0, Columns).XCellRange.RangeAddress
3189 Set oShiftAddress = .XCellRange.RangeAddress
3192 ' Determine the Shift mode
3193 With com.sun.star.sheet.CellInsertMode
3194 If WholeColumn Then lShiftMode = .COLUMNS Else lShiftMode = .RIGHT
3197 ' Move the cells as requested. This modifies .XCellRange
3198 .XSpreadsheet.insertCells(oShiftAddress, lShiftMode)
3200 ' Determine the receiving area
3201 sShift = .XCellRange.AbsoluteName
3207 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
3210 ' When error, return the original range
3211 If Not IsNull(oSourceAddress) Then sShift = oSourceAddress.RangeName
3213 End Function
' SFDocuments.SF_Calc.ShiftRight
3215 REM -----------------------------------------------------------------------------
3216 Public Function ShiftUp(Optional ByVal Range As Variant _
3217 , Optional ByVal WholeRow As Variant _
3218 , Optional ByVal Rows As Variant _
3220 ''' Delete the topmost rows of a specified range and move all cells below upwards
3221 ''' The deleted cells can span whole rows or be limited to the width of the range
3222 ''' The height of the deleted area is provided by the Rows argument
3223 ''' The execution of the method has no effect on the current selection
3224 ''' Args:
3225 ''' Range: the range in which cells have to be erased, as a string
3226 ''' WholeRow: when True (default = False), erase whole rows
3227 ''' Rows: the height of the area to delete.
3228 ''' Default = the height of the Range argument, it is also its maximum value
3229 ''' Returns:
3230 ''' A string representing the location of the remaining part of the initial range,
3231 ''' or the zero-length string if the whole range has been deleted
3232 ''' Examples:
3233 ''' newrange = oDoc.ShiftUp(
"SheetX.G1:L10
")
' ""
3234 ''' newrange = oDoc.ShiftUp(
"SheetX.G1:L10
", Rows :=
3)
' "$SheetX.$G$
1:$I$
10"
3236 Dim sShift As String
' Return value
3237 Dim oSourceAddress As Object
' Alias of Range as _Address
3238 Dim lHeight As Long
' Range height
3239 Dim oShiftAddress As Object
' com.sun.star.table.CellRangeAddress - Range adjusted to the right height
3240 Dim lShiftMode As Long
' One of the com.sun.star.sheet.CellDeleteMode enum values
3242 Const cstThisSub =
"SFDocuments.Calc.ShiftUp
"
3243 Const cstSubArgs =
"Range, [WholeRow=False], [Rows]
"
3245 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
3246 sShift =
""
3249 If IsMissing(WholeRow) Or IsEmpty(WholeRow) Then WholeRow = False
3250 If IsMissing(Rows) Or IsEmpty(Rows) Then Rows =
0
3251 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
3252 If Not _IsStillAlive(True) Then GoTo Finally
3253 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
3254 If Not ScriptForge.SF_Utils._Validate(WholeRow,
"WholeRow
", ScriptForge.V_BOOLEAN) Then GoTo Finally
3255 If Not ScriptForge.SF_Utils._Validate(Rows,
"Rows
", ScriptForge.V_NUMERIC) Then GoTo Finally
3259 Set oSourceAddress = _ParseAddress(Range)
3260 Set _LastParsedAddress = Nothing
' Range will be erased. Force re-parsing next time
3264 ' Manage the height of the area to delete
3265 ' The removeRange() method erases a number of rows equal to the height of the cell range to delete
3267 If Rows
<=
0 Then Rows = lHeight
3268 If Rows
< lHeight Then
3269 Set oShiftAddress = _Offset(oSourceAddress,
0,
0, Rows,
0).XCellRange.RangeAddress
3270 Else
' Rows is capped at the range height
3271 Set oShiftAddress = .XCellRange.RangeAddress
3274 ' Determine the Delete mode
3275 With com.sun.star.sheet.CellDeleteMode
3276 If WholeRow Then lShiftMode = .ROWS Else lShiftMode = .UP
3279 ' Move the cells as requested. This modifies .XCellRange
3280 .XSpreadsheet.removeRange(oShiftAddress, lShiftMode)
3282 ' Determine the remaining area
3283 If Rows
< lHeight Then sShift = .XCellRange.AbsoluteName
3289 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
3292 ' When error, return the original range
3293 If Not IsNull(oSourceAddress) Then sShift = oSourceAddress.RangeName
3295 End Function
' SFDocuments.SF_Calc.ShiftUp
3297 REM -----------------------------------------------------------------------------
3298 Public Function SortRange(Optional ByVal Range As Variant _
3299 , Optional ByVal SortKeys As Variant _
3300 , Optional ByVal SortOrder As Variant _
3301 , Optional ByVal DestinationCell As Variant _
3302 , Optional ByVal ContainsHeader As Variant _
3303 , Optional ByVal CaseSensitive As Variant _
3304 , Optional ByVal SortColumns As Variant _
3306 ''' Sort the given range on maximum
3 columns/rows. The sorting order may vary by column/row
3307 ''' Args:
3308 ''' Range: the range to sort as a string
3309 ''' SortKeys: a scalar (if
1 column/row) or an array of column/row numbers starting from
1
3310 ''' SortOrder: a scalar or an array of strings:
"ASC
" or
"DESC
"
3311 ''' Each item is paired with the corresponding item in SortKeys
3312 ''' If the SortOrder array is shorter than SortKeys, the remaining keys are sorted
3313 ''' in ascending order
3314 ''' DestinationCell: the destination of the sorted range of cells, as a string
3315 ''' If given as range, the destination will be reduced to its top-left cell
3316 ''' By default, Range is overwritten with its sorted content
3317 ''' ContainsHeader: when True, the first row/column is not sorted. Default = False
3318 ''' CaseSensitive: only for string comparisons, default = False
3319 ''' SortColumns: when True, the columns are sorted from left to right
3320 ''' Default = False: rows are sorted from top to bottom.
3321 ''' Returns:
3322 ''' The modified range of cells as a string
3323 ''' Example:
3324 ''' oDoc.SortRange(
"A2:J200
", Array(
1,
3), , Array(
"ASC
",
"DESC
"), CaseSensitive := True)
3325 ''' ' Sort on columns A (ascending) and C (descending)
3327 Dim sSort As String
' Return value
3328 Dim oRangeAddress As _Address
' Parsed range
3329 Dim oRange As Object
' com.sun.star.table.XCellRange
3330 Dim oDestRange As Object
' Destination as a range
3331 Dim oDestAddress As Object
' com.sun.star.table.CellRangeAddress
3332 Dim oDestCell As Object
' com.sun.star.table.CellAddress
3333 Dim vSortDescriptor As Variant
' Array of com.sun.star.beans.PropertyValue
3334 Dim vSortFields As Variant
' Array of com.sun.star.table.TableSortField
3335 Dim sOrder As String
' Item in SortOrder
3337 Const cstThisSub =
"SFDocuments.Calc.SortRange
"
3338 Const cstSubArgs =
"Range, SortKeys, [TargetRange=
""""], [SortOrder=
""ASC
""], [DestinationCell=
""""], [ContainsHeader=False], [CaseSensitive=False], [SortColumns=False]
"
3340 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
3341 sSort =
""
3344 If IsMissing(SortKeys) Or IsEmpty(SortKeys) Then
3346 ElseIf Not IsArray(SortKeys) Then
3347 SortKeys = Array(SortKeys)
3349 If IsMissing(DestinationCell) Or IsEmpty(DestinationCell) Then DestinationCell =
""
3350 If IsMissing(SortOrder) Or IsEmpty(SortOrder) Then
3351 SortOrder = Array(
"ASC
")
3352 ElseIf Not IsArray(SortOrder) Then
3353 SortOrder = Array(SortOrder)
3355 If IsMissing(ContainsHeader) Or IsEmpty(ContainsHeader) Then ContainsHeader = False
3356 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
3357 If IsMissing(SortColumns) Or IsEmpty(SortColumns) Then SortColumns = False
3358 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
3359 If Not _IsStillAlive() Then GoTo Finally
3360 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
3361 If Not ScriptForge.SF_Utils._ValidateArray(SortKeys,
"SortKeys
",
1, V_NUMERIC, True) Then GoTo Finally
3362 If Not ScriptForge.SF_Utils._Validate(DestinationCell,
"DestinationCell
", V_STRING) Then GoTo Finally
3363 If Not ScriptForge.SF_Utils._ValidateArray(SortOrder,
"SortOrder
",
1, V_STRING, True) Then GoTo Finally
3364 If Not ScriptForge.SF_Utils._Validate(ContainsHeader,
"ContainsHeader
", ScriptForge.V_BOOLEAN) Then GoTo Finally
3365 If Not ScriptForge.SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", ScriptForge.V_BOOLEAN) Then GoTo Finally
3366 If Not ScriptForge.SF_Utils._Validate(SortColumns,
"SortColumns
", ScriptForge.V_BOOLEAN) Then GoTo Finally
3368 Set oRangeAddress = _ParseAddress(Range)
3369 If Len(DestinationCell)
> 0 Then Set oDestRange = _ParseAddress(DestinationCell)
3372 ' Initialize the sort descriptor
3373 Set oRange = oRangeAddress.XCellRange
3374 vSortDescriptor = oRange.createSortDescriptor
3375 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"IsSortColumns
", SortColumns)
3376 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"ContainsHeader
", ContainsHeader)
3377 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"BindFormatsToContent
", True)
3378 If Len(DestinationCell) =
0 Then
3379 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"CopyOutputData
", False)
3381 Set oDestAddress = oDestRange.XCellRange.RangeAddress
3382 Set oDestCell = New com.sun.star.table.CellAddress
3384 oDestCell.Sheet = .Sheet
3385 oDestCell.Column = .StartColumn
3386 oDestCell.Row = .StartRow
3388 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"CopyOutputData
", True)
3389 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"OutputPosition
", oDestCell)
3391 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"IsUserListEnabled
", False)
3393 ' Define the sorting keys
3394 vSortFields = Array()
3395 ReDim vSortFields(
0 To UBound(SortKeys))
3396 For i =
0 To UBound(SortKeys)
3397 vSortFields(i) = New com.sun.star.table.TableSortField
3398 If i
> UBound(SortOrder) Then sOrder =
"" Else sOrder = SortOrder(i)
3399 If Len(sOrder) =
0 Then sOrder =
"ASC
"
3401 .Field = SortKeys(i) -
1
3402 .IsAscending = ( UCase(sOrder) =
"ASC
" )
3403 .IsCaseSensitive = CaseSensitive
3407 ' Associate the keys and the descriptor, and sort
3408 vSortDescriptor = ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor,
"SortFields
", vSortFields)
3409 oRange.sort(vSortDescriptor)
3411 ' Compute the changed area
3412 If Len(DestinationCell) =
0 Then
3413 sSort = oRangeAddress.RangeName
3416 sSort = _Offset(oDestRange,
0,
0, .Height, .Width).RangeName
3422 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
3426 End Function
' SFDocuments.SF_Calc.SortRange
3428 REM ======================================================= SUPERCLASS PROPERTIES
3430 REM -----------------------------------------------------------------------------
3431 Property Get CustomProperties() As Variant
3432 CustomProperties = [_Super].GetProperty(
"CustomProperties
")
3433 End Property
' SFDocuments.SF_Calc.CustomProperties
3435 REM -----------------------------------------------------------------------------
3436 Property Let CustomProperties(Optional ByVal pvCustomProperties As Variant)
3437 [_Super].CustomProperties = pvCustomProperties
3438 End Property
' SFDocuments.SF_Calc.CustomProperties
3440 REM -----------------------------------------------------------------------------
3441 Property Get Description() As Variant
3442 Description = [_Super].GetProperty(
"Description
")
3443 End Property
' SFDocuments.SF_Calc.Description
3445 REM -----------------------------------------------------------------------------
3446 Property Let Description(Optional ByVal pvDescription As Variant)
3447 [_Super].Description = pvDescription
3448 End Property
' SFDocuments.SF_Calc.Description
3450 REM -----------------------------------------------------------------------------
3451 Property Get DocumentProperties() As Variant
3452 DocumentProperties = [_Super].GetProperty(
"DocumentProperties
")
3453 End Property
' SFDocuments.SF_Calc.DocumentProperties
3455 REM -----------------------------------------------------------------------------
3456 Property Get DocumentType() As String
3457 DocumentType = [_Super].GetProperty(
"DocumentType
")
3458 End Property
' SFDocuments.SF_Calc.DocumentType
3460 REM -----------------------------------------------------------------------------
3461 Property Get ExportFilters() As Variant
3462 ExportFilters = [_Super].GetProperty(
"ExportFilters
")
3463 End Property
' SFDocuments.SF_Calc.ExportFilters
3465 REM -----------------------------------------------------------------------------
3466 Property Get ImportFilters() As Variant
3467 ImportFilters = [_Super].GetProperty(
"ImportFilters
")
3468 End Property
' SFDocuments.SF_Calc.ImportFilters
3470 REM -----------------------------------------------------------------------------
3471 Property Get IsBase() As Boolean
3472 IsBase = [_Super].GetProperty(
"IsBase
")
3473 End Property
' SFDocuments.SF_Calc.IsBase
3475 REM -----------------------------------------------------------------------------
3476 Property Get IsCalc() As Boolean
3477 IsCalc = [_Super].GetProperty(
"IsCalc
")
3478 End Property
' SFDocuments.SF_Calc.IsCalc
3480 REM -----------------------------------------------------------------------------
3481 Property Get IsDraw() As Boolean
3482 IsDraw = [_Super].GetProperty(
"IsDraw
")
3483 End Property
' SFDocuments.SF_Calc.IsDraw
3485 REM -----------------------------------------------------------------------------
3486 Property Get IsImpress() As Boolean
3487 IsImpress = [_Super].GetProperty(
"IsImpress
")
3488 End Property
' SFDocuments.SF_Calc.IsImpress
3490 REM -----------------------------------------------------------------------------
3491 Property Get IsMath() As Boolean
3492 IsMath = [_Super].GetProperty(
"IsMath
")
3493 End Property
' SFDocuments.SF_Calc.IsMath
3495 REM -----------------------------------------------------------------------------
3496 Property Get IsWriter() As Boolean
3497 IsWriter = [_Super].GetProperty(
"IsWriter
")
3498 End Property
' SFDocuments.SF_Calc.IsWriter
3500 REM -----------------------------------------------------------------------------
3501 Property Get Keywords() As Variant
3502 Keywords = [_Super].GetProperty(
"Keywords
")
3503 End Property
' SFDocuments.SF_Calc.Keywords
3505 REM -----------------------------------------------------------------------------
3506 Property Let Keywords(Optional ByVal pvKeywords As Variant)
3507 [_Super].Keywords = pvKeywords
3508 End Property
' SFDocuments.SF_Calc.Keywords
3510 REM -----------------------------------------------------------------------------
3511 Property Get Readonly() As Variant
3512 Readonly = [_Super].GetProperty(
"Readonly
")
3513 End Property
' SFDocuments.SF_Calc.Readonly
3515 REM -----------------------------------------------------------------------------
3516 Property Get Subject() As Variant
3517 Subject = [_Super].GetProperty(
"Subject
")
3518 End Property
' SFDocuments.SF_Calc.Subject
3520 REM -----------------------------------------------------------------------------
3521 Property Let Subject(Optional ByVal pvSubject As Variant)
3522 [_Super].Subject = pvSubject
3523 End Property
' SFDocuments.SF_Calc.Subject
3525 REM -----------------------------------------------------------------------------
3526 Property Get Title() As Variant
3527 Title = [_Super].GetProperty(
"Title
")
3528 End Property
' SFDocuments.SF_Calc.Title
3530 REM -----------------------------------------------------------------------------
3531 Property Let Title(Optional ByVal pvTitle As Variant)
3532 [_Super].Title = pvTitle
3533 End Property
' SFDocuments.SF_Calc.Title
3535 REM -----------------------------------------------------------------------------
3536 Property Get XComponent() As Variant
3537 XComponent = [_Super].GetProperty(
"XComponent
")
3538 End Property
' SFDocuments.SF_Calc.XComponent
3540 REM ========================================================== SUPERCLASS METHODS
3542 REM -----------------------------------------------------------------------------
3543 'Public Function Activate() As Boolean
3544 ' Activate = [_Super].Activate()
3545 'End Function
' SFDocuments.SF_Calc.Activate
3547 REM -----------------------------------------------------------------------------
3548 Public Function CloseDocument(Optional ByVal SaveAsk As Variant) As Boolean
3549 CloseDocument = [_Super].CloseDocument(SaveAsk)
3550 End Function
' SFDocuments.SF_Calc.CloseDocument
3552 REM -----------------------------------------------------------------------------
3553 Public Function CreateMenu(Optional ByVal MenuHeader As Variant _
3554 , Optional ByVal Before As Variant _
3555 , Optional ByVal SubmenuChar As Variant _
3557 Set CreateMenu = [_Super].CreateMenu(MenuHeader, Before, SubmenuChar)
3558 End Function
' SFDocuments.SF_Calc.CreateMenu
3560 REM -----------------------------------------------------------------------------
3561 Public Function ExportAsPDF(Optional ByVal FileName As Variant _
3562 , Optional ByVal Overwrite As Variant _
3563 , Optional ByVal Pages As Variant _
3564 , Optional ByVal Password As Variant _
3565 , Optional ByVal Watermark As Variant _
3567 ExportAsPDF = [_Super].ExportAsPDF(FileName, Overwrite, Pages, Password, Watermark)
3568 End Function
' SFDocuments.SF_Calc.ExportAsPDF
3570 REM -----------------------------------------------------------------------------
3571 Public Function RemoveMenu(Optional ByVal MenuHeader As Variant) As Boolean
3572 RemoveMenu = [_Super].RemoveMenu(MenuHeader)
3573 End Function
' SFDocuments.SF_Calc.RemoveMenu
3575 REM -----------------------------------------------------------------------------
3576 Public Sub RunCommand(Optional ByVal Command As Variant _
3577 , ParamArray Args As Variant _
3579 [_Super].RunCommand(Command, Args)
3580 End Sub
' SFDocuments.SF_Calc.RunCommand
3582 REM -----------------------------------------------------------------------------
3583 Public Function Save() As Boolean
3584 Save = [_Super].Save()
3585 End Function
' SFDocuments.SF_Calc.Save
3587 REM -----------------------------------------------------------------------------
3588 Public Function SaveAs(Optional ByVal FileName As Variant _
3589 , Optional ByVal Overwrite As Variant _
3590 , Optional ByVal Password As Variant _
3591 , Optional ByVal FilterName As Variant _
3592 , Optional ByVal FilterOptions As Variant _
3594 SaveAs = [_Super].SaveAs(FileName, Overwrite, Password, FilterName, FilterOptions)
3595 End Function
' SFDocuments.SF_Calc.SaveAs
3597 REM -----------------------------------------------------------------------------
3598 Public Function SaveCopyAs(Optional ByVal FileName As Variant _
3599 , Optional ByVal Overwrite As Variant _
3600 , Optional ByVal Password As Variant _
3601 , Optional ByVal FilterName As Variant _
3602 , Optional ByVal FilterOptions As Variant _
3604 SaveCopyAs = [_Super].SaveCopyAs(FileName, Overwrite, Password, FilterName, FilterOptions)
3605 End Function
' SFDocuments.SF_Calc.SaveCopyAs
3607 REM -----------------------------------------------------------------------------
3608 Public Function SetPrinter(Optional ByVal Printer As Variant _
3609 , Optional ByVal Orientation As Variant _
3610 , Optional ByVal PaperFormat As Variant _
3612 SetPrinter = [_Super].SetPrinter(Printer, Orientation, PaperFormat)
3613 End Function
' SFDocuments.SF_Calc.SetPrinter
3615 REM =========================================================== PRIVATE FUNCTIONS
3617 REM -----------------------------------------------------------------------------
3618 Private Sub _ClearRange(ByVal psTarget As String _
3619 , Optional ByVal Range As Variant _
3620 , Optional FilterFormula As Variant _
3621 , Optional FilterScope As Variant _
3623 ''' Clear the given range with the given options
3624 ''' The range may be filtered by a formula for a selective clearance
3625 ''' Arguments checking is done in this Sub, not in the calling one
3626 ''' Args:
3627 ''' psTarget:
"All
",
"Formats
" or
"Values
"
3628 ''' Range: the range to clear as a string
3629 ''' FilterFormula: a selection of cells based on a Calc formula
3630 ''' When left empty, all the cells of the range are cleared
3631 ''' psFilterScope:
"CELL
",
"ROW
" or
"COLUMN
"
3633 Dim lClear As Long
' A combination of com.sun.star.sheet.CellFlags
3634 Dim oRange As Object
' Alias of Range
3635 Dim vRanges() As Variant
' Array of subranges resulting from the application of the filter
3638 Dim cstThisSub As String : cstThisSub =
"SFDocuments.Calc.Clear
" & psTarget
3639 Const cstSubArgs =
"Range, [FilterFormula=
""], [FilterScope=
""CELL
""|
""ROW
""|
""COLUMN
""]
"
3641 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
3644 If IsMissing(FilterFormula) Or IsEmpty(FilterFormula) Then FilterFormula =
""
3645 If IsMissing(FilterScope) Or IsEmpty(FilterScope) Then FilterScope =
"CELL
"
3646 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
3647 If Not _IsStillAlive() Then GoTo Finally
3648 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
3649 If Not ScriptForge.SF_Utils._Validate(FilterFormula,
"FilterFormula
", V_STRING) Then GoTo Finally
3650 If Len(FilterFormula)
> 0 Then
3651 If Not ScriptForge.SF_Utils._Validate(FilterScope,
"FilterScope
", V_STRING, Array(
"CELL
",
"ROW
",
"COLUMN
")) Then GoTo Finally
3653 If Not ScriptForge.SF_Utils._Validate(FilterScope,
"FilterScope
", V_STRING) Then GoTo Finally
3658 With com.sun.star.sheet.CellFlags
3659 Select Case psTarget
3660 Case
"All
"
3661 lClear = .VALUE + .DATETIME + .STRING + .ANNOTATION + .FORMULA _
3662 + .HARDATTR + .STYLES + .OBJECTS + .EDITATTR + .FORMATTED
3663 Case
"Formats
"
3664 lClear = .HARDATTR + .STYLES + .EDITATTR + .FORMATTED
3665 Case
"Values
"
3666 lClear = .VALUE + .DATETIME + .STRING + .FORMULA
3670 If VarType(Range) = V_STRING Then Set oRange = _ParseAddress(Range) Else Set oRange = Range
3672 ' Without filter, the whole range is cleared
3673 ' Otherwise the filter cuts the range in subranges and clears them one by one
3674 If Len(FilterFormula) =
0 Then
3675 oRange.XCellRange.clearContents(lClear)
3677 vRanges() = _ComputeFilter(oRange, FilterFormula, UCase(FilterScope))
3678 For i =
0 To UBound(vRanges)
3679 vRanges(i).XCellRange.clearContents(lClear)
3684 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
3688 End Sub
' SFDocuments.SF_Calc._ClearRange
3690 REM -----------------------------------------------------------------------------
3691 Private Function _ComputeFilter(ByRef poRange As Object _
3692 , ByVal psFilterFormula As String _
3693 , ByVal psFilterScope As String _
3695 ''' Compute in the given range the cells, rows or columns for which
3696 ''' the given formula returns TRUE
3697 ''' Args:
3698 ''' poRange: the range on which to compute the filter as an _Address type
3699 ''' psFilterFormula: the formula to be applied on each row, column or cell
3700 ''' psFilterSCope:
"ROW
",
"COLUMN
" or
"CELL
"
3701 ''' Returns:
3702 ''' An array of ranges as objects of type _Address
3704 Dim vRanges As Variant
' Return value
3705 Dim oRange As Object
' A single vRanges() item
3706 Dim lLast As Long
' Last used row or column number in the sheet containing Range
3707 Dim oFormulaRange As _Address
' Range where the FilterFormula must be stored
3708 Dim sFormulaDirection As String
' Either V(ertical), H(orizontal) or B(oth)
3709 Dim vDataArray As Variant
' DataArray compatible with .DataArray UNO property
3710 Dim vFilter As Variant
' Array of Boolean values indicating which rows should be erased
3711 Dim bFilter As Boolean
' A single item in vFilter
3712 Dim iDims As Integer
' Number of dimensions of vFilter()
3713 Dim lLower As Long
' Lower level of contiguous True filter values
3714 Dim lUpper As Long
' Upper level of contiguous True filter values
3715 Dim i As Long, j As Long
3718 ' Error handling is determined by the calling method
3724 ' Compute the range where to apply the formula
3725 ' Determine the direction of the range containing the formula vertical, horizontal or both
3726 Select Case psFilterScope
3727 Case
"ROW
"
3728 lLast = LastColumn(.SheetName)
3729 ' Put formulas as a single column in the unused area at the right of the range to filter
3730 Set oFormulaRange = _Offset(poRange,
0, lLast - .XCellRange.RangeAddress.StartColumn +
1,
0,
1)
3731 sFormulaDirection =
"V
"
3732 Case
"COLUMN
"
3733 lLast = LastRow(.SheetName)
3734 ' Put formulas as a single row in the unused area at the bottom of the range to filter
3735 Set oFormulaRange = _Offset(poRange, lLast - .XCellRange.RangeAddress.StartRow +
1,
0,
1,
0)
3736 sFormulaDirection =
"H
"
3737 Case
"CELL
"
3738 lLast = LastRow(.SheetName)
3739 ' Put formulas as a matrix in the unused area at the bottom of the range to filter
3740 Set oFormulaRange = _Offset(poRange, lLast - .XCellRange.RangeAddress.StartRow +
1,
0,
0,
0)
3741 sFormulaDirection =
"B
"
3742 If oFormulaRange.Width =
1 Then
3743 sFormulaDirection =
"V
"
3744 ElseIf oFormulaRange.Height =
1 Then
3745 sFormulaDirection =
"H
"
3749 ' Apply the formula and get the result as an array of Boolean values. Clean up
3750 SetFormula(oFormulaRange, psFilterFormula)
3751 vDataArray = oFormulaRange.XCellRange.getDataArray()
3752 vFilter = _ConvertFromDataArray(vDataArray)
3753 iDims = ScriptForge.SF_Array.CountDims(vFilter)
3754 ClearAll(oFormulaRange)
3756 ' Convert the filter values (
0 = False,
1 = True) to a set of ranges
3758 Case -
1 ' Scalar
3759 If vFilter =
1 Then vRanges = ScriptForge.SF_Array.Append(vRanges, poRange)
3760 Case
0 ' Empty array
3761 ' Nothing to do
3762 Case
1,
2 ' Vector or Array
3763 ' Strategy: group contiguous applicable rows/columns to optimize heavy operations like CompactUp, CompactLeft
3764 ' Stack the contiguous ranges of True values in vRanges()
3766 ' To manage vector and array with same code, setup a single fictitious loop when vector, otherwise scan array by row
3767 For i =
0 To Iif(iDims =
1,
0, UBound(vFilter,
1))
3768 lLower = -
1 : lUpper = -
1
3770 For j =
0 To UBound(vFilter, iDims)
3771 If iDims =
1 Then bFilter = CBool(vFilter(j)) Else bFilter = CBool(vFilter(i, j))
3772 If j = UBound(vFilter, iDims) And bFilter Then
' Don
't forget the last item
3773 If lLower
< 0 Then lLower = j
3775 ElseIf Not bFilter Then
3776 If lLower
>=
0 Then lUpper = j -
1
3778 If lLower
< 0 Then lLower = j
3780 ' Determine the next applicable range when one found and limit reached
3781 If lUpper
> -
1 Then
3782 If sFormulaDirection =
"V
" Then
' ROW
3783 Set oRange = _Offset(poRange, lLower,
0, lUpper - lLower +
1,
0)
3784 ElseIf sFormulaDirection =
"H
" Then
' COLUMN
3785 Set oRange = _Offset(poRange,
0, lLower,
0, lUpper - lLower +
1)
3787 Set oRange = _Offset(poRange, i, lLower,
1, lUpper - lLower +
1)
3789 If Not IsNull(oRange) Then vRanges = ScriptForge.SF_Array.Append(vRanges, oRange)
3790 lLower = -
1 : lUpper = -
1
3796 ' Should not happen
3802 _ComputeFilter = vRanges()
3804 End Function
' SFDocuments.SF_Calc._ComputeFilter
3806 REM -----------------------------------------------------------------------------
3807 Public Function _ConvertFromDataArray(ByRef pvDataArray As Variant) As Variant
3808 ''' Convert a data array to a scalar, a vector or a
2D array
3809 ''' Args:
3810 ''' pvDataArray: an array as returned by the XCellRange.getDataArray or .getFormulaArray methods
3811 ''' Returns:
3812 ''' A scalar, a zero-based
1D array or a zero-based
2D array of strings and/or doubles
3813 ''' To convert doubles to dates, use the CDate builtin function
3815 Dim vArray As Variant
' Return value
3816 Dim lMax1 As Long
' UBound of pvDataArray
3817 Dim lMax2 As Long
' UBound of pvDataArray items
3824 ' Convert the data array to scalar, vector or array
3825 lMax1 = UBound(pvDataArray)
3826 If lMax1
>=
0 Then
3827 lMax2 = UBound(pvDataArray(
0))
3828 If lMax2
>=
0 Then
3829 If lMax1 + lMax2
> 0 Then vArray = Array()
3831 Case lMax1 =
0 And lMax2 =
0 ' Scalar
3832 vArray = pvDataArray(
0)(
0)
3833 Case lMax1
> 0 And lMax2 =
0 ' Vertical vector
3834 ReDim vArray(
0 To lMax1)
3836 vArray(i) = pvDataArray(i)(
0)
3838 Case lMax1 =
0 And lMax2
> 0 ' Horizontal vector
3839 ReDim vArray(
0 To lMax2)
3841 vArray(j) = pvDataArray(
0)(j)
3843 Case Else
' Array
3844 ReDim vArray(
0 To lMax1,
0 To lMax2)
3847 vArray(i, j) = pvDataArray(i)(j)
3855 _ConvertFromDataArray = vArray
3856 End Function
' SFDocuments.SF_Calc._ConvertFromDataArray
3858 REM -----------------------------------------------------------------------------
3859 Private Function _ConvertToCellValue(ByVal pvItem As Variant) As Variant
3860 ''' Convert the argument to a valid Calc cell content
3862 Dim vCell As Variant
' Return value
3865 Select Case ScriptForge.SF_Utils._VarTypeExt(pvItem)
3866 Case V_STRING : vCell = pvItem
3867 Case V_DATE : vCell = CDbl(pvItem)
3868 Case ScriptForge.V_NUMERIC : vCell = CDbl(pvItem)
3869 Case ScriptForge.V_BOOLEAN : vCell = CDbl(Iif(pvItem,
1,
0))
3870 Case Else : vCell =
""
3874 _ConvertToCellValue = vCell
3876 End Function
' SFDocuments.SF_Calc._ConvertToCellValue
3878 REM -----------------------------------------------------------------------------
3879 Private Function _ConvertToDataArray(ByRef pvArray As Variant _
3880 , Optional ByVal plRows As Long _
3881 , Optional ByVal plColumns As Long _
3883 ''' Create a
2-dimensions nested array (compatible with the ranges .DataArray property)
3884 ''' from a scalar, a
1D array or a
2D array
3885 ''' Input may be a
1D array of arrays, typically when call issued by a Python script
3886 ''' Array items are converted to (possibly empty) strings or doubles
3887 ''' Args:
3888 ''' pvArray: the input scalar or array. If array, must be
1 or
2D otherwise it is ignored.
3889 ''' plRows, plColumns: the upper bounds of the data array
3890 ''' If bigger than input array, fill with zero-length strings
3891 ''' If smaller than input array, truncate
3892 ''' If plRows =
0 and the input array is a vector, the data array is aligned horizontally
3893 ''' They are either both present or both absent
3894 ''' When absent
3895 ''' The size of the output is fully determined by the input array
3896 ''' Vectors are aligned vertically
3897 ''' Returns:
3898 ''' A data array compatible with ranges .DataArray property
3899 ''' The output is always an array of nested arrays
3901 Dim vDataArray() As Variant
' Return value
3902 Dim vVector() As Variant
' A temporary
1D array
3903 Dim vItem As Variant
' A single input item
3904 Dim iDims As Integer
' Number of dimensions of the input argument
3905 Dim lMin1 As Long
' Lower bound (
1) of input array
3906 Dim lMax1 As Long
' Upper bound (
1)
3907 Dim lMin2 As Long
' Lower bound (
2)
3908 Dim lMax2 As Long
' Upper bound (
2)
3909 Dim lRows As Long
' Upper bound of vDataArray
3910 Dim lCols As Long
' Upper bound of vVector
3911 Dim bHorizontal As Boolean
' Horizontal vector
3912 Dim bDataArray As Boolean
' Input array is already an array of arrays
3916 Const cstEmpty =
"" ' Empty cell
3918 If IsMissing(plRows) Or IsEmpty(plRows) Then plRows = -
1
3919 If IsMissing(plColumns) Or IsEmpty(plColumns) Then plColumns = -
1
3921 vDataArray = Array()
3924 ' Check the input argument and know its boundaries
3925 iDims = ScriptForge.SF_Array.CountDims(pvArray)
3926 If iDims =
0 Or iDims
> 2 Then Exit Function
3927 lMin1 =
0 : lMax1 =
0 ' Default values
3928 lMin2 =
0 : lMax2 =
0
3930 Case -
1 ' Scalar value
3932 bHorizontal = ( plRows =
0 And plColumns
> 0 )
3933 bDataArray = IsArray(pvArray(
0))
3934 If Not bDataArray Then
3935 If Not bHorizontal Then
3936 lMin1 = LBound(pvArray) : lMax1 = UBound(pvArray)
3938 lMin2 = LBound(pvArray) : lMax2 = UBound(pvArray)
3942 lMin1 = LBound(pvArray) : lMax1 = UBound(pvArray)
3943 lMin2 = LBound(pvArray(
0)) : lMax2 = UBound(pvArray(
0))
3946 lMin1 = LBound(pvArray,
1) : lMax1 = UBound(pvArray,
1)
3947 lMin2 = LBound(pvArray,
2) : lMax2 = UBound(pvArray,
2)
3950 ' Set the output dimensions accordingly
3951 If plRows
>=
0 Then
' Dimensions of output are imposed
3954 Else
' Dimensions of output determined by input argument
3955 lRows =
0 : lCols =
0 ' Default values
3957 Case -
1 ' Scalar value
3958 Case
1 ' Vectors are aligned vertically
3959 lRows = lMax1 - lMin1
3961 lRows = lMax1 - lMin1
3962 lCols = lMax2 - lMin2
3965 ReDim vDataArray(
0 To lRows)
3967 ' Feed the output array row by row, each row being a vector
3969 ReDim vVector(
0 To lCols)
3971 If i
> lMax1 - lMin1 Then
3972 vVector(j) = cstEmpty
3973 ElseIf j
> lMax2 - lMin2 Then
3974 vVector(j) = cstEmpty
3977 Case -
1 : vItem = _ConvertToCellValue(pvArray)
3980 vItem = _ConvertToCellValue(pvArray(j + lMin2))
3982 vItem = _ConvertToCellValue(pvArray(i + lMin1))
3986 vItem = _ConvertToCellValue(pvArray(i + lMin1)(j + lMin2))
3988 vItem = _ConvertToCellValue(pvArray(i + lMin1, j + lMin2))
3993 vDataArray(i) = vVector
3998 _ConvertToDataArray = vDataArray
4000 End Function
' SFDocuments.SF_Calc._ConvertToDataArray
4002 REM -----------------------------------------------------------------------------
4003 Private Function _DFunction(ByVal psFunction As String _
4004 , Optional ByVal Range As Variant _
4006 ''' Apply the given function on all the numeric values stored in the given range
4007 ''' Args:
4008 ''' Range : the range as a string where to apply the function on
4009 ''' Returns:
4010 ''' The resulting value as a double
4012 Dim dblGet As Double
' Return value
4013 Dim oAddress As Object
' Alias of Range
4014 Dim vFunction As Variant
' com.sun.star.sheet.GeneralFunction.XXX
4015 Dim cstThisSub As String : cstThisSub =
"SFDocuments.Calc.
" & psFunction
4016 Const cstSubArgs =
"Range
"
4018 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
4022 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
4023 If Not _IsStillAlive() Then GoTo Finally
4024 If Not ScriptForge.SF_Utils._Validate(Range,
"Range
", V_STRING) Then GoTo Finally
4029 Set oAddress = _ParseAddress(Range)
4030 Select Case psFunction
4031 Case
"DAvg
" : vFunction = com.sun.star.sheet.GeneralFunction.AVERAGE
4032 Case
"DCount
" : vFunction = com.sun.star.sheet.GeneralFunction.COUNTNUMS
4033 Case
"DMax
" : vFunction = com.sun.star.sheet.GeneralFunction.MAX
4034 Case
"DMin
" : vFunction = com.sun.star.sheet.GeneralFunction.MIN
4035 Case
"DSum
" : vFunction = com.sun.star.sheet.GeneralFunction.SUM
4036 Case Else : GoTo Finally
4038 dblGet = oAddress.XCellRange.computeFunction(vFunction)
4042 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
4046 End Function
' SFDocuments.SF_Calc._DFunction
4048 REM -----------------------------------------------------------------------------
4049 Private Function _FileIdent() As String
4050 ''' Returns a file identification from the information that is currently available
4051 ''' Useful e.g. for display in error messages
4053 _FileIdent = [_Super]._FileIdent()
4055 End Function
' SFDocuments.SF_Calc._FileIdent
4057 REM -----------------------------------------------------------------------------
4058 Function _GetColumnName(ByVal plColumnNumber As Long) As String
4059 ''' Convert a column number (range
1,
2,.
.16384) into its letter counterpart (range
'A
',
'B
',..
'XFD
').
4060 ''' Args:
4061 ''' ColumnNumber: the column number, must be in the interval
1 ...
16384
4062 ''' Returns:
4063 ''' a string representation of the column name, in range
'A
'..
'XFD
'
4064 ''' Adapted from a Python function by sundar nataraj
4065 ''' http://stackoverflow.com/questions/
23861680/convert-spreadsheet-number-to-column-letter
4067 Dim sCol As String
' Return value
4068 Dim lDiv As Long
' Intermediate result
4069 Dim lMod As Long
' Result of modulo
26 operation
4073 lDiv = plColumnNumber
4074 Do While lDiv
> 0
4075 lMod = (lDiv -
1) Mod
26
4076 sCol = Chr(
65 + lMod)
& sCol
4077 lDiv = (lDiv - lMod) \
26
4081 _GetColumnName = sCol
4082 End Function
' SFDocuments.SF_Calc._GetColumnName
4084 REM -----------------------------------------------------------------------------
4085 Private Function _IsStillAlive(Optional ByVal pbForUpdate As Boolean _
4086 , Optional ByVal pbError As Boolean _
4088 ''' Returns True if the document has not been closed manually or incidentally since the last use
4089 ''' If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
4090 ''' Args:
4091 ''' pbForUpdate: if True (default = False), check additionally if document is open for editing
4092 ''' pbError: if True (default), raise a fatal error
4094 Dim bAlive As Boolean
' Return value
4096 If IsMissing(pbForUpdate) Then pbForUpdate = False
4097 If IsMissing(pbError) Then pbError = True
4100 bAlive = [_Super]._IsStillAlive(pbForUpdate, pbError)
4103 _IsStillAlive = bAlive
4105 End Function
' SFDocuments.SF_Calc._IsStillAlive
4107 REM -----------------------------------------------------------------------------
4108 Private Function _LastCell(ByRef poSheet As Object) As Variant
4109 ''' Returns in an array the coordinates of the last used cell in the given sheet
4111 Dim oCursor As Object
' Cursor on the cell
4112 Dim oRange As Object
' The used range
4113 Dim vCoordinates(
0 To
1) As Long
' Return value: (
0) = Column, (
1) = Row
4116 Set oCursor = poSheet.createCursorByRange(poSheet.getCellRangeByName(
"A1
"))
4117 oCursor.gotoEndOfUsedArea(True)
4118 Set oRange = poSheet.getCellRangeByName(oCursor.AbsoluteName)
4120 vCoordinates(
0) = oRange.RangeAddress.EndColumn +
1
4121 vCoordinates(
1) = oRange.RangeAddress.EndRow +
1
4124 _LastCell = vCoordinates
4125 End Function
' SFDocuments.SF_Calc._LastCell
4127 REM -----------------------------------------------------------------------------
4128 Public Function _Offset(ByRef pvRange As Variant _
4129 , ByVal plRows As Long _
4130 , ByVal plColumns As Long _
4131 , ByVal plHeight As Long _
4132 , ByVal plWidth As Long _
4134 ''' Returns a new range offset by a certain number of rows and columns from a given range
4135 ''' Args:
4136 ''' pvRange : the range, as a string or an object, from which the function searches for the new range
4137 ''' plRows : the number of rows by which the reference was corrected up (negative value) or down.
4138 ''' plColumns : the number of columns by which the reference was corrected to the left (negative value) or to the right.
4139 ''' plHeight : the vertical height for an area that starts at the new reference position.
4140 ''' plWidth : the horizontal width for an area that starts at the new reference position.
4141 ''' Arguments Rows and Columns must not lead to zero or negative start row or column.
4142 ''' Arguments Height and Width must not lead to zero or negative count of rows or columns.
4143 ''' Returns:
4144 ''' A new range as object of type _Address
4145 ''' Exceptions:
4146 ''' OFFSETADDRESSERROR The computed range of cells falls beyond the sheet boundaries
4148 Dim oOffset As Object
' Return value
4149 Dim oAddress As Object
' Alias of Range
4150 Dim oSheet As Object
' com.sun.star.sheet.XSpreadsheet
4151 Dim oRange As Object
' com.sun.star.table.XCellRange
4152 Dim oNewRange As Object
' com.sun.star.table.XCellRange
4153 Dim lLeft As Long
' New range coordinates
4158 Set oOffset = Nothing
4161 If plHeight
< 0 Or plWidth
< 0 Then GoTo CatchAddress
4164 If VarType(pvRange) = V_STRING Then Set oAddress = _ParseAddress(pvRange) Else Set oAddress = pvRange
4165 Set oSheet = oAddress.XSpreadSheet
4166 Set oRange = oAddress.XCellRange.RangeAddress
4169 ' Compute and validate new coordinates
4171 lLeft = .StartColumn + plColumns
4172 lTop = .StartRow + plRows
4173 lRight = lLeft + Iif(plWidth =
0, .EndColumn - .StartColumn, plWidth -
1)
4174 lBottom = lTop + Iif(plHeight =
0, .EndRow - .StartRow, plHeight -
1)
4175 If lLeft
< 0 Or lRight
< 0 Or lTop
< 0 Or lBottom
< 0 _
4176 Or lLeft
>= MAXCOLS Or lRight
>= MAXCOLS _
4177 Or lTop
>= MAXROWS Or lBottom
>= MAXROWS _
4178 Then GoTo CatchAddress
4179 Set oNewRange = oSheet.getCellRangeByPosition(lLeft, lTop, lRight, lBottom)
4182 ' Define the new range address
4183 Set oOffset = New _Address
4185 .ObjectType = CALCREFERENCE
4186 .ServiceName = SERVICEREFERENCE
4187 .RawAddress = oNewRange.AbsoluteName
4188 .Component = _Component
4189 .XSpreadsheet = oNewRange.Spreadsheet
4190 .SheetName = .XSpreadsheet.Name
4191 .SheetIndex = .XSpreadsheet.RangeAddress.Sheet
4192 .RangeName = .RawAddress
4193 .XCellRange = oNewRange
4194 .Height = oNewRange.RangeAddress.EndRow - oNewRange.RangeAddress.StartRow +
1
4195 .Width = oNewRange.RangeAddress.EndColumn - oNewRange.RangeAddress.StartColumn +
1
4199 Set _Offset = oOffset
4204 ScriptForge.SF_Exception.RaiseFatal(OFFSETADDRESSERROR,
"Range
", oAddress.RawAddress _
4205 ,
"Rows
", plRows,
"Columns
", plColumns,
"Height
", plHeight,
"Width
", plWidth _
4206 ,
"Document
", [_Super]._FileIdent())
4208 End Function
' SFDocuments.SF_Calc._Offset
4210 REM -----------------------------------------------------------------------------
4211 Private Function _ParseAddress(ByVal psAddress As String) As Object
4212 ''' Parse and validate a sheet or range reference
4213 ''' Syntax to parse:
4214 ''' [Sheet].[Range]
4215 ''' Sheet =
> [
'][$]sheet[
'] or document named range or ~
4216 ''' Range =
> A1:D10, A1, A:D,
10:
10 ($ ignored), or sheet named range or ~
4217 ''' Returns:
4218 ''' An object of type _Address
4219 ''' Exceptions:
4220 ''' CALCADDRESSERROR
' Address could not be parsed to a valid address
4222 Dim oAddress As Object
' Return value
4223 Dim sAddress As String
' Alias of psAddress
4224 Dim vRangeName As Variant
' Array Sheet/Range
4225 Dim lStart As Long
' Position of found regex
4226 Dim sSheet As String
' Sheet component
4227 Dim sRange As String
' Range component
4228 Dim oSheets As Object
' com.sun.star.sheet.XSpreadsheets
4229 Dim oNamedRanges As Object
' com.sun.star.sheet.XNamedRanges
4230 Dim oRangeAddress As Object
' Alias for rangeaddress
4231 Dim vLastCell As Variant
' Result of _LastCell() method
4232 Dim oSelect As Object
' Current selection
4234 ' If psAddress has already been parsed, get the result back
4235 If Not IsNull(_LastParsedAddress) Then
4236 ' Given argument must contain an explicit reference to a sheet
4237 If (InStr(psAddress,
"~.
") =
0 And InStr(psAddress,
".
")
> 0 And psAddress = _LastParsedAddress.RawAddress) _
4238 Or psAddress = _LastParsedAddress.RangeName Then
4239 Set _ParseAddress = _LastParsedAddress
4242 Set _LastParsedAddress = Nothing
4246 ' Reinitialize a new _Address object
4247 Set oAddress = New _Address
4249 sSheet =
"" : sRange =
""
4250 .SheetName =
"" : .RangeName =
""
4252 .ObjectType = CALCREFERENCE
4253 .ServiceName = SERVICEREFERENCE
4254 .RawAddress = psAddress
4255 Set .XSpreadSheet = Nothing : Set .XCellRange = Nothing
4257 ' Remove leading
"$
' when followed with an apostrophe
4258 If Left(psAddress,
2) =
"$
'" Then sAddress = Mid(psAddress,
2) Else sAddress = psAddress
4259 ' Split in sheet and range components on dot not enclosed in single quotes
4260 vRangeName = ScriptForge.SF_String.SplitNotQuoted(sAddress, Delimiter :=
".
", QuoteChar :=
"'")
4261 sSheet = ScriptForge.SF_String.Unquote(Replace(vRangeName(
0),
"''",
"\
'"), QuoteChar :=
"'")
4262 ' Keep a leading
"$
" in the sheet name only if name enclosed in single quotes
4264 ' sheet names may contain
"$
" (even
"$
" is a valid sheet name), named ranges must not
4265 ' sheet names may contain apostrophes (except in
1st and last positions), range names must not
4266 If Left(vRangeName(
0),
2)
<> "'$
" And Left(sSheet,
1) =
"$
" And Len(sSheet)
> 1 Then sSheet = Mid(sSheet,
2)
4267 If UBound(vRangeName)
> 0 Then sRange = vRangeName(
1)
4269 ' Resolve sheet part: either a document named range, or the active sheet or a real sheet
4270 Set oSheets = _Component.getSheets()
4271 Set oNamedRanges = _Component.NamedRanges
4272 If oSheets.hasByName(sSheet) Then
4273 ElseIf sSheet =
"~
" And Len(sRange)
> 0 Then
4274 sSheet = _Component.CurrentController.ActiveSheet.Name
4275 ElseIf oNamedRanges.hasByName(sSheet) Then
4276 .XCellRange = oNamedRanges.getByName(sSheet).ReferredCells
4277 sSheet = oSheets.getByIndex(oNamedRanges.getByName(sSheet).ReferencePosition.Sheet).Name
4280 sSheet = _Component.CurrentController.ActiveSheet.Name
4283 .XSpreadSheet = oSheets.getByName(sSheet)
4284 .SheetIndex = .XSpreadSheet.RangeAddress.Sheet
4286 ' Resolve range part - either a sheet named range or the current selection or a real range or
""
4287 If IsNull(.XCellRange) Then
4288 Set oNamedRanges = .XSpreadSheet.NamedRanges
4289 If sRange =
"~
" Then
4290 Set oSelect = _Component.CurrentController.getSelection()
4291 If oSelect.supportsService(
"com.sun.star.sheet.SheetCellRanges
") Then
' Multiple selections
4292 Set .XCellRange = oSelect.getByIndex(
0)
4294 Set .XCellRange = oSelect
4296 ElseIf sRange =
"*
" Or sRange =
"" Then
4297 vLastCell = _LastCell(.XSpreadSheet)
4298 sRange =
"A1:
" & _GetColumnName(vLastCell(
0))
& CStr(vLastCell(
1))
4299 Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
4300 ElseIf oNamedRanges.hasByName(sRange) Then
4301 .XCellRange = oNamedRanges.getByName(sRange).ReferredCells
4303 On Local Error GoTo CatchError
4304 Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
4305 ' If range reaches the limits of the sheets, reduce it up to the used area
4306 Set oRangeAddress = .XCellRange.RangeAddress
4307 If oRangeAddress.StartColumn =
0 And oRangeAddress.EndColumn = MAXCOLS -
1 Then
4308 vLastCell = _LastCell(.XSpreadSheet)
4309 sRange =
"A
" & CStr(oRangeAddress.StartRow +
1)
& ":
" _
4310 & _GetColumnName(vLastCell(
0))
& CStr(oRangeAddress.EndRow +
1)
4311 Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
4312 ElseIf oRangeAddress.StartRow =
0 And oRangeAddress.EndRow = MAXROWS -
1 Then
4313 vLastCell = _LastCell(.XSpreadSheet)
4314 sRange = _GetColumnName(oRangeAddress.StartColumn +
1)
& "1" & ":
" _
4315 & _GetColumnName(oRangeAddress.EndColumn +
1)
& CStr(_LastCell(.XSpreadSheet)(
1))
4316 Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
4320 If IsNull(.XCellRange) Then GoTo CatchAddress
4322 Set oRangeAddress = .XCellRange.RangeAddress
4323 .RangeName = .XCellRange.AbsoluteName
4324 .Height = oRangeAddress.EndRow - oRangeAddress.StartRow +
1
4325 .Width = oRangeAddress.EndColumn - oRangeAddress.StartColumn +
1
4327 ' Remember the current component in case of use outside the current instance
4328 Set .Component = _Component
4332 ' Store last parsed address for reuse
4333 Set _LastParsedAddress = oAddress
4336 Set _ParseAddress = oAddress
4339 ScriptForge.SF_Exception.Clear()
4341 ScriptForge.SF_Exception.RaiseFatal(CALCADDRESSERROR,
"Range
", psAddress _
4342 ,
"Document
", [_Super]._FileIdent())
4344 End Function
' SFDocuments.SF_Calc._ParseAddress
4346 REM -----------------------------------------------------------------------------
4347 Private Function _PropertyGet(Optional ByVal psProperty As String _
4348 , Optional ByVal pvArg As Variant _
4350 ''' Return the value of the named property
4351 ''' Args:
4352 ''' psProperty: the name of the property
4354 Dim oProperties As Object
' Document or Custom properties
4355 Dim vLastCell As Variant
' Coordinates of last used cell in a sheet
4356 Dim oSelect As Object
' Current selection
4357 Dim vRanges As Variant
' List of selected ranges
4358 Dim oAddress As Object
' _Address type for range description
4359 Dim oCursor As Object
' com.sun.star.sheet.XSheetCellCursor
4361 Dim cstThisSub As String
4362 Const cstSubArgs =
""
4364 _PropertyGet = False
4366 cstThisSub =
"SFDocuments.Calc.get
" & psProperty
4367 ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
4368 If Not _IsStillAlive() Then GoTo Finally
4370 Select Case UCase(psProperty)
4371 Case UCase(
"CurrentSelection
")
4372 Set oSelect = _Component.CurrentController.getSelection()
4373 If IsNull(oSelect) Then
4374 _PropertyGet = Array()
4375 ElseIf oSelect.supportsService(
"com.sun.star.sheet.SheetCellRanges
") Then
' Multiple selections
4377 For i =
0 To oSelect.Count -
1
4378 vRanges = ScriptForge.SF_Array.Append(vRanges, oSelect.getByIndex(i).AbsoluteName)
4380 _PropertyGet = vRanges
4382 _PropertyGet = oSelect.AbsoluteName
4384 Case UCase(
"Height
")
4385 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4388 If Not ScriptForge.SF_Utils._Validate(pvArg,
"Range
", V_STRING) Then GoTo Finally
4389 _PropertyGet = _ParseAddress(pvArg).Height
4391 Case UCase(
"FirstCell
"), UCase(
"FirstRow
"), UCase(
"FirstColumn
") _
4392 , UCase(
"LastCell
"), UCase(
"LastColumn
"), UCase(
"LastRow
") _
4393 , UCase(
"SheetName
")
4394 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
' Avoid errors when instance is watched in Basic IDE
4395 If InStr(UCase(psProperty),
"CELL
")
> 0 Then _PropertyGet =
"" Else _PropertyGet = -
1
4397 If Not ScriptForge.SF_Utils._Validate(pvArg,
"Range
", V_STRING) Then GoTo Finally
4398 Set oAddress = _ParseAddress(pvArg)
4399 With oAddress.XCellRange
4400 Select Case UCase(psProperty)
4401 Case UCase(
"FirstCell
")
4402 _PropertyGet = A1Style(.RangeAddress.StartRow +
1, .RangeAddress.StartColumn +
1, , , oAddress.XSpreadsheet.Name)
4403 Case UCase(
"FirstColumn
") : _PropertyGet = CLng(.RangeAddress.StartColumn +
1)
4404 Case UCase(
"FirstRow
") : _PropertyGet = CLng(.RangeAddress.StartRow +
1)
4405 Case UCase(
"LastCell
")
4406 _PropertyGet = A1Style(.RangeAddress.EndRow +
1, .RangeAddress.EndColumn +
1, , , oAddress.XSpreadsheet.Name)
4407 Case UCase(
"LastColumn
") : _PropertyGet = CLng(.RangeAddress.EndColumn +
1)
4408 Case UCase(
"LastRow
") : _PropertyGet = CLng(.RangeAddress.EndRow +
1)
4409 Case UCase(
"SheetName
") : _PropertyGet = oAddress.XSpreadsheet.Name
4413 Case UCase(
"Range
")
4414 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4415 Set _PropertyGet = Nothing
4417 If Not ScriptForge.SF_Utils._Validate(pvArg,
"Range
", V_STRING) Then GoTo Finally
4418 Set _PropertyGet = _ParseAddress(pvArg)
4420 Case UCase(
"Region
")
4421 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4422 _PropertyGet =
""
4424 If Not ScriptForge.SF_Utils._Validate(pvArg,
"Range
", V_STRING) Then GoTo Finally
4425 Set oAddress = _ParseAddress(pvArg)
4427 Set oCursor = .XSpreadsheet.createCursorByRange(.XCellRange)
4428 oCursor.collapseToCurrentRegion()
4429 _PropertyGet = oCursor.AbsoluteName
4432 Case UCase(
"Sheet
")
4433 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4434 Set _PropertyGet = Nothing
4436 If Not _ValidateSheet(pvArg,
"SheetName
", , True) Then GoTo Finally
4437 Set _PropertyGet = _ParseAddress(pvArg)
4439 Case UCase(
"Sheets
")
4440 _PropertyGet = _Component.getSheets.getElementNames()
4441 Case UCase(
"Width
")
4442 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4445 If Not ScriptForge.SF_Utils._Validate(pvArg,
"Range
", V_STRING) Then GoTo Finally
4446 _PropertyGet = _ParseAddress(pvArg).Width
4448 Case UCase(
"XCellRange
")
4449 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4450 Set _PropertyGet = Nothing
4452 If Not ScriptForge.SF_Utils._Validate(pvArg,
"Range
", V_STRING) Then GoTo Finally
4453 Set _PropertyGet = _ParseAddress(pvArg).XCellRange
4455 Case UCase(
"XSheetCellCursor
")
4456 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4457 Set _PropertyGet = Nothing
4459 If Not ScriptForge.SF_Utils._Validate(pvArg,
"Range
", V_STRING) Then GoTo Finally
4460 Set oAddress = _ParseAddress(pvArg)
4461 Set _PropertyGet = oAddress.XSpreadsheet.createCursorByRange(oAddress.XCellRange)
4463 Case UCase(
"XSpreadsheet
")
4464 If IsMissing(pvArg) Or IsEmpty(pvArg) Then
4465 Set _PropertyGet = Nothing
4467 If Not _ValidateSheet(pvArg,
"SheetName
", , True) Then GoTo Finally
4468 Set _PropertyGet = _Component.getSheets.getByName(pvArg)
4475 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
4477 End Function
' SFDocuments.SF_Calc._PropertyGet
4479 REM -----------------------------------------------------------------------------
4480 Private Function _QuoteSheetName(ByVal psSheetName As String) As String
4481 ''' Return the given sheet name surrounded with single quotes
4482 ''' when required to insert the sheet name into a Calc formula
4483 ''' Enclosed single quotes are doubled
4484 ''' Args:
4485 ''' psSheetName: the name to quote
4486 ''' Returns:
4487 ''' The quoted or unchanged sheet name
4489 Dim sSheetName As String
' Return value
4493 ' Surround the sheet name with single quotes when required by the presence of single quotes
4494 If InStr(psSheetName,
"'")
> 0 Then
4495 sSheetName =
"'" & Replace(psSheetName,
"'",
"''")
& "'"
4497 ' Surround the sheet name with single quotes when required by the presence of at least one of the special characters
4498 sSheetName = psSheetName
4499 For i =
1 To Len(cstSPECIALCHARS)
4500 If InStr(sSheetName, Mid(cstSPECIALCHARS, i,
1))
> 0 Then
4501 sSheetName =
"'" & sSheetName
& "'"
4508 _QuoteSheetName = sSheetName
4510 End Function
' SFDocuments.SF_Calc._QuoteSheetName
4512 REM -----------------------------------------------------------------------------
4513 Private Function _Repr() As String
4514 ''' Convert the SF_Calc instance to a readable string, typically for debugging purposes (DebugPrint ...)
4515 ''' Args:
4516 ''' Return:
4517 ''' "[DOCUMENT]: Type/File
"
4519 _Repr =
"[Calc]:
" & [_Super]._FileIdent()
4521 End Function
' SFDocuments.SF_Calc._Repr
4523 REM -----------------------------------------------------------------------------
4524 Private Sub _RestoreSelections(ByRef pvComponent As Variant _
4525 , ByRef pvSelection As Variant _
4527 ''' Set the selection to a single or a multiple range
4528 ''' Does not work well when multiple selections and macro terminating in Basic IDE
4529 ''' Called by the CopyToCell and CopyToRange methods
4530 ''' Args:
4531 ''' pvComponent: should work for foreign instances as well
4532 ''' pvSelection: the stored selection done previously by Component.CurrentController.getSelection()
4534 Dim oCellRanges As Object
' com.sun.star.sheet.SheetCellRanges
4535 Dim vRangeAddresses As Variant
' Array of com.sun.star.table.CellRangeAddress
4539 If IsArray(pvSelection) Then
4540 Set oCellRanges = pvComponent.createInstance(
"com.sun.star.sheet.SheetCellRanges
")
4541 vRangeAddresses = Array()
4542 ReDim vRangeAddresses(
0 To UBound(pvSelection))
4543 For i =
0 To UBound(pvSelection)
4544 vRangeAddresses(i) = pvSelection.getByIndex(i).RangeAddress
4546 oCellRanges.addRangeAddresses(vRangeAddresses, False)
4547 pvComponent.CurrentController.select(oCellRanges)
4549 pvComponent.CurrentController.select(pvSelection)
4554 End Sub
' SFDocuments.SF_Calc._RestoreSelections
4556 REM -----------------------------------------------------------------------------
4557 Private Function _ValidateSheet(Optional ByRef pvSheetName As Variant _
4558 , Optional ByVal psArgName As String _
4559 , Optional ByVal pvNew As Variant _
4560 , Optional ByVal pvActive As Variant _
4561 , Optional ByVal pvOptional as Variant _
4562 , Optional ByVal pvNumeric As Variant _
4563 , Optional ByVal pvReference As Variant _
4564 , Optional ByVal pvResetSheet As Variant _
4566 ''' Sheet designation validation function similar to the SF_Utils._ValidateXXX functions
4567 ''' Args:
4568 ''' pvSheetName: string or numeric position
4569 ''' pvArgName: the name of the variable to be used in the error message
4570 ''' pvNew: if True, sheet must not exist (default = False)
4571 ''' pvActive: if True, the shortcut
"~
" is accepted (default = False)
4572 ''' pvOptional: if True, a zero-length string is accepted (default = False)
4573 ''' pvNumeric: if True, the sheet position is accepted (default = False)
4574 ''' pvReference: if True, a sheet reference is acceptable (default = False)
4575 ''' pvNumeric and pvReference must not both be = True
4576 ''' pvResetSheet: if True, return in pvSheetName the correct (case-sensitive) sheet name (default = False)
4577 ''' Returns
4578 ''' True if valid. SheetName is reset to current value if =
"~
"
4579 ''' Exceptions
4580 ''' DUPLICATESHEETERROR A sheet with the given name exists already
4582 Dim vSheets As Variant
' List of sheets
4583 Dim lSheet As Long
' Index in list of sheets
4584 Dim vTypes As Variant
' Array of accepted variable types
4585 Dim bValid As Boolean
' Return value
4588 If IsMissing(pvNew) Or IsEmpty(pvNew) Then pvNew = False
4589 If IsMissing(pvActive) Or IsEmpty(pvActive) Then pvActive = False
4590 If IsMissing(pvOptional) Or IsEmpty(pvOptional) Then pvOptional = False
4591 If IsMissing(pvNumeric) Or IsEmpty(pvNumeric) Then pvNumeric = False
4592 If IsMissing(pvReference) Or IsEmpty(pvReference) Then pvReference = False
4593 If IsMissing(pvResetSheet) Or IsEmpty(pvResetSheet) Then pvResetSheet = False
4595 ' Define the acceptable variable types
4597 vTypes = Array(V_STRING, V_NUMERIC)
4598 ElseIf pvReference Then
4599 vTypes = Array(V_STRING, ScriptForge.V_OBJECT)
4603 If Not ScriptForge.SF_Utils._Validate(pvSheetName, psArgName, vTypes, , , Iif(pvReference, CALCREFERENCE,
"")) Then GoTo Finally
4607 If VarType(pvSheetName) = V_STRING Then
4608 If pvOptional And Len(pvSheetName) =
0 Then
4609 ElseIf pvActive And pvSheetName =
"~
" Then
4610 pvSheetName = _Component.CurrentController.ActiveSheet.Name
4612 vSheets = _Component.getSheets.getElementNames()
4614 ' ScriptForge.SF_String.FindRegex(sAddress,
"^
'[^\[\]*?:\/\\]+
'")
4615 If ScriptForge.SF_Array.Contains(vSheets, pvSheetName) Then GoTo CatchDuplicate
4617 If Not ScriptForge.SF_Utils._Validate(pvSheetName, psArgName, V_STRING, vSheets) Then GoTo Finally
4618 If pvResetSheet Then
4619 lSheet = ScriptForge.SF_Array.IndexOf(vSheets, pvSheetName, CaseSensitive := False)
4620 pvSheetName = vSheets(lSheet)
4628 _ValidateSheet = bValid
4631 ScriptForge.SF_Exception.RaiseFatal(DUPLICATESHEETERROR, psArgName, pvSheetName,
"Document
", [_Super]._FileIdent())
4633 End Function
' SFDocuments.SF_Calc._ValidateSheet
4635 REM -----------------------------------------------------------------------------
4636 Private Function _ValidateSheetName(ByRef psSheetName As String _
4637 , ByVal psArgName As String _
4639 ''' Check the validity of the sheet name:
4640 ''' A sheet name - must not be empty
4641 ''' - must not contain next characters: []*?:/\
4642 ''' - must not use
' (the apostrophe) as first or last character
4643 ''' Args:
4644 ''' psSheetName: the name to check
4645 ''' psArgName: the name of the argument to appear in error messages
4646 ''' Returns:
4647 ''' True when the sheet name is valid
4648 ''' Exceptions:
4649 ''' CALCADDRESSERROR
' Sheet name could not be parsed to a valid name
4651 Dim bValid As Boolean
' Return value
4654 bValid = ( Len(psSheetName)
> 0 )
4655 If bValid Then bValid = ( Left(psSheetName,
1)
<> "'" And Right(psSheetName,
1)
<> "'" )
4656 If bValid Then bValid = ( Len(ScriptForge.SF_String.FindRegex(psSheetName,
"^[^\[\]*?:\/\\]+$
",
1, CaseSensitive := False))
> 0 )
4657 If Not bValid Then GoTo CatchSheet
4660 _ValidateSheetName = bValid
4663 ScriptForge.SF_Exception.RaiseFatal(CALCADDRESSERROR, psArgName, psSheetName _
4664 ,
"Document
", [_Super]._FileIdent())
4666 End Function
' SFDocuments.SF_Calc._ValidateSheetName
4668 REM ============================================ END OF SFDOCUMENTS.SF_CALC