SF_Calc.xba 124 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843
  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 =======================================================================================================================
  8. Option Compatible
  9. Option ClassModule
  10. Option Explicit
  11. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  12. &apos;&apos;&apos; SF_Calc
  13. &apos;&apos;&apos; =======
  14. &apos;&apos;&apos;
  15. &apos;&apos;&apos; The SFDocuments library gathers a number of methods and properties making easy
  16. &apos;&apos;&apos; the management and several manipulations of LibreOffice documents
  17. &apos;&apos;&apos;
  18. &apos;&apos;&apos; Some methods are generic for all types of documents: they are combined in the SF_Document module.
  19. &apos;&apos;&apos; Specific properties and methods are implemented in the concerned subclass(es) SF_Calc, SF_Writer, ...
  20. &apos;&apos;&apos;
  21. &apos;&apos;&apos; To workaround the absence of class inheritance in LibreOffice Basic, some redundancy is necessary
  22. &apos;&apos;&apos; Each subclass MUST implement also the generic methods and properties, even if they only call
  23. &apos;&apos;&apos; the parent methods and properties.
  24. &apos;&apos;&apos; They should also duplicate some generic private members as a subset of their own set of members
  25. &apos;&apos;&apos;
  26. &apos;&apos;&apos; The SF_Calc module is focused on :
  27. &apos;&apos;&apos; - management (copy, insert, move, ...) of sheets within a Calc document
  28. &apos;&apos;&apos; - exchange of data between Basic data structures and Calc ranges of values
  29. &apos;&apos;&apos;
  30. &apos;&apos;&apos; The current module is closely related to the &quot;UI&quot; service of the ScriptForge library
  31. &apos;&apos;&apos;
  32. &apos;&apos;&apos; Service invocation examples:
  33. &apos;&apos;&apos; 1) From the UI service
  34. &apos;&apos;&apos; Dim ui As Object, oDoc As Object
  35. &apos;&apos;&apos; Set ui = CreateScriptService(&quot;UI&quot;)
  36. &apos;&apos;&apos; Set oDoc = ui.CreateDocument(&quot;Calc&quot;, ...)
  37. &apos;&apos;&apos; &apos; or Set oDoc = ui.OpenDocument(&quot;C:\Me\MyFile.ods&quot;)
  38. &apos;&apos;&apos; 2) Directly if the document is already opened
  39. &apos;&apos;&apos; Dim oDoc As Object
  40. &apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.Calc&quot;, &quot;Untitled 1&quot;) &apos; Default = ActiveWindow
  41. &apos;&apos;&apos; &apos; or Set oDoc = CreateScriptService(&quot;SFDocuments.Calc&quot;, &quot;Untitled 1&quot;) &apos; Untitled 1 is presumed a Calc document
  42. &apos;&apos;&apos; &apos; The substring &quot;SFDocuments.&quot; in the service name is optional
  43. &apos;&apos;&apos;
  44. &apos;&apos;&apos; Definitions:
  45. &apos;&apos;&apos; Many methods require a &quot;Sheet&quot; or a &quot;Range&quot; as argument. (NB: a single cell is considered as a special case of a Range)
  46. &apos;&apos;&apos; Usually, within a specific Calc instance, sheets and ranges are given as a string: &quot;SheetX&quot; and &quot;D2:F6&quot;
  47. &apos;&apos;&apos; Multiple ranges are not supported in this context.
  48. &apos;&apos;&apos; Additionally, the .Sheet and .Range methods return a reference that may be used
  49. &apos;&apos;&apos; as argument of a method called from another instance of the Calc service
  50. &apos;&apos;&apos; Example:
  51. &apos;&apos;&apos; Dim oDocA As Object : Set oDocA = ui.OpenDocument(&quot;C:\FileA.ods&quot;, Hidden := True, ReadOnly := True)
  52. &apos;&apos;&apos; Dim oDocB As Object : Set oDocB = ui.OpenDocument(&quot;C:\FileB.ods&quot;)
  53. &apos;&apos;&apos; oDocB.CopyToRange(oDocA.Range(&quot;SheetX.D4:F8&quot;), &quot;D2:F6&quot;) &apos; CopyToRange(source, target)
  54. &apos;&apos;&apos;
  55. &apos;&apos;&apos; Sheet: the sheet name as a string or an object produced by .Sheet()
  56. &apos;&apos;&apos; &quot;~&quot; = current sheet
  57. &apos;&apos;&apos; Range: a string designating a set of contiguous cells located in a sheet of the current instance
  58. &apos;&apos;&apos; &quot;~&quot; = current selection (if multiple selections, its 1st component)
  59. &apos;&apos;&apos; or an object produced by .Range()
  60. &apos;&apos;&apos; The sheet name is optional (default = active sheet). Surrounding quotes and $ signs are optional
  61. &apos;&apos;&apos; ~.~, ~ The current selection in the active sheet
  62. &apos;&apos;&apos; &apos;$SheetX&apos;.D2 or $D$2 A single cell
  63. &apos;&apos;&apos; &apos;$SheetX&apos;.D2:F6, D2:D10 Multiple cells
  64. &apos;&apos;&apos; &apos;$SheetX&apos;.A:A or 3:5 All cells in the same column or row up to the last active cell
  65. &apos;&apos;&apos; SheetX.* All cells up to the last active cell
  66. &apos;&apos;&apos; myRange A range name at spreadsheet level
  67. &apos;&apos;&apos; ~.yourRange, SheetX.someRange A range name at sheet level
  68. &apos;&apos;&apos; myDoc.Range(&quot;SheetX.D2:F6&quot;)
  69. &apos;&apos;&apos; A range within the sheet SheetX in file associated with the myDoc Calc instance
  70. &apos;&apos;&apos;
  71. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  72. REM ================================================================== EXCEPTIONS
  73. Private Const UNKNOWNFILEERROR = &quot;UNKNOWNFILEERROR&quot;
  74. Private Const BASEDOCUMENTOPENERROR = &quot;BASEDOCUMENTOPENERROR&quot;
  75. Private Const CALCADDRESSERROR = &quot;CALCADDRESSERROR&quot;
  76. Private Const DUPLICATESHEETERROR = &quot;DUPLICATESHEETERROR&quot;
  77. Private Const OFFSETADDRESSERROR = &quot;OFFSETADDRESSERROR&quot;
  78. REM ============================================================= PRIVATE MEMBERS
  79. Private [Me] As Object
  80. Private [_Parent] As Object
  81. Private [_Super] As Object &apos; Document superclass, which the current instance is a subclass of
  82. Private ObjectType As String &apos; Must be CALC
  83. Private ServiceName As String
  84. &apos; Window component
  85. Private _Component As Object &apos; com.sun.star.lang.XComponent
  86. Type _Address
  87. ObjectType As String &apos; Must be &quot;SF_CalcReference&quot;
  88. RawAddress As String
  89. Component As Object &apos; com.sun.star.lang.XComponent
  90. SheetName As String
  91. SheetIndex As Integer
  92. RangeName As String
  93. Height As Long
  94. Width As Long
  95. XSpreadSheet As Object &apos; com.sun.star.sheet.XSpreadsheet
  96. XCellRange As Object &apos; com.sun.star.table.XCellRange
  97. End Type
  98. REM ============================================================ MODULE CONSTANTS
  99. Private Const cstSHEET = 1
  100. Private Const cstRANGE = 2
  101. Private Const MAXCOLS = 2^10 &apos; Max number of columns in a sheet
  102. Private Const MAXROWS = 2^20 &apos; Max number of rows in a sheet
  103. Private Const CALCREFERENCE = &quot;SF_CalcReference&quot; &apos; Object type of _Address
  104. REM ===================================================== CONSTRUCTOR/DESTRUCTOR
  105. REM -----------------------------------------------------------------------------
  106. Private Sub Class_Initialize()
  107. Set [Me] = Nothing
  108. Set [_Parent] = Nothing
  109. Set [_Super] = Nothing
  110. ObjectType = &quot;CALC&quot;
  111. ServiceName = &quot;SFDocuments.Calc&quot;
  112. Set _Component = Nothing
  113. End Sub &apos; SFDocuments.SF_Calc Constructor
  114. REM -----------------------------------------------------------------------------
  115. Private Sub Class_Terminate()
  116. Call Class_Initialize()
  117. End Sub &apos; SFDocuments.SF_Calc Destructor
  118. REM -----------------------------------------------------------------------------
  119. Public Function Dispose() As Variant
  120. If Not IsNull([_Super]) Then Set [_Super] = [_Super].Dispose()
  121. Call Class_Terminate()
  122. Set Dispose = Nothing
  123. End Function &apos; SFDocuments.SF_Calc Explicit Destructor
  124. REM ================================================================== PROPERTIES
  125. REM -----------------------------------------------------------------------------
  126. Property Get CurrentSelection() As Variant
  127. &apos;&apos;&apos; Returns as a string the currently selected range or as an array the list of the currently selected ranges
  128. CurrentSelection = _PropertyGet(&quot;CurrentSelection&quot;)
  129. End Property &apos; SFDocuments.SF_Calc.CurrentSelection (get)
  130. REM -----------------------------------------------------------------------------
  131. Property Let CurrentSelection(Optional ByVal pvSelection As Variant)
  132. &apos;&apos;&apos; Set the selection to a single or a multiple range
  133. &apos;&apos;&apos; The argument is a string or an array of strings
  134. Dim sRange As String &apos; A single selection
  135. Dim oCellRanges As Object &apos; com.sun.star.sheet.SheetCellRanges
  136. Dim vRangeAddresses As Variant &apos; Array of com.sun.star.table.CellRangeAddress
  137. Dim i As Long
  138. Const cstThisSub = &quot;SFDocuments.Calc.setCurrentSelection&quot;
  139. Const cstSubArgs = &quot;Selection&quot;
  140. On Local Error GoTo Catch
  141. Check:
  142. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  143. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  144. If IsArray(pvSelection) Then
  145. If Not ScriptForge.SF_Utils._ValidateArray(pvSelection, &quot;pvSelection&quot;, 1, V_STRING, True) Then GoTo Finally
  146. Else
  147. If Not ScriptForge.SF_Utils._Validate(pvSelection, &quot;pvSelection&quot;, V_STRING) Then GoTo Finally
  148. End If
  149. End If
  150. Try:
  151. If IsArray(pvSelection) Then
  152. Set oCellRanges = _Component.createInstance(&quot;com.sun.star.sheet.SheetCellRanges&quot;)
  153. vRangeAddresses = Array()
  154. ReDim vRangeAddresses(0 To UBound(pvSelection))
  155. For i = 0 To UBound(pvSelection)
  156. vRangeAddresses(i) = Range(pvSelection(i)).XCellRange.RangeAddress
  157. Next i
  158. oCellRanges.addRangeAddresses(vRangeAddresses, False)
  159. _Component.CurrentController.select(oCellRanges)
  160. Else
  161. _Component.CurrentController.select(_ParseAddress(pvSelection).XCellRange)
  162. End If
  163. Finally:
  164. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  165. Exit Property
  166. Catch:
  167. GoTo Finally
  168. End Property &apos; SFDocuments.SF_Calc.CurrentSelection (let)
  169. REM -----------------------------------------------------------------------------
  170. Property Get Height(Optional ByVal RangeName As Variant) As Long
  171. &apos;&apos;&apos; Returns the height in # of rows of the given range
  172. Height = _PropertyGet(&quot;Height&quot;, RangeName)
  173. End Property &apos; SFDocuments.SF_Calc.Height
  174. REM -----------------------------------------------------------------------------
  175. Property Get LastCell(Optional ByVal SheetName As Variant) As String
  176. &apos;&apos;&apos; Returns the last used cell in a given sheet
  177. LastCell = _PropertyGet(&quot;LastCell&quot;, SheetName)
  178. End Property &apos; SFDocuments.SF_Calc.LastCell
  179. REM -----------------------------------------------------------------------------
  180. Property Get LastColumn(Optional ByVal SheetName As Variant) As Long
  181. &apos;&apos;&apos; Returns the last used column in a given sheet
  182. LastColumn = _PropertyGet(&quot;LastColumn&quot;, SheetName)
  183. End Property &apos; SFDocuments.SF_Calc.LastColumn
  184. REM -----------------------------------------------------------------------------
  185. Property Get LastRow(Optional ByVal SheetName As Variant) As Long
  186. &apos;&apos;&apos; Returns the last used column in a given sheet
  187. LastRow = _PropertyGet(&quot;LastRow&quot;, SheetName)
  188. End Property &apos; SFDocuments.SF_Calc.LastRow
  189. REM -----------------------------------------------------------------------------
  190. Property Get Range(Optional ByVal RangeName As Variant) As Variant
  191. &apos;&apos;&apos; Returns a (internal) range object
  192. Range = _PropertyGet(&quot;Range&quot;, RangeName)
  193. End Property &apos; SFDocuments.SF_Calc.Range
  194. REM -----------------------------------------------------------------------------
  195. Property Get Sheet(Optional ByVal SheetName As Variant) As Variant
  196. &apos;&apos;&apos; Returns a (internal) sheet object
  197. Sheet = _PropertyGet(&quot;Sheet&quot;, SheetName)
  198. End Property &apos; SFDocuments.SF_Calc.Sheet
  199. REM -----------------------------------------------------------------------------
  200. Property Get Sheets() As Variant
  201. &apos;&apos;&apos; Returns an array listing the existing sheet names
  202. Sheets = _PropertyGet(&quot;Sheets&quot;)
  203. End Property &apos; SFDocuments.SF_Calc.Sheets
  204. REM -----------------------------------------------------------------------------
  205. Property Get Width(Optional ByVal RangeName As Variant) As Long
  206. &apos;&apos;&apos; Returns the width in # of columns of the given range
  207. Width = _PropertyGet(&quot;Width&quot;, RangeName)
  208. End Property &apos; SFDocuments.SF_Calc.Width
  209. REM -----------------------------------------------------------------------------
  210. Property Get XCellRange(Optional ByVal RangeName As Variant) As Variant
  211. &apos;&apos;&apos; Returns a UNO object of type com.sun.star.Table.CellRange
  212. XCellRange = _PropertyGet(&quot;XCellRange&quot;, RangeName)
  213. End Property &apos; SFDocuments.SF_Calc.XCellRange
  214. REM -----------------------------------------------------------------------------
  215. Property Get XSpreadsheet(Optional ByVal SheetName As Variant) As Variant
  216. &apos;&apos;&apos; Returns a UNO object of type com.sun.star.sheet.XSpreadsheet
  217. XSpreadsheet = _PropertyGet(&quot;XSpreadsheet&quot;, SheetName)
  218. End Property &apos; SFDocuments.SF_Calc.XSpreadsheet
  219. REM ===================================================================== METHODS
  220. REM -----------------------------------------------------------------------------
  221. Public Function Activate(Optional ByVal SheetName As Variant) As Boolean
  222. &apos;&apos;&apos; Make the current document or the given sheet active
  223. &apos;&apos;&apos; Args:
  224. &apos;&apos;&apos; SheetName: Default = the Calc document as a whole
  225. &apos;&apos;&apos; Returns:
  226. &apos;&apos;&apos; True if the document or the sheet could be made active
  227. &apos;&apos;&apos; Otherwise, there is no change in the actual user interface
  228. &apos;&apos;&apos; Examples:
  229. &apos;&apos;&apos; oDoc.Activate(&quot;SheetX&quot;)
  230. Dim bActive As Boolean &apos; Return value
  231. Dim oSheet As Object &apos; Reference to sheet
  232. Const cstThisSub = &quot;SFDocuments.Calc.Activate&quot;
  233. Const cstSubArgs = &quot;[SheetName]&quot;
  234. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  235. bActive = False
  236. Check:
  237. If IsMissing(SheetName) Or IsEmpty(SheetName) Then SheetName = &quot;&quot;
  238. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  239. If Not [_Super]._IsStillAlive() Then GoTo Finally
  240. If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , , True) Then GoTo Finally
  241. End If
  242. Try:
  243. &apos; Sheet activation, to do only when meaningful, precedes document activation
  244. If Len(SheetName) &gt; 0 Then
  245. With _Component
  246. Set oSheet = .getSheets.getByName(SheetName)
  247. Set .CurrentController.ActiveSheet = oSheet
  248. End With
  249. End If
  250. bActive = [_Super].Activate()
  251. Finally:
  252. Activate = bActive
  253. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  254. Exit Function
  255. Catch:
  256. GoTo Finally
  257. End Function &apos; SFDocuments.SF_Calc.Activate
  258. REM -----------------------------------------------------------------------------
  259. Public Sub ClearAll(Optional ByVal Range As Variant) As String
  260. &apos;&apos;&apos; Clear entirely the given range
  261. &apos;&apos;&apos; Args:
  262. &apos;&apos;&apos; Range : the cell or the range as a string that should be cleared
  263. &apos;&apos;&apos; Examples:
  264. &apos;&apos;&apos; oDoc.ClearAll(&quot;SheetX&quot;) &apos; Clears the used area of the sheet
  265. Dim lClear As Long &apos; The elements to clear
  266. Dim oRange As Object &apos; Alias of Range
  267. Const cstThisSub = &quot;SFDocuments.Calc.ClearAll&quot;
  268. Const cstSubArgs = &quot;Range&quot;
  269. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  270. Check:
  271. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  272. If Not [_Super]._IsStillAlive() Then GoTo Finally
  273. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  274. End If
  275. Try:
  276. With com.sun.star.sheet.CellFlags
  277. lClear = 0 _
  278. + .VALUE _
  279. + .DATETIME _
  280. + .STRING _
  281. + .ANNOTATION _
  282. + .FORMULA _
  283. + .HARDATTR _
  284. + .STYLES _
  285. + .OBJECTS _
  286. + .EDITATTR _
  287. + .FORMATTED
  288. Set oRange = _ParseAddress(Range)
  289. oRange.XCellRange.clearContents(lClear)
  290. End With
  291. Finally:
  292. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  293. Exit Sub
  294. Catch:
  295. GoTo Finally
  296. End Sub &apos; SF_Documents.SF_Calc.ClearAll
  297. REM -----------------------------------------------------------------------------
  298. Public Sub ClearFormats(Optional ByVal Range As Variant) As String
  299. &apos;&apos;&apos; Clear all the formatting elements of the given range
  300. &apos;&apos;&apos; Args:
  301. &apos;&apos;&apos; Range : the cell or the range as a string that should be cleared
  302. &apos;&apos;&apos; Examples:
  303. &apos;&apos;&apos; oDoc.ClearFormats(&quot;SheetX:A1:E100&quot;) &apos; Clear the formats of the given range
  304. Dim lClear As Long &apos; The elements to clear
  305. Dim oRange As Object &apos; Alias of Range
  306. Const cstThisSub = &quot;SFDocuments.Calc.ClearFormats&quot;
  307. Const cstSubArgs = &quot;Range&quot;
  308. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  309. Check:
  310. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  311. If Not [_Super]._IsStillAlive() Then GoTo Finally
  312. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  313. End If
  314. Try:
  315. With com.sun.star.sheet.CellFlags
  316. lClear = 0 _
  317. + .HARDATTR _
  318. + .STYLES _
  319. + .EDITATTR _
  320. + .FORMATTED
  321. Set oRange = _ParseAddress(Range)
  322. oRange.XCellRange.clearContents(lClear)
  323. End With
  324. Finally:
  325. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  326. Exit Sub
  327. Catch:
  328. GoTo Finally
  329. End Sub &apos; SF_Documents.SF_Calc.ClearFormats
  330. REM -----------------------------------------------------------------------------
  331. Public Sub ClearValues(Optional ByVal Range As Variant) As String
  332. &apos;&apos;&apos; Clear values and formulas in the given range
  333. &apos;&apos;&apos; Args:
  334. &apos;&apos;&apos; Range : the cell or the range as a string that should be cleared
  335. &apos;&apos;&apos; Examples:
  336. &apos;&apos;&apos; oDoc.ClearValues(&quot;SheetX:*&quot;) &apos; Clears the used area of the sheet
  337. Dim lClear As Long &apos; The elements to clear
  338. Dim oRange As Object &apos; Alias of Range
  339. Const cstThisSub = &quot;SFDocuments.Calc.ClearValues&quot;
  340. Const cstSubArgs = &quot;Range&quot;
  341. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  342. Check:
  343. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  344. If Not [_Super]._IsStillAlive() Then GoTo Finally
  345. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  346. End If
  347. Try:
  348. With com.sun.star.sheet.CellFlags
  349. lClear = 0 _
  350. + .VALUE _
  351. + .DATETIME _
  352. + .STRING _
  353. + .FORMULA
  354. Set oRange = _ParseAddress(Range)
  355. oRange.XCellRange.clearContents(lClear)
  356. End With
  357. Finally:
  358. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  359. Exit Sub
  360. Catch:
  361. GoTo Finally
  362. End Sub &apos; SF_Documents.SF_Calc.ClearValues
  363. REM -----------------------------------------------------------------------------
  364. Public Function CopySheet(Optional ByVal SheetName As Variant _
  365. , Optional ByVal NewName As Variant _
  366. , Optional ByVal BeforeSheet As Variant _
  367. ) As Boolean
  368. &apos;&apos;&apos; Copy a specified sheet before an existing sheet or at the end of the list of sheets
  369. &apos;&apos;&apos; The sheet to copy may be inside any open Calc document
  370. &apos;&apos;&apos; Args:
  371. &apos;&apos;&apos; SheetName: The name of the sheet to copy or its reference
  372. &apos;&apos;&apos; NewName: Must not exist
  373. &apos;&apos;&apos; BeforeSheet: The name (string) or index (numeric, starting from 1) of the sheet before which to insert
  374. &apos;&apos;&apos; Returns:
  375. &apos;&apos;&apos; True if the sheet could be copied successfully
  376. &apos;&apos;&apos; Exceptions:
  377. &apos;&apos;&apos; DUPLICATESHEETERROR A sheet with the given name exists already
  378. &apos;&apos;&apos; Examples:
  379. &apos;&apos;&apos; oDoc.CopySheet(&quot;SheetX&quot;, &quot;SheetY&quot;)
  380. &apos;&apos;&apos; &apos; Copy within the same document
  381. &apos;&apos;&apos; Dim oDocA As Object : Set oDocA = ui.OpenDocument(&quot;C:\Temp\FileA.ods&quot;, Hidden := True, ReadOnly := True)
  382. &apos;&apos;&apos; Dim oDocB As Object : Set oDocB = ui.OpenDocument(&quot;C:\Temp\FileB.ods&quot;)
  383. &apos;&apos;&apos; oDocB.CopySheet(oDocA.Sheet(&quot;SheetX&quot;), &quot;SheetY&quot;)
  384. &apos;&apos;&apos; &apos; Copy from 1 file to another and put the new sheet at the end
  385. Dim bCopy As Boolean &apos; Return value
  386. Dim oSheets As Object &apos; com.sun.star.sheet.XSpreadsheets
  387. Dim vSheets As Variant &apos; List of existing sheets
  388. Dim lSheetIndex As Long &apos; Index of a sheet
  389. Dim oSheet As Object &apos; Alias of SheetName as reference
  390. Dim lRandom As Long &apos; Output of random number generator
  391. Dim sRandom &apos; Random sheet name
  392. Const cstThisSub = &quot;SFDocuments.Calc.CopySheet&quot;
  393. Const cstSubArgs = &quot;SheetName, NewName, [BeforeSheet=&quot;&quot;&quot;&quot;]&quot;
  394. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  395. bCopy = False
  396. Check:
  397. If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
  398. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  399. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  400. If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True, , , True) Then GoTo Finally
  401. If Not _ValidateSheet(NewName, &quot;NewName&quot;, True) Then GoTo Finally
  402. If Not _ValidateSheet(BeforeSheet, &quot;BeforeSheet&quot;, , True, , True) Then GoTo Finally
  403. End If
  404. Try:
  405. &apos; Determine the index of the sheet before which to insert the copy
  406. Set oSheets = _Component.getSheets
  407. vSheets = oSheets.getElementNames()
  408. If VarType(BeforeSheet) = V_STRING Then
  409. lSheetIndex = ScriptForge.SF_Array.IndexOf(vSheets, BeforeSheet)
  410. Else
  411. lSheetIndex = BeforeSheet - 1
  412. If lSheetIndex &lt; 0 Then lSheetIndex = 0
  413. If lSheetIndex &gt; UBound(vSheets) Then lSheetIndex = UBound(vSheets) + 1
  414. End If
  415. &apos; Copy sheet inside the same document OR import from another document
  416. If VarType(SheetName) = V_STRING Then
  417. _Component.getSheets.copyByName(SheetName, NewName, lSheetIndex)
  418. Else
  419. Set oSheet = SheetName
  420. With oSheet
  421. &apos; If a sheet with same name as input exists in the target sheet, rename it first with a random name
  422. sRandom = &quot;&quot;
  423. If ScriptForge.SF_Array.Contains(vSheets, .SheetName) Then
  424. lRandom = ScriptForge.SF_Session.ExecuteCalcFunction(&quot;RANDBETWEEN&quot;, 1, 9999999)
  425. sRandom = &quot;SF_&quot; &amp; Right(&quot;0000000&quot; &amp; lRandom, 7)
  426. oSheets.getByName(.SheetName).setName(sRandom)
  427. End If
  428. &apos; Import i.o. Copy
  429. oSheets.importSheet(oSheet.Component, .SheetName, lSheetIndex)
  430. &apos; Rename to new sheet name
  431. oSheets.getByName(.SheetName).setName(NewName)
  432. &apos; Reset random name
  433. If Len(sRandom) &gt; 0 Then oSheets.getByName(srandom).setName(.SheetName)
  434. End With
  435. End If
  436. bCopy = True
  437. Finally:
  438. CopySheet = bCopy
  439. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  440. Exit Function
  441. Catch:
  442. GoTo Finally
  443. CatchDuplicate:
  444. ScriptForge.SF_Exception.RaiseFatal(DUPLICATESHEETERROR, &quot;NewName&quot;, NewName, &quot;Document&quot;, [_Super]._FileIdent())
  445. GoTo Finally
  446. End Function &apos; SFDocuments.SF_Calc.CopySheet
  447. REM -----------------------------------------------------------------------------
  448. Public Function CopySheetFromFile(Optional ByVal FileName As Variant _
  449. , Optional ByVal SheetName As Variant _
  450. , Optional ByVal NewName As Variant _
  451. , Optional ByVal BeforeSheet As Variant _
  452. ) As Boolean
  453. &apos;&apos;&apos; Copy a specified sheet before an existing sheet or at the end of the list of sheets
  454. &apos;&apos;&apos; The sheet to copy is located inside any closed Calc document
  455. &apos;&apos;&apos; Args:
  456. &apos;&apos;&apos; FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
  457. &apos;&apos;&apos; The file must not be protected with a password
  458. &apos;&apos;&apos; SheetName: The name of the sheet to copy or its reference
  459. &apos;&apos;&apos; NewName: Must not exist
  460. &apos;&apos;&apos; BeforeSheet: The name (string) or index (numeric, starting from 1) of the sheet before which to insert
  461. &apos;&apos;&apos; Returns:
  462. &apos;&apos;&apos; True if the sheet could be created
  463. &apos;&apos;&apos; The created sheet is blank when the input file is not a Calc file
  464. &apos;&apos;&apos; The created sheet contains an error message when the input sheet was not found
  465. &apos;&apos;&apos; Exceptions:
  466. &apos;&apos;&apos; DUPLICATESHEETERROR A sheet with the given name exists already
  467. &apos;&apos;&apos; UNKNOWNFILEERROR The input file is unknown
  468. &apos;&apos;&apos; Examples:
  469. &apos;&apos;&apos; oDoc.CopySheetFromFile(&quot;C:\MyFile.ods&quot;, &quot;SheetX&quot;, &quot;SheetY&quot;, 3)
  470. Dim bCopy As Boolean &apos; Return value
  471. Dim oSheet As Object &apos; com.sun.star.sheet.XSpreadsheet
  472. Dim sFileName As String &apos; URL alias of FileName
  473. Dim FSO As Object &apos; SF_FileSystem
  474. Const cstThisSub = &quot;SFDocuments.Calc.CopySheetFromFile&quot;
  475. Const cstSubArgs = &quot;FileName, SheetName, NewName, [BeforeSheet=&quot;&quot;&quot;&quot;]&quot;
  476. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  477. bCopy = False
  478. Check:
  479. If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
  480. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  481. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  482. If Not ScriptForge.SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  483. If Not ScriptForge.SF_Utils._Validate(SheetName, &quot;SheetName&quot;, V_STRING) Then GoTo Finally
  484. If Not _ValidateSheet(NewName, &quot;NewName&quot;, True) Then GoTo Finally
  485. If Not _ValidateSheet(BeforeSheet, &quot;BeforeSheet&quot;, , True, , True) Then GoTo Finally
  486. End If
  487. Try:
  488. Set FSO = ScriptForge.SF_FileSystem
  489. &apos; Does the input file exist ?
  490. If Not FSO.FileExists(FileName) Then GoTo CatchNotExists
  491. sFileName = FSO._ConvertToUrl(FileName)
  492. &apos; Insert a blank new sheet and import sheet from file va link setting and deletion
  493. If Not InsertSheet(Newname, BeforeSheet) Then GoTo Finally
  494. Set oSheet = _Component.getSheets.getByName(NewName)
  495. With oSheet
  496. .link(sFileName,SheetName, &quot;&quot;, &quot;&quot;, com.sun.star.sheet.SheetLinkMode.NORMAL)
  497. .LinkMode = com.sun.star.sheet.SheetLinkMode.NONE
  498. .LinkURL = &quot;&quot;
  499. End With
  500. bCopy = True
  501. Finally:
  502. CopySheetFromFile = bCopy
  503. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  504. Exit Function
  505. Catch:
  506. GoTo Finally
  507. CatchNotExists:
  508. ScriptForge.SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;FileName&quot;, FileName)
  509. GoTo Finally
  510. End Function &apos; SFDocuments.SF_Calc.CopySheetFromFile
  511. REM -----------------------------------------------------------------------------
  512. Public Function CopyToCell(Optional ByVal SourceRange As Variant _
  513. , Optional ByVal DestinationCell As Variant _
  514. ) As String
  515. &apos;&apos;&apos; Copy a specified source range to a destination range or cell
  516. &apos;&apos;&apos; The source range may belong to another open document
  517. &apos;&apos;&apos; The method imitates the behaviour of a Copy/Paste from a range to a single cell
  518. &apos;&apos;&apos; Args:
  519. &apos;&apos;&apos; SourceRange: the source range as a string if it belongs to the same document
  520. &apos;&apos;&apos; or as a reference if it belongs to another open Calc document
  521. &apos;&apos;&apos; DestinationCell: the destination of the copied range of cells, as a string
  522. &apos;&apos;&apos; If given as range, the destination will be reduced to its top-left cell
  523. &apos;&apos;&apos; Returns:
  524. &apos;&apos;&apos; A string representing the modified range of cells
  525. &apos;&apos;&apos; The modified area depends only on the size of the source area
  526. &apos;&apos;&apos; Examples:
  527. &apos;&apos;&apos; oDoc.CopyToCell(&quot;SheetX.A1:F10&quot;, &quot;SheetY.C5&quot;)
  528. &apos;&apos;&apos; &apos; Copy within the same document
  529. &apos;&apos;&apos; Dim oDocA As Object : Set oDocA = ui.OpenDocument(&quot;C:\Temp\FileA.ods&quot;, Hidden := True, ReadOnly := True)
  530. &apos;&apos;&apos; Dim oDocB As Object : Set oDocB = ui.OpenDocument(&quot;C:\Temp\FileB.ods&quot;)
  531. &apos;&apos;&apos; oDocB.CopyToCell(oDocA.Range(&quot;SheetX.A1:F10&quot;), &quot;SheetY.C5&quot;)
  532. &apos;&apos;&apos; &apos; Copy from 1 file to another
  533. Dim sCopy As String &apos; Return value
  534. Dim oSource As Object &apos; Alias of SourceRange to avoid &quot;Object variable not set&quot; run-time error
  535. Dim oSourceAddress As Object &apos; com.sun.star.table.CellRangeAddress
  536. Dim oDestRange As Object &apos; Destination as a range
  537. Dim oDestAddress As Object &apos; com.sun.star.table.CellRangeAddress
  538. Dim oDestCell As Object &apos; com.sun.star.table.CellAddress
  539. Dim oSelect As Object &apos; Current selection in source
  540. Dim oClipboard As Object &apos; com.sun.star.datatransfer.XTransferable
  541. Const cstThisSub = &quot;SFDocuments.Calc.CopyToCell&quot;
  542. Const cstSubArgs = &quot;SourceRange, DestinationCell&quot;
  543. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  544. sCopy = &quot;&quot;
  545. Check:
  546. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  547. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  548. If Not ScriptForge.SF_Utils._Validate(SourceRange, &quot;SourceRange&quot;, Array(V_STRING, ScriptForge.V_OBJECT), , , CALCREFERENCE) Then GoTo Finally
  549. If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
  550. End If
  551. Try:
  552. If VarType(SourceRange) = V_STRING Then &apos; Same document - Use UNO copyRange method
  553. Set oSourceAddress = _ParseAddress(SourceRange).XCellRange.RangeAddress
  554. Set oDestRange = _ParseAddress(DestinationCell)
  555. Set oDestAddress = oDestRange.XCellRange.RangeAddress
  556. Set oDestCell = New com.sun.star.table.CellAddress
  557. With oDestAddress
  558. oDestCell.Sheet = .Sheet
  559. oDestCell.Column = .StartColumn
  560. oDestCell.Row = .StartRow
  561. End With
  562. oDestRange.XSpreadsheet.copyRange(oDestCell, oSourceAddress)
  563. Else &apos; Use clipboard to copy - current selection in Source should be preserved
  564. Set oSource = SourceRange
  565. With oSource
  566. &apos; Keep current selection in source document
  567. Set oSelect = .Component.CurrentController.getSelection()
  568. &apos; Select, copy the source range and paste in the top-left cell of the destination
  569. .Component.CurrentController.select(.XCellRange)
  570. Set oClipboard = .Component.CurrentController.getTransferable()
  571. _Component.CurrentController.select(_Offset(DestinationCell, 0, 0, 1, 1).XCellRange)
  572. _Component.CurrentController.insertTransferable(oClipBoard)
  573. &apos; Restore previous selection in Source
  574. _RestoreSelections(.Component, oSelect)
  575. Set oSourceAddress = .XCellRange.RangeAddress
  576. End With
  577. End If
  578. With oSourceAddress
  579. sCopy = _Offset(DestinationCell, 0, 0, .EndRow - .StartRow + 1, .EndColumn - .StartColumn + 1).RangeName
  580. End With
  581. Finally:
  582. CopyToCell = sCopy
  583. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  584. Exit Function
  585. Catch:
  586. GoTo Finally
  587. End Function &apos; SFDocuments.SF_Calc.CopyToCell
  588. REM -----------------------------------------------------------------------------
  589. Public Function CopyToRange(Optional ByVal SourceRange As Variant _
  590. , Optional ByVal DestinationRange As Variant _
  591. ) As String
  592. &apos;&apos;&apos; Copy downwards and/or rightwards a specified source range to a destination range
  593. &apos;&apos;&apos; The source range may belong to another open document
  594. &apos;&apos;&apos; The method imitates the behaviour of a Copy/Paste from a range to a larger range
  595. &apos;&apos;&apos; If the height (resp. width) of the destination area is &gt; 1 row (resp. column)
  596. &apos;&apos;&apos; then the height (resp. width) of the source must be &lt;= the height (resp. width)
  597. &apos;&apos;&apos; of the destination. Otherwise nothing happens
  598. &apos;&apos;&apos; If the height (resp.width) of the destination is = 1 then the destination
  599. &apos;&apos;&apos; is expanded downwards (resp. rightwards) up to the height (resp. width)
  600. &apos;&apos;&apos; of the source range
  601. &apos;&apos;&apos; Args:
  602. &apos;&apos;&apos; SourceRange: the source range as a string if it belongs to the same document
  603. &apos;&apos;&apos; or as a reference if it belongs to another open Calc document
  604. &apos;&apos;&apos; DestinationRange: the destination of the copied range of cells, as a string
  605. &apos;&apos;&apos; Returns:
  606. &apos;&apos;&apos; A string representing the modified range of cells
  607. &apos;&apos;&apos; Examples:
  608. &apos;&apos;&apos; oDoc.CopyToRange(&quot;SheetX.A1:F10&quot;, &quot;SheetY.C5:J5&quot;)
  609. &apos;&apos;&apos; &apos; Copy within the same document
  610. &apos;&apos;&apos; &apos; Returned range: $SheetY.$C$5:$J$14
  611. &apos;&apos;&apos; Dim oDocA As Object : Set oDocA = ui.OpenDocument(&quot;C:\Temp\FileA.ods&quot;, Hidden := True, ReadOnly := True)
  612. &apos;&apos;&apos; Dim oDocB As Object : Set oDocB = ui.OpenDocument(&quot;C:\Temp\FileB.ods&quot;)
  613. &apos;&apos;&apos; oDocB.CopyToRange(oDocA.Range(&quot;SheetX.A1:F10&quot;), &quot;SheetY.C5:J5&quot;)
  614. &apos;&apos;&apos; &apos; Copy from 1 file to another
  615. Dim sCopy As String &apos; Return value
  616. Dim oSource As Object &apos; Alias of SourceRange to avoid &quot;Object variable not set&quot; run-time error
  617. Dim oDestRange As Object &apos; Destination as a range
  618. Dim oDestCell As Object &apos; com.sun.star.table.CellAddress
  619. Dim oSelect As Object &apos; Current selection in source
  620. Dim oClipboard As Object &apos; com.sun.star.datatransfer.XTransferable
  621. Dim bSameDocument As Boolean &apos; True when source in same document as destination
  622. Dim lHeight As Long &apos; Height of destination
  623. Dim lWidth As Long &apos; Width of destination
  624. Const cstThisSub = &quot;SFDocuments.Calc.CopyToRange&quot;
  625. Const cstSubArgs = &quot;SourceRange, DestinationRange&quot;
  626. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  627. sCopy = &quot;&quot;
  628. Check:
  629. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  630. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  631. If Not ScriptForge.SF_Utils._Validate(SourceRange, &quot;SourceRange&quot;, Array(V_STRING, ScriptForge.V_OBJECT), , , CALCREFERENCE) Then GoTo Finally
  632. If Not ScriptForge.SF_Utils._Validate(DestinationRange, &quot;DestinationRange&quot;, V_STRING) Then GoTo Finally
  633. End If
  634. Try:
  635. &apos; Copy done via clipboard
  636. &apos; Check Height/Width destination = 1 or &gt; Height/Width of source
  637. bSameDocument = ( VarType(SourceRange) = V_STRING )
  638. If bSameDocument Then Set oSource = _ParseAddress(SourceRange) Else Set oSource = SourceRange
  639. Set oDestRange = _ParseAddress(DestinationRange)
  640. With oDestRange
  641. lHeight = .Height
  642. lWidth = .Width
  643. If lHeight = 1 Then
  644. lHeight = oSource.Height &apos; Future height
  645. ElseIf lHeight &lt; oSource.Height Then
  646. GoTo Finally
  647. End If
  648. If lWidth = 1 Then
  649. lWidth = oSource.Width &apos; Future width
  650. ElseIf lWidth &lt; oSource.Width Then
  651. GoTo Finally
  652. End If
  653. End With
  654. With oSource
  655. &apos; Store actual selection in source
  656. Set oSelect = .Component.CurrentController.getSelection()
  657. &apos; Select, copy the source range and paste in the destination
  658. .Component.CurrentController.select(.XCellRange)
  659. Set oClipboard = .Component.CurrentController.getTransferable()
  660. _Component.CurrentController.select(oDestRange.XCellRange)
  661. _Component.CurrentController.insertTransferable(oClipBoard)
  662. &apos; Restore selection in source
  663. _RestoreSelections(.Component, oSelect)
  664. End With
  665. sCopy = _Offset(oDestRange, 0, 0, lHeight, lWidth).RangeName
  666. Finally:
  667. CopyToRange = sCopy
  668. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  669. Exit Function
  670. Catch:
  671. GoTo Finally
  672. End Function &apos; SFDocuments.SF_Calc.CopyToRange
  673. REM -----------------------------------------------------------------------------
  674. Public Function DAvg(Optional ByVal Range As Variant) As Double
  675. &apos;&apos;&apos; Get the average of the numeric values stored in the given range
  676. &apos;&apos;&apos; Args:
  677. &apos;&apos;&apos; Range : the range as a string where to get the values from
  678. &apos;&apos;&apos; Returns:
  679. &apos;&apos;&apos; The average of the numeric values as a double
  680. &apos;&apos;&apos; Examples:
  681. &apos;&apos;&apos; Val = oDoc.DAvg(&quot;~.A1:A1000&quot;)
  682. Try:
  683. DAvg = _DFunction(&quot;DAvg&quot;, Range)
  684. Finally:
  685. Exit Function
  686. End Function &apos; SF_Documents.SF_Calc.DAvg
  687. REM -----------------------------------------------------------------------------
  688. Public Function DCount(Optional ByVal Range As Variant) As Long
  689. &apos;&apos;&apos; Get the number of numeric values stored in the given range
  690. &apos;&apos;&apos; Args:
  691. &apos;&apos;&apos; Range : the range as a string where to get the values from
  692. &apos;&apos;&apos; Returns:
  693. &apos;&apos;&apos; The number of numeric values a Long
  694. &apos;&apos;&apos; Examples:
  695. &apos;&apos;&apos; Val = oDoc.DCount(&quot;~.A1:A1000&quot;)
  696. Try:
  697. DCount = _DFunction(&quot;DCount&quot;, Range)
  698. Finally:
  699. Exit Function
  700. End Function &apos; SF_Documents.SF_Calc.DCount
  701. REM -----------------------------------------------------------------------------
  702. Public Function DMax(Optional ByVal Range As Variant) As Double
  703. &apos;&apos;&apos; Get the greatest of the numeric values stored in the given range
  704. &apos;&apos;&apos; Args:
  705. &apos;&apos;&apos; Range : the range as a string where to get the values from
  706. &apos;&apos;&apos; Returns:
  707. &apos;&apos;&apos; The greatest of the numeric values as a double
  708. &apos;&apos;&apos; Examples:
  709. &apos;&apos;&apos; Val = oDoc.DMax(&quot;~.A1:A1000&quot;)
  710. Try:
  711. DMax = _DFunction(&quot;DMax&quot;, Range)
  712. Finally:
  713. Exit Function
  714. End Function &apos; SF_Documents.SF_Calc.DMax
  715. REM -----------------------------------------------------------------------------
  716. Public Function DMin(Optional ByVal Range As Variant) As Double
  717. &apos;&apos;&apos; Get the smallest of the numeric values stored in the given range
  718. &apos;&apos;&apos; Args:
  719. &apos;&apos;&apos; Range : the range as a string where to get the values from
  720. &apos;&apos;&apos; Returns:
  721. &apos;&apos;&apos; The smallest of the numeric values as a double
  722. &apos;&apos;&apos; Examples:
  723. &apos;&apos;&apos; Val = oDoc.DMin(&quot;~.A1:A1000&quot;)
  724. Try:
  725. DMin = _DFunction(&quot;DMin&quot;, Range)
  726. Finally:
  727. Exit Function
  728. End Function &apos; SF_Documents.SF_Calc.DMin
  729. REM -----------------------------------------------------------------------------
  730. Public Function DSum(Optional ByVal Range As Variant) As Double
  731. &apos;&apos;&apos; Get sum of the numeric values stored in the given range
  732. &apos;&apos;&apos; Args:
  733. &apos;&apos;&apos; Range : the range as a string where to get the values from
  734. &apos;&apos;&apos; Returns:
  735. &apos;&apos;&apos; The sum of the numeric values as a double
  736. &apos;&apos;&apos; Examples:
  737. &apos;&apos;&apos; Val = oDoc.DSum(&quot;~.A1:A1000&quot;)
  738. Try:
  739. DSum = _DFunction(&quot;DSum&quot;, Range)
  740. Finally:
  741. Exit Function
  742. End Function &apos; SF_Documents.SF_Calc.DSum
  743. REM -----------------------------------------------------------------------------
  744. Function GetColumnName(Optional ByVal ColumnNumber As Variant) As String
  745. &apos;&apos;&apos; Convert a column number (range 1, 2,..1024) into its letter counterpart (range &apos;A&apos;, &apos;B&apos;,..&apos;AMJ&apos;).
  746. &apos;&apos;&apos; Args:
  747. &apos;&apos;&apos; ColumnNumber: the column number, must be in the interval 1 ... 1024
  748. &apos;&apos;&apos; Returns:
  749. &apos;&apos;&apos; a string representation of the column name, in range &apos;A&apos;..&apos;AMJ&apos;
  750. &apos;&apos;&apos; If ColumnNumber is not in the allowed range, returns a zero-length string
  751. &apos;&apos;&apos; Example:
  752. &apos;&apos;&apos; MsgBox oDoc.GetColumnName(1022) &apos; &quot;AMH&quot;
  753. &apos;&apos;&apos; Adapted from a Python function by sundar nataraj
  754. &apos;&apos;&apos; http://stackoverflow.com/questions/23861680/convert-spreadsheet-number-to-column-letter
  755. Dim sCol As String &apos; Return value
  756. Const cstThisSub = &quot;SFDocuments.Calc.GetColumnName&quot;
  757. Const cstSubArgs = &quot;ColumnNumber&quot;
  758. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  759. sCol = &quot;&quot;
  760. Check:
  761. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  762. If Not SF_Utils._Validate(ColumnNumber, &quot;ColumnNumber&quot;, V_NUMERIC) Then GoTo Finally
  763. End If
  764. Try:
  765. If (ColumnNumber &gt; 0) And (ColumnNumber &lt;= MAXCOLS) Then sCol = _GetColumnName(ColumnNumber)
  766. Finally:
  767. GetColumnName = sCol
  768. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  769. Exit Function
  770. Catch:
  771. GoTo Finally
  772. End Function &apos; SFDocuments.SF_Calc.GetColumnName
  773. REM -----------------------------------------------------------------------------
  774. Public Function GetFormula(Optional ByVal Range As Variant) As Variant
  775. &apos;&apos;&apos; Get the formula(e) stored in the given range of cells
  776. &apos;&apos;&apos; Args:
  777. &apos;&apos;&apos; Range : the range as a string where to get the formula from
  778. &apos;&apos;&apos; Returns:
  779. &apos;&apos;&apos; A scalar, a zero-based 1D array or a zero-based 2D array of strings
  780. &apos;&apos;&apos; Examples:
  781. &apos;&apos;&apos; Val = oDoc.GetFormula(&quot;~.A1:A1000&quot;)
  782. Dim vGet As Variant &apos; Return value
  783. Dim oAddress As Object &apos; Alias of Range
  784. Dim vDataArray As Variant &apos; DataArray compatible with .DataArray UNO property
  785. Const cstThisSub = &quot;SFDocuments.Calc.GetFormula&quot;
  786. Const cstSubArgs = &quot;Range&quot;
  787. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  788. vGet = Empty
  789. Check:
  790. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  791. If Not [_Super]._IsStillAlive() Then GoTo Finally
  792. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  793. End If
  794. Try:
  795. &apos; Get the data
  796. Set oAddress = _ParseAddress(Range)
  797. vDataArray = oAddress.XCellRange.getFormulaArray()
  798. &apos; Convert the data array to scalar, vector or array
  799. vGet = _ConvertFromDataArray(vDataArray)
  800. Finally:
  801. GetFormula = vGet
  802. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  803. Exit Function
  804. Catch:
  805. GoTo Finally
  806. End Function &apos; SF_Documents.SF_Calc.GetFormula
  807. REM -----------------------------------------------------------------------------
  808. Public Function GetProperty(Optional ByVal PropertyName As Variant _
  809. , Optional ObjectName As Variant _
  810. ) As Variant
  811. &apos;&apos;&apos; Return the actual value of the given property
  812. &apos;&apos;&apos; Args:
  813. &apos;&apos;&apos; PropertyName: the name of the property as a string
  814. &apos;&apos;&apos; ObjectName: a sheet or range name
  815. &apos;&apos;&apos; Returns:
  816. &apos;&apos;&apos; The actual value of the property
  817. &apos;&apos;&apos; Exceptions:
  818. &apos;&apos;&apos; ARGUMENTERROR The property does not exist
  819. Const cstThisSub = &quot;SFDocuments.Calc.GetProperty&quot;
  820. Const cstSubArgs = &quot;&quot;
  821. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  822. GetProperty = Null
  823. Check:
  824. If IsMissing(ObjectName) Or IsEMpty(ObjectName) Then ObjectName = &quot;&quot;
  825. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  826. If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  827. If Not ScriptForge.SF_Utils._Validate(ObjectName, &quot;ObjectName&quot;, V_STRING) Then GoTo Catch
  828. End If
  829. Try:
  830. &apos; Superclass or subclass property ?
  831. If ScriptForge.SF_Array.Contains([_Super].Properties(), PropertyName) Then
  832. GetProperty = [_Super].GetProperty(PropertyName)
  833. Else
  834. GetProperty = _PropertyGet(PropertyName)
  835. End If
  836. Finally:
  837. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  838. Exit Function
  839. Catch:
  840. GoTo Finally
  841. End Function &apos; SFDocuments.SF_Calc.GetProperty
  842. REM -----------------------------------------------------------------------------
  843. Public Function GetValue(Optional ByVal Range As Variant) As Variant
  844. &apos;&apos;&apos; Get the value(s) stored in the given range of cells
  845. &apos;&apos;&apos; Args:
  846. &apos;&apos;&apos; Range : the range as a string where to get the value from
  847. &apos;&apos;&apos; Returns:
  848. &apos;&apos;&apos; A scalar, a zero-based 1D array or a zero-based 2D array of strings and doubles
  849. &apos;&apos;&apos; To convert doubles to dates, use the CDate builtin function
  850. &apos;&apos;&apos; Examples:
  851. &apos;&apos;&apos; Val = oDoc.GetValue(&quot;~.A1:A1000&quot;)
  852. Dim vGet As Variant &apos; Return value
  853. Dim oAddress As Object &apos; Alias of Range
  854. Dim vDataArray As Variant &apos; DataArray compatible with .DataArray UNO property
  855. Const cstThisSub = &quot;SFDocuments.Calc.GetValue&quot;
  856. Const cstSubArgs = &quot;Range&quot;
  857. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  858. vGet = Empty
  859. Check:
  860. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  861. If Not [_Super]._IsStillAlive() Then GoTo Finally
  862. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  863. End If
  864. Try:
  865. &apos; Get the data
  866. Set oAddress = _ParseAddress(Range)
  867. vDataArray = oAddress.XCellRange.getDataArray()
  868. &apos; Convert the data array to scalar, vector or array
  869. vGet = _ConvertFromDataArray(vDataArray)
  870. Finally:
  871. GetValue = vGet
  872. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  873. Exit Function
  874. Catch:
  875. GoTo Finally
  876. End Function &apos; SF_Documents.SF_Calc.GetValue
  877. REM -----------------------------------------------------------------------------
  878. Public Function ImportFromCSVFile(Optional ByVal FileName As Variant _
  879. , Optional ByVal DestinationCell As Variant _
  880. , Optional ByVal FilterOptions As Variant _
  881. ) As String
  882. &apos;&apos;&apos; Import the content of a CSV-formatted text file starting from a given cell
  883. &apos;&apos;&apos; Beforehand the destination area will be cleared from any content and format
  884. &apos;&apos;&apos; Args:
  885. &apos;&apos;&apos; FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
  886. &apos;&apos;&apos; DestinationCell: the destination of the copied range of cells, as a string
  887. &apos;&apos;&apos; If given as range, the destination will be reduced to its top-left cell
  888. &apos;&apos;&apos; FilterOptions: The arguments of the CSV input filter.
  889. &apos;&apos;&apos; Read https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_Options#Filter_Options_for_the_CSV_Filter
  890. &apos;&apos;&apos; Default: input file encoding is UTF8
  891. &apos;&apos;&apos; separator = comma, semi-colon or tabulation
  892. &apos;&apos;&apos; string delimiter = double quote
  893. &apos;&apos;&apos; all lines are included
  894. &apos;&apos;&apos; quoted strings are formatted as texts
  895. &apos;&apos;&apos; special numbers are detected
  896. &apos;&apos;&apos; all columns are presumed texts
  897. &apos;&apos;&apos; language = english/US =&gt; decimal separator is &quot;.&quot;, thousands separator = &quot;,&quot;
  898. &apos;&apos;&apos; Returns:
  899. &apos;&apos;&apos; A string representing the modified range of cells
  900. &apos;&apos;&apos; The modified area depends only on the content of the source file
  901. &apos;&apos;&apos; Exceptions:
  902. &apos;&apos;&apos; DOCUMENTOPENERROR The csv file could not be opened
  903. &apos;&apos;&apos; Examples:
  904. &apos;&apos;&apos; oDoc.ImportFromCSVFile(&quot;C:\Temp\myCsvFile.csv&quot;, &quot;SheetY.C5&quot;)
  905. Dim sImport As String &apos; Return value
  906. Dim oUI As Object &apos; UI service
  907. Dim oSource As Object &apos; New Calc document with csv loaded
  908. Dim oSelect As Object &apos; Current selection in destination
  909. Const cstFilter = &quot;Text - txt - csv (StarCalc)&quot;
  910. Const cstFilterOptions = &quot;9/44/59/MRG,34,76,1,,1033,true,true&quot;
  911. Const cstThisSub = &quot;SFDocuments.Calc.ImportFromCSVFile&quot;
  912. Const cstSubArgs = &quot;FileName, DestinationCell, [FilterOptions]=&quot;&quot;9/44/59/MRG,34,76,1,,1033,true,true&quot;&quot;&quot;
  913. &apos; If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  914. sImport = &quot;&quot;
  915. Check:
  916. If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = cstFilterOptions
  917. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  918. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  919. If Not ScriptForge.SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  920. If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
  921. End If
  922. Try:
  923. &apos; Input file is loaded in an empty worksheet. Data are copied to destination cell
  924. Set oUI = CreateScriptService(&quot;UI&quot;)
  925. Set oSource = oUI.OpenDocument(FileName _
  926. , ReadOnly := True _
  927. , Hidden := True _
  928. , FilterName := cstFilter _
  929. , FilterOptions := FilterOptions _
  930. )
  931. &apos; Remember current selection and restore it after copy
  932. Set oSelect = _Component.CurrentController.getSelection()
  933. sImport = CopyToCell(oSource.Range(&quot;*&quot;), DestinationCell)
  934. _RestoreSelections(_Component, oSelect)
  935. Finally:
  936. If Not IsNull(oSource) Then oSource.CloseDocument(False)
  937. ImportFromCSVFile = sImport
  938. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  939. Exit Function
  940. Catch:
  941. GoTo Finally
  942. End Function &apos; SFDocuments.SF_Calc.ImportFromCSVFile
  943. REM -----------------------------------------------------------------------------
  944. Public Sub ImportFromDatabase(Optional ByVal FileName As Variant _
  945. , Optional ByVal RegistrationName As Variant _
  946. , Optional ByVal DestinationCell As Variant _
  947. , Optional ByVal SQLCommand As Variant _
  948. , Optional ByVal DirectSQL As Variant _
  949. )
  950. &apos;&apos;&apos; Import the content of a database table, query or resultset, i.e. the result of a SELECT SQL command,
  951. &apos;&apos;&apos; starting from a given cell
  952. &apos;&apos;&apos; Beforehand the destination area will be cleared from any content and format
  953. &apos;&apos;&apos; The modified area depends only on the content of the source data
  954. &apos;&apos;&apos; Args:
  955. &apos;&apos;&apos; FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
  956. &apos;&apos;&apos; RegistrationName: the name of a registered database
  957. &apos;&apos;&apos; It is ignored if FileName &lt;&gt; &quot;&quot;
  958. &apos;&apos;&apos; DestinationCell: the destination of the copied range of cells, as a string
  959. &apos;&apos;&apos; If given as range, the destination will be reduced to its top-left cell
  960. &apos;&apos;&apos; SQLCommand: either a table or query name (without square brackets)
  961. &apos;&apos;&apos; or a full SQL commands where table and fieldnames are preferably surrounded with square brackets
  962. &apos;&apos;&apos; Returns:
  963. &apos;&apos;&apos; Implemented as a Sub because the doImport UNO method does not return any error
  964. &apos;&apos;&apos; Exceptions:
  965. &apos;&apos;&apos; BASEDOCUMENTOPENERROR The database file could not be opened
  966. &apos;&apos;&apos; Examples:
  967. &apos;&apos;&apos; oDoc.ImportFromDatabase(&quot;C:\Temp\myDbFile.odb&quot;, , &quot;SheetY.C5&quot;, &quot;SELECT * FROM [Employees] ORDER BY [LastName]&quot;)
  968. Dim oDBContext As Object &apos; com.sun.star.sdb.DatabaseContext
  969. Dim oDatabase As Object &apos; SFDatabases.Database service
  970. Dim lCommandType As Long &apos; A com.sun.star.sheet.DataImportMode.xxx constant
  971. Dim oQuery As Object &apos; com.sun.star.ucb.XContent
  972. Dim bDirect As Boolean &apos; Alias of DirectSQL
  973. Dim oDestRange As Object &apos; Destination as a range
  974. Dim oDestAddress As Object &apos; com.sun.star.table.CellRangeAddress
  975. Dim oDestCell As Object &apos; com.sun.star.table.XCell
  976. Dim oSelect As Object &apos; Current selection in destination
  977. Dim vImportOptions As Variant &apos; Array of PropertyValues
  978. Const cstThisSub = &quot;SFDocuments.Calc.ImportFromDatabase&quot;
  979. Const cstSubArgs = &quot;[FileName=&quot;&quot;&quot;&quot;], [RegistrationName=&quot;&quot;&quot;&quot;], DestinationCell, SQLCommand, [DirectSQL=False]&quot;
  980. &apos; If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  981. Check:
  982. If IsMissing(FileName) Or IsEmpty(FileName) Then FileName = &quot;&quot;
  983. If IsMissing(RegistrationName) Or IsEmpty(RegistrationName) Then RegistrationName = &quot;&quot;
  984. If IsMissing(DirectSQL) Or IsEmpty(DirectSQL) Then DirectSQL = False
  985. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  986. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  987. If Not ScriptForge.SF_Utils._ValidateFile(FileName, &quot;FileName&quot;, , True) Then GoTo Finally
  988. If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
  989. If Not ScriptForge.SF_Utils._Validate(SQLCommand, &quot;SQLCommand&quot;, V_STRING) Then GoTo Finally
  990. If Not ScriptForge.SF_Utils._Validate(DirectSQL, &quot;DirectSQL&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  991. End If
  992. &apos; Check the existence of FileName
  993. If Len(FileName) = 0 Then &apos; FileName has precedence over RegistrationName
  994. If Len(RegistrationName) = 0 Then GoTo CatchError
  995. Set oDBContext = ScriptForge.SF_Utils._GetUNOService(&quot;DatabaseContext&quot;)
  996. If Not oDBContext.hasRegisteredDatabase(RegistrationName) Then GoTo CatchError
  997. FileName = ScriptForge.SF_FileSystem._ConvertFromUrl(oDBContext.getDatabaseLocation(RegistrationName))
  998. End If
  999. If Not ScriptForge.SF_FileSystem.FileExists(FileName) Then GoTo CatchError
  1000. Try:
  1001. &apos; Check command type
  1002. Set oDatabase = ScriptForge.SF_Services.CreateScriptService(&quot;SFDatabases.Database&quot;, FileName, , True) &apos; Read-only
  1003. If IsNull(oDatabase) Then GoTo CatchError
  1004. With oDatabase
  1005. If ScriptForge.SF_Array.Contains(.Tables, SQLCommand) Then
  1006. bDirect = True
  1007. lCommandType = com.sun.star.sheet.DataImportMode.TABLE
  1008. ElseIf ScriptForge.SF_Array.Contains(.Queries, SQLCommand) Then
  1009. Set oQuery = .XConnection.Queries.getByName(SQLCommand)
  1010. bDirect = Not oQuery.EscapeProcessing
  1011. lCommandType = com.sun.star.sheet.DataImportMode.QUERY
  1012. Else
  1013. bDirect = DirectSQL
  1014. lCommandType = com.sun.star.sheet.DataImportMode.SQL
  1015. SQLCommand = ._ReplaceSquareBrackets(SQLCommand)
  1016. End If
  1017. .CloseDatabase()
  1018. Set oDatabase = oDatabase.Dispose()
  1019. End With
  1020. &apos; Determine the destination cell as the top-left coordinates of the given range
  1021. Set oDestRange = _ParseAddress(DestinationCell)
  1022. Set oDestAddress = oDestRange.XCellRange.RangeAddress
  1023. Set oDestCell = oDestRange.XSpreadsheet.getCellByPosition(oDestAddress.StartColumn, oDestAddress.StartRow)
  1024. &apos; Remember current selection
  1025. Set oSelect = _Component.CurrentController.getSelection()
  1026. &apos; Import arguments
  1027. vImportOptions = Array(_
  1028. ScriptForge.SF_Utils._MakePropertyValue(&quot;DatabaseName&quot;, ScriptForge.SF_FileSystem._ConvertToUrl(FileName)) _
  1029. , ScriptForge.SF_Utils._MakePropertyValue(&quot;SourceObject&quot;, SQLCommand) _
  1030. , ScriptForge.SF_Utils._MakePropertyValue(&quot;SourceType&quot;, lCommandType) _
  1031. , ScriptForge.SF_Utils._MakePropertyValue(&quot;IsNative&quot;, bDirect) _
  1032. )
  1033. oDestCell.doImport(vImportOptions)
  1034. &apos; Restore selection after import_
  1035. _RestoreSelections(_Component, oSelect)
  1036. Finally:
  1037. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1038. Exit Sub
  1039. Catch:
  1040. GoTo Finally
  1041. CatchError:
  1042. SF_Exception.RaiseFatal(BASEDOCUMENTOPENERROR, &quot;FileName&quot;, FileName, &quot;RegistrationName&quot;, RegistrationName)
  1043. GoTo Finally
  1044. End Sub &apos; SFDocuments.SF_Calc.ImportFromDatabase
  1045. REM -----------------------------------------------------------------------------
  1046. Public Function InsertSheet(Optional ByVal SheetName As Variant _
  1047. , Optional ByVal BeforeSheet As Variant _
  1048. ) As Boolean
  1049. &apos;&apos;&apos; Insert a new empty sheet before an existing sheet or at the end of the list of sheets
  1050. &apos;&apos;&apos; Args:
  1051. &apos;&apos;&apos; SheetName: The name of the new sheet
  1052. &apos;&apos;&apos; BeforeSheet: The name (string) or index (numeric, starting from 1) of the sheet before which to insert
  1053. &apos;&apos;&apos; Returns:
  1054. &apos;&apos;&apos; True if the sheet could be inserted successfully
  1055. &apos;&apos;&apos; Examples:
  1056. &apos;&apos;&apos; oDoc.InsertSheet(&quot;SheetX&quot;, &quot;SheetY&quot;)
  1057. Dim bInsert As Boolean &apos; Return value
  1058. Dim vSheets As Variant &apos; List of existing sheets
  1059. Dim lSheetIndex As Long &apos; Index of a sheet
  1060. Const cstThisSub = &quot;SFDocuments.Calc.InsertSheet&quot;
  1061. Const cstSubArgs = &quot;SheetName, [BeforeSheet=&quot;&quot;&quot;&quot;]&quot;
  1062. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1063. bInsert = False
  1064. Check:
  1065. If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
  1066. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1067. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  1068. If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, True) Then GoTo Finally
  1069. If Not _ValidateSheet(BeforeSheet, &quot;BeforeSheet&quot;, , True, , True) Then GoTo Finally
  1070. End If
  1071. vSheets = _Component.getSheets.getElementNames()
  1072. Try:
  1073. If VarType(BeforeSheet) = V_STRING Then
  1074. lSheetIndex = ScriptForge.SF_Array.IndexOf(vSheets, BeforeSheet)
  1075. Else
  1076. lSheetIndex = BeforeSheet - 1
  1077. If lSheetIndex &lt; 0 Then lSheetIndex = 0
  1078. If lSheetIndex &gt; UBound(vSheets) Then lSheetIndex = UBound(vSheets) + 1
  1079. End If
  1080. _Component.getSheets.insertNewByName(SheetName, lSheetIndex)
  1081. bInsert = True
  1082. Finally:
  1083. InsertSheet = binsert
  1084. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1085. Exit Function
  1086. Catch:
  1087. GoTo Finally
  1088. End Function &apos; SFDocuments.SF_Calc.InsertSheet
  1089. REM -----------------------------------------------------------------------------
  1090. Public Function Methods() As Variant
  1091. &apos;&apos;&apos; Return the list of public methods of the Model service as an array
  1092. Methods = Array( _
  1093. &quot;Activate&quot; _
  1094. , &quot;ClearAll&quot; _
  1095. , &quot;ClearFormats&quot; _
  1096. , &quot;ClearValues&quot; _
  1097. , &quot;CloseDocument&quot; _
  1098. , &quot;CopySheet&quot; _
  1099. , &quot;CopySheetFromFile&quot; _
  1100. , &quot;CopyToCell&quot; _
  1101. , &quot;CopyToRange&quot; _
  1102. , &quot;DAvg&quot; _
  1103. , &quot;DCount&quot; _
  1104. , &quot;DMax&quot; _
  1105. , &quot;DMin&quot; _
  1106. , &quot;DSum&quot; _
  1107. , &quot;GetColumnName&quot; _
  1108. , &quot;GetFormula&quot; _
  1109. , &quot;GetValue&quot; _
  1110. , &quot;ImportFromCSVFile&quot; _
  1111. , &quot;ImportFromDatabase&quot; _
  1112. , &quot;InsertSheet&quot; _
  1113. , &quot;MoveRange&quot; _
  1114. , &quot;MoveSheet&quot; _
  1115. , &quot;Offset&quot; _
  1116. , &quot;RemoveSheet&quot; _
  1117. , &quot;RenameSheet&quot; _
  1118. , &quot;RunCommand&quot; _
  1119. , &quot;Save&quot; _
  1120. , &quot;SaveAs&quot; _
  1121. , &quot;SaveCopyAs&quot; _
  1122. , &quot;SetArray&quot; _
  1123. , &quot;SetCellStyle&quot; _
  1124. , &quot;SetFormula&quot; _
  1125. , &quot;SetValue&quot; _
  1126. , &quot;SortRange&quot; _
  1127. )
  1128. End Function &apos; SFDocuments.SF_Calc.Methods
  1129. REM -----------------------------------------------------------------------------
  1130. Public Function MoveRange(Optional ByVal Source As Variant _
  1131. , Optional ByVal Destination As Variant _
  1132. ) As String
  1133. &apos;&apos;&apos; Move a specified source range to a destination range
  1134. &apos;&apos;&apos; Args:
  1135. &apos;&apos;&apos; Source: the source range of cells as a string
  1136. &apos;&apos;&apos; Destination: the destination of the moved range of cells, as a string
  1137. &apos;&apos;&apos; Returns:
  1138. &apos;&apos;&apos; A string representing the modified range of cells
  1139. &apos;&apos;&apos; The modified area depends only on the size of the source area
  1140. &apos;&apos;&apos; Examples:
  1141. &apos;&apos;&apos; oDoc.MoveRange(&quot;SheetX.A1:F10&quot;, &quot;SheetY.C5&quot;)
  1142. Dim sMove As String &apos; Return value
  1143. Dim oSource As Object &apos; Alias of Source to avoid &quot;Object variable not set&quot; run-time error
  1144. Dim oSourceAddress As Object &apos; com.sun.star.table.CellRangeAddress
  1145. Dim oDestRange As Object &apos; Destination as a range
  1146. Dim oDestAddress As Object &apos; com.sun.star.table.CellRangeAddress
  1147. Dim oDestCell As Object &apos; com.sun.star.table.CellAddress
  1148. Dim oSelect As Object &apos; Current selection in source
  1149. Dim oClipboard As Object &apos; com.sun.star.datatransfer.XTransferable
  1150. Dim oCellRanges As Object &apos; com.sun.star.sheet.SheetCellRanges
  1151. Dim vRangeAddresses As Variant &apos; Array of com.sun.star.table.CellRangeAddress
  1152. Dim i As Long
  1153. Const cstThisSub = &quot;SFDocuments.Calc.MoveRange&quot;
  1154. Const cstSubArgs = &quot;Source, Destination&quot;
  1155. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1156. sMove = &quot;&quot;
  1157. Check:
  1158. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1159. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  1160. If Not _Validate(Source, &quot;Source&quot;, V_STRING) Then GoTo Finally
  1161. If Not _Validate(Destination, &quot;Destination&quot;, V_STRING) Then GoTo Finally
  1162. End If
  1163. Try:
  1164. Set oSourceAddress = _ParseAddress(Source).XCellRange.RangeAddress
  1165. Set oDestRange = _ParseAddress(Destination)
  1166. Set oDestAddress = oDestRange.XCellRange.RangeAddress
  1167. Set oDestCell = New com.sun.star.table.CellAddress
  1168. With oDestAddress
  1169. oDestCell.Sheet = .Sheet
  1170. oDestCell.Column = .StartColumn
  1171. oDestCell.Row = .StartRow
  1172. End With
  1173. oDestRange.XSpreadsheet.moveRange(oDestCell, oSourceAddress)
  1174. With oSourceAddress
  1175. sMove = _Offset(Destination, 0, 0, .EndRow - .StartRow + 1, .EndColumn - .StartColumn + 1).RangeName
  1176. End With
  1177. Finally:
  1178. MoveRange = sMove
  1179. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1180. Exit Function
  1181. Catch:
  1182. GoTo Finally
  1183. End Function &apos; SFDocuments.SF_Calc.MoveRange
  1184. REM -----------------------------------------------------------------------------
  1185. Public Function MoveSheet(Optional ByVal SheetName As Variant _
  1186. , Optional ByVal BeforeSheet As Variant _
  1187. ) As Boolean
  1188. &apos;&apos;&apos; Move a sheet before an existing sheet or at the end of the list of sheets
  1189. &apos;&apos;&apos; Args:
  1190. &apos;&apos;&apos; SheetName: The name of the sheet to move
  1191. &apos;&apos;&apos; BeforeSheet: The name (string) or index (numeric, starting from 1) of the sheet before which to move the sheet
  1192. &apos;&apos;&apos; Returns:
  1193. &apos;&apos;&apos; True if the sheet could be moved successfully
  1194. &apos;&apos;&apos; Examples:
  1195. &apos;&apos;&apos; oDoc.MoveSheet(&quot;SheetX&quot;, &quot;SheetY&quot;)
  1196. Dim bMove As Boolean &apos; Return value
  1197. Dim vSheets As Variant &apos; List of existing sheets
  1198. Dim lSheetIndex As Long &apos; Index of a sheet
  1199. Const cstThisSub = &quot;SFDocuments.Calc.MoveSheet&quot;
  1200. Const cstSubArgs = &quot;SheetName, [BeforeSheet=&quot;&quot;&quot;&quot;]&quot;
  1201. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1202. bMove = False
  1203. Check:
  1204. If IsMissing(BeforeSheet) Or IsEmpty(BeforeSheet) Then BeforeSheet = 32768
  1205. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1206. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  1207. If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) Then GoTo Finally
  1208. If Not _ValidateSheet(BeforeSheet, &quot;BeforeSheet&quot;, , True, , True) Then GoTo Finally
  1209. End If
  1210. vSheets = _Component.getSheets.getElementNames()
  1211. Try:
  1212. If VarType(BeforeSheet) = V_STRING Then
  1213. lSheetIndex = ScriptForge.SF_Array.IndexOf(vSheets, BeforeSheet)
  1214. Else
  1215. lSheetIndex = BeforeSheet - 1
  1216. If lSheetIndex &lt; 0 Then lSheetIndex = 0
  1217. If lSheetIndex &gt; UBound(vSheets) Then lSheetIndex = UBound(vSheets) + 1
  1218. End If
  1219. _Component.getSheets.MoveByName(SheetName, lSheetIndex)
  1220. bMove = True
  1221. Finally:
  1222. MoveSheet = bMove
  1223. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1224. Exit Function
  1225. Catch:
  1226. GoTo Finally
  1227. End Function &apos; SFDocuments.SF_Calc.MoveSheet
  1228. REM -----------------------------------------------------------------------------
  1229. Public Function Offset(Optional ByRef Range As Variant _
  1230. , Optional ByVal Rows As Variant _
  1231. , Optional ByVal Columns As Variant _
  1232. , Optional ByVal Height As Variant _
  1233. , Optional ByVal Width As Variant _
  1234. ) As String
  1235. &apos;&apos;&apos; Returns a new range offset by a certain number of rows and columns from a given range
  1236. &apos;&apos;&apos; Args:
  1237. &apos;&apos;&apos; Range : the range, as a string, from which the function searches for the new range
  1238. &apos;&apos;&apos; Rows : the number of rows by which the reference was corrected up (negative value) or down.
  1239. &apos;&apos;&apos; Use 0 (default) to stay in the same row.
  1240. &apos;&apos;&apos; Columns : the number of columns by which the reference was corrected to the left (negative value) or to the right.
  1241. &apos;&apos;&apos; Use 0 (default) to stay in the same column
  1242. &apos;&apos;&apos; Height : the vertical height for an area that starts at the new reference position.
  1243. &apos;&apos;&apos; Default = no vertical resizing
  1244. &apos;&apos;&apos; Width : the horizontal width for an area that starts at the new reference position.
  1245. &apos;&apos;&apos; Default - no horizontal resizing
  1246. &apos;&apos;&apos; Arguments Rows and Columns must not lead to zero or negative start row or column.
  1247. &apos;&apos;&apos; Arguments Height and Width must not lead to zero or negative count of rows or columns.
  1248. &apos;&apos;&apos; Returns:
  1249. &apos;&apos;&apos; A new range as a string
  1250. &apos;&apos;&apos; Exceptions:
  1251. &apos;&apos;&apos; OFFSETADDRESSERROR The computed range of cells falls beyond the sheet boundaries
  1252. &apos;&apos;&apos; Examples:
  1253. &apos;&apos;&apos; oDoc.Offset(&quot;A1&quot;, 2, 2) &apos; &quot;&apos;SheetX&apos;.$C$3&quot; (A1 moved by two rows and two columns down)
  1254. &apos;&apos;&apos; oDoc.Offset(&quot;A1&quot;, 2, 2, 5, 6) &apos; &quot;&apos;SheetX&apos;.$C$3:$H$7&quot;
  1255. Dim sOffset As String &apos; Return value
  1256. Dim oAddress As Object &apos; Alias of Range
  1257. Const cstThisSub = &quot;SFDocuments.Calc.Offset&quot;
  1258. Const cstSubArgs = &quot;Range, [Rows=0], [Columns=0], [Height], [Width]&quot;
  1259. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1260. sOffset = &quot;&quot;
  1261. Check:
  1262. If IsMissing(Rows) Or IsEmpty(Rows) Then Rows = 0
  1263. If IsMissing(Columns) Or IsEmpty(Columns) Then Columns = 0
  1264. If IsMissing(Height) Or IsEmpty(Height) Then Height = 0
  1265. If IsMissing(Width) Or IsEmpty(Width) Then Width = 0
  1266. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1267. If Not [_Super]._IsStillAlive() Then GoTo Finally
  1268. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  1269. If Not ScriptForge.SF_Utils._Validate(Rows, &quot;Rows&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1270. If Not ScriptForge.SF_Utils._Validate(Columns, &quot;Columns&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1271. If Not ScriptForge.SF_Utils._Validate(Height, &quot;Height&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1272. If Not ScriptForge.SF_Utils._Validate(Width, &quot;Width&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1273. End If
  1274. Try:
  1275. &apos; Define the new range string
  1276. Set oAddress = _Offset(Range, Rows, Columns, Height, Width)
  1277. sOffset = oAddress.RangeName
  1278. Finally:
  1279. Offset = sOffset
  1280. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1281. Exit Function
  1282. Catch:
  1283. GoTo Finally
  1284. End Function &apos; SF_Documents.SF_Calc.Offset
  1285. REM -----------------------------------------------------------------------------
  1286. Public Function Properties() As Variant
  1287. &apos;&apos;&apos; Return the list or properties of the Timer class as an array
  1288. Properties = Array( _
  1289. &quot;CurrentSelection&quot; _
  1290. , &quot;CustomProperties&quot; _
  1291. , &quot;Description&quot; _
  1292. , &quot;DocumentProperties&quot; _
  1293. , &quot;DocumentType&quot; _
  1294. , &quot;Height&quot; _
  1295. , &quot;IsBase&quot; _
  1296. , &quot;IsCalc&quot; _
  1297. , &quot;IsDraw &quot; _
  1298. , &quot;IsImpress&quot; _
  1299. , &quot;IsMath&quot; _
  1300. , &quot;IsWriter&quot; _
  1301. , &quot;Keywords&quot; _
  1302. , &quot;LastCell&quot; _
  1303. , &quot;LastColumn&quot; _
  1304. , &quot;LastRow&quot; _
  1305. , &quot;Range&quot; _
  1306. , &quot;Readonly&quot; _
  1307. , &quot;Sheet&quot; _
  1308. , &quot;Sheets&quot; _
  1309. , &quot;Subject&quot; _
  1310. , &quot;Title&quot; _
  1311. , &quot;Width&quot; _
  1312. , &quot;XCellRange&quot; _
  1313. , &quot;XComponent&quot; _
  1314. , &quot;XSpreadsheet&quot; _
  1315. )
  1316. End Function &apos; SFDocuments.SF_Calc.Properties
  1317. REM -----------------------------------------------------------------------------
  1318. Public Function RemoveSheet(Optional ByVal SheetName As Variant) As Boolean
  1319. &apos;&apos;&apos; Remove an existing sheet from the document
  1320. &apos;&apos;&apos; Args:
  1321. &apos;&apos;&apos; SheetName: The name of the sheet to remove
  1322. &apos;&apos;&apos; Returns:
  1323. &apos;&apos;&apos; True if the sheet could be removed successfully
  1324. &apos;&apos;&apos; Examples:
  1325. &apos;&apos;&apos; oDoc.RemoveSheet(&quot;SheetX&quot;)
  1326. Dim bRemove As Boolean &apos; Return value
  1327. Const cstThisSub = &quot;SFDocuments.Calc.RemoveSheet&quot;
  1328. Const cstSubArgs = &quot;SheetName&quot;
  1329. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1330. bRemove = False
  1331. Check:
  1332. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1333. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  1334. If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) Then GoTo Finally
  1335. End If
  1336. Try:
  1337. _Component.getSheets.RemoveByName(SheetName)
  1338. bRemove = True
  1339. Finally:
  1340. RemoveSheet = bRemove
  1341. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1342. Exit Function
  1343. Catch:
  1344. GoTo Finally
  1345. End Function &apos; SFDocuments.SF_Calc.RemoveSheet
  1346. REM -----------------------------------------------------------------------------
  1347. Public Function RenameSheet(Optional ByVal SheetName As Variant _
  1348. , Optional ByVal NewName As Variant _
  1349. ) As Boolean
  1350. &apos;&apos;&apos; Rename a specified sheet
  1351. &apos;&apos;&apos; Args:
  1352. &apos;&apos;&apos; SheetName: The name of the sheet to rename
  1353. &apos;&apos;&apos; NewName: Must not exist
  1354. &apos;&apos;&apos; Returns:
  1355. &apos;&apos;&apos; True if the sheet could be renamed successfully
  1356. &apos;&apos;&apos; Exceptions:
  1357. &apos;&apos;&apos; DUPLICATESHEETERROR A sheet with the given name exists already
  1358. &apos;&apos;&apos; Examples:
  1359. &apos;&apos;&apos; oDoc.RenameSheet(&quot;SheetX&quot;, &quot;SheetY&quot;)
  1360. Dim bRename As Boolean &apos; Return value
  1361. Const cstThisSub = &quot;SFDocuments.Calc.RenameSheet&quot;
  1362. Const cstSubArgs = &quot;SheetName, NewName&quot;
  1363. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1364. bRename = False
  1365. Check:
  1366. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1367. If Not [_Super]._IsStillAlive(True) Then GoTo Finally
  1368. If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) Then GoTo Finally
  1369. If Not _ValidateSheet(NewName, &quot;NewName&quot;, True) Then GoTo Finally
  1370. End If
  1371. Try:
  1372. _Component.getSheets.getByName(SheetName).setName(NewName)
  1373. bRename = True
  1374. Finally:
  1375. RenameSheet = bRename
  1376. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1377. Exit Function
  1378. Catch:
  1379. GoTo Finally
  1380. End Function &apos; SFDocuments.SF_Calc.RenameSheet
  1381. REM -----------------------------------------------------------------------------
  1382. Public Function SetArray(Optional ByVal TargetCell As Variant _
  1383. , Optional ByRef Value As Variant _
  1384. ) As String
  1385. &apos;&apos;&apos; Set the given (array of) values starting from the target cell
  1386. &apos;&apos;&apos; The updated area expands itself from the target cell or from the top-left corner of the given range
  1387. &apos;&apos;&apos; as far as determined by the size of the input Value.
  1388. &apos;&apos;&apos; Vectors are always expanded vertically
  1389. &apos;&apos;&apos; Args:
  1390. &apos;&apos;&apos; TargetCell : the cell or the range as a string that should receive a new value
  1391. &apos;&apos;&apos; Value: a scalar, a vector or an array with the new values
  1392. &apos;&apos;&apos; The new values should be strings, numeric values or dates. Other types empty the corresponding cell
  1393. &apos;&apos;&apos; Returns:
  1394. &apos;&apos;&apos; A string representing the updated range
  1395. &apos;&apos;&apos; Exceptions:
  1396. &apos;&apos;&apos; OFFSETADDRESSERROR The computed range of cells falls beyond the sheet boundaries
  1397. &apos;&apos;&apos; Examples:
  1398. &apos;&apos;&apos; oDoc.SetArray(&quot;SheetX.A1&quot;, SF_Array.RangeInit(1, 1000))
  1399. Dim sSet As String &apos; Return value
  1400. Dim oSet As Object &apos; _Address alias of sSet
  1401. Dim vDataArray As Variant &apos; DataArray compatible with .DataArray UNO property
  1402. Const cstThisSub = &quot;SFDocuments.Calc.SetArray&quot;
  1403. Const cstSubArgs = &quot;TargetCell, Value&quot;
  1404. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1405. sSet = &quot;&quot;
  1406. Check:
  1407. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1408. If Not [_Super]._IsStillAlive() Then GoTo Finally
  1409. If Not ScriptForge.SF_Utils._Validate(TargetCell, &quot;TargetCell&quot;, V_STRING) Then GoTo Finally
  1410. If IsArray(Value) Then
  1411. If Not ScriptForge.SF_Utils._ValidateArray(Value, &quot;Value&quot;) Then GoTo Finally
  1412. Else
  1413. If Not ScriptForge.SF_Utils._Validate(Value, &quot;Value&quot;) Then GoTo Finally
  1414. End If
  1415. End If
  1416. Try:
  1417. &apos; Convert argument to data array and derive new range from its size
  1418. vDataArray = _ConvertToDataArray(Value)
  1419. If UBound(vDataArray) &lt; LBound(vDataArray) Then GoTo Finally
  1420. Set oSet = _Offset(TargetCell, 0, 0, plHeight := UBound(vDataArray) + 1, plWidth := UBound(vDataArray(0)) + 1) &apos; +1 : vDataArray is zero-based
  1421. With oSet
  1422. .XCellRange.setDataArray(vDataArray)
  1423. sSet = .RangeName
  1424. End With
  1425. Finally:
  1426. SetArray = sSet
  1427. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1428. Exit Function
  1429. Catch:
  1430. GoTo Finally
  1431. End Function &apos; SF_Documents.SF_Calc.SetArray
  1432. REM -----------------------------------------------------------------------------
  1433. Public Function SetCellStyle(Optional ByVal TargetRange As Variant _
  1434. , Optional ByVal Style As Variant _
  1435. ) As String
  1436. &apos;&apos;&apos; Apply the given cell style in the given range
  1437. &apos;&apos;&apos; The full range is updated and the remainder of the sheet is left untouched
  1438. &apos;&apos;&apos; If the cell style does not exist, an error is raised
  1439. &apos;&apos;&apos; Args:
  1440. &apos;&apos;&apos; TargetRange : the range as a string that should receive a new cell style
  1441. &apos;&apos;&apos; Style: the style name as a string
  1442. &apos;&apos;&apos; Returns:
  1443. &apos;&apos;&apos; A string representing the updated range
  1444. &apos;&apos;&apos; Examples:
  1445. &apos;&apos;&apos; oDoc.SetCellStyle(&quot;A1:F1&quot;, &quot;Heading 2&quot;)
  1446. Dim sSet As String &apos; Return value
  1447. Dim oAddress As _Address &apos; Alias of TargetRange
  1448. Dim oStyleFamilies As Object &apos; com.sun.star.container.XNameAccess
  1449. Dim vStyles As Variant &apos; Array of existing cell styles
  1450. Const cstStyle = &quot;CellStyles&quot;
  1451. Const cstThisSub = &quot;SFDocuments.Calc.SetCellStyle&quot;
  1452. Const cstSubArgs = &quot;TargetRange, Style&quot;
  1453. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1454. sSet = &quot;&quot;
  1455. Check:
  1456. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1457. If Not [_Super]._IsStillAlive() Then GoTo Finally
  1458. If Not ScriptForge.SF_Utils._Validate(TargetRange, &quot;TargetRange&quot;, V_STRING) Then GoTo Finally
  1459. Set oStyleFamilies = _Component.StyleFamilies
  1460. If oStyleFamilies.hasByName(cstStyle) Then vStyles = oStyleFamilies.getByName(cstStyle).getElementNames() Else vStyles = Array()
  1461. If Not ScriptForge.SF_Utils._Validate(Style, &quot;Style&quot;, V_STRING, vStyles) Then GoTo Finally
  1462. End If
  1463. Try:
  1464. Set oAddress = _ParseAddress(TargetRange)
  1465. With oAddress
  1466. .XCellRange.CellStyle = Style
  1467. sSet = .RangeName
  1468. End With
  1469. Finally:
  1470. SetCellStyle = sSet
  1471. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1472. Exit Function
  1473. Catch:
  1474. GoTo Finally
  1475. End Function &apos; SF_Documents.SF_Calc.SetCellStyle
  1476. REM -----------------------------------------------------------------------------
  1477. Public Function SetFormula(Optional ByVal TargetRange As Variant _
  1478. , Optional ByRef Formula As Variant _
  1479. ) As String
  1480. &apos;&apos;&apos; Set the given (array of) formulae in the given range
  1481. &apos;&apos;&apos; The full range is updated and the remainder of the sheet is left untouched
  1482. &apos;&apos;&apos; If the given formula is a string:
  1483. &apos;&apos;&apos; the unique formula is pasted across the whole range with adjustment of the relative references
  1484. &apos;&apos;&apos; Otherwise
  1485. &apos;&apos;&apos; If the size of Formula &lt; the size of Range, then the other cells are emptied
  1486. &apos;&apos;&apos; If the size of Formula &gt; the size of Range, then Formula is only partially copied
  1487. &apos;&apos;&apos; Vectors are always expanded vertically, except if the range has a height of exactly 1 row
  1488. &apos;&apos;&apos; Args:
  1489. &apos;&apos;&apos; TargetRange : the range as a string that should receive a new Formula
  1490. &apos;&apos;&apos; Formula: a scalar, a vector or an array with the new formula(e) as strings for each cell of the range.
  1491. &apos;&apos;&apos; Returns:
  1492. &apos;&apos;&apos; A string representing the updated range
  1493. &apos;&apos;&apos; Examples:
  1494. &apos;&apos;&apos; oDoc.SetFormula(&quot;A1&quot;, &quot;=A2&quot;)
  1495. &apos;&apos;&apos; oDoc.SetFormula(&quot;A1:F1&quot;, Array(&quot;=A2&quot;, &quot;=B2&quot;, &quot;=C2+10&quot;)) &apos; Horizontal vector, partially empty
  1496. &apos;&apos;&apos; oDoc.SetFormula(&quot;A1:D2&quot;, &quot;=E1&quot;) &apos; D2 contains the formula &quot;=H2&quot;
  1497. Dim sSet As String &apos; Return value
  1498. Dim oAddress As Object &apos; Alias of TargetRange
  1499. Dim vDataArray As Variant &apos; DataArray compatible with .DataArray UNO property
  1500. Const cstThisSub = &quot;SFDocuments.Calc.SetFormula&quot;
  1501. Const cstSubArgs = &quot;TargetRange, Formula&quot;
  1502. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1503. sSet = &quot;&quot;
  1504. Check:
  1505. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1506. If Not [_Super]._IsStillAlive() Then GoTo Finally
  1507. If Not ScriptForge.SF_Utils._Validate(TargetRange, &quot;TargetRange&quot;, V_STRING) Then GoTo Finally
  1508. If IsArray(Formula) Then
  1509. If Not ScriptForge.SF_Utils._ValidateArray(Formula, &quot;Formula&quot;, 0, V_STRING) Then GoTo Finally
  1510. Else
  1511. If Not ScriptForge.SF_Utils._Validate(Formula, &quot;Formula&quot;, V_STRING) Then GoTo Finally
  1512. End If
  1513. End If
  1514. Try:
  1515. Set oAddress = _ParseAddress(TargetRange)
  1516. With oAddress
  1517. If IsArray(Formula) Then
  1518. &apos; Convert to data array and limit its size to the size of the initial range
  1519. vDataArray = _ConvertToDataArray(Formula, .Height - 1, .Width - 1)
  1520. If UBound(vDataArray) &lt; LBound(vDataArray) Then GoTo Finally
  1521. .XCellRange.setFormulaArray(vDataArray)
  1522. Else
  1523. With .XCellRange
  1524. &apos; Store formula in top-left cell and paste it along the whole range
  1525. .getCellByPosition(0, 0).setFormula(Formula)
  1526. .fillSeries(com.sun.star.sheet.FillDirection.TO_BOTTOM, com.sun.star.sheet.FillMode.SIMPLE, 0, 0, 0)
  1527. .fillSeries(com.sun.star.sheet.FillDirection.TO_RIGHT, com.sun.star.sheet.FillMode.SIMPLE, 0, 0, 0)
  1528. End With
  1529. End If
  1530. sSet = .RangeName
  1531. End With
  1532. Finally:
  1533. SetFormula = sSet
  1534. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1535. Exit Function
  1536. Catch:
  1537. GoTo Finally
  1538. End Function &apos; SF_Documents.SF_Calc.SetFormula
  1539. REM -----------------------------------------------------------------------------
  1540. Private Function SetProperty(Optional ByVal psProperty As String _
  1541. , Optional ByVal pvValue As Variant _
  1542. ) As Boolean
  1543. &apos;&apos;&apos; Set the new value of the named property
  1544. &apos;&apos;&apos; Args:
  1545. &apos;&apos;&apos; psProperty: the name of the property
  1546. &apos;&apos;&apos; pvValue: the new value of the given property
  1547. &apos;&apos;&apos; Returns:
  1548. &apos;&apos;&apos; True if successful
  1549. Dim bSet As Boolean &apos; Return value
  1550. Static oSession As Object &apos; Alias of SF_Session
  1551. Dim cstThisSub As String
  1552. Const cstSubArgs = &quot;Value&quot;
  1553. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1554. bSet = False
  1555. cstThisSub = &quot;SFDocuments.Calc.set&quot; &amp; psProperty
  1556. If IsMissing(pvValue) Then pvValue = Empty
  1557. &apos;ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) &apos; Validation done in Property Lets
  1558. If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
  1559. bSet = True
  1560. Select Case UCase(psProperty)
  1561. Case UCase(&quot;CurrentSelection&quot;)
  1562. CurrentSelection = pvValue
  1563. Case UCase(&quot;CustomProperties&quot;)
  1564. CustomProperties = pvValue
  1565. Case UCase(&quot;Description&quot;)
  1566. Description = pvValue
  1567. Case UCase(&quot;Keywords&quot;)
  1568. Keywords = pvValue
  1569. Case UCase(&quot;Subject&quot;)
  1570. Subject = pvValue
  1571. Case UCase(&quot;Title&quot;)
  1572. Title = pvValue
  1573. Case Else
  1574. bSet = False
  1575. End Select
  1576. Finally:
  1577. SetProperty = bSet
  1578. &apos;ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1579. Exit Function
  1580. Catch:
  1581. GoTo Finally
  1582. End Function &apos; SFDocuments.SF_Calc.SetProperty
  1583. REM -----------------------------------------------------------------------------
  1584. Public Function SetValue(Optional ByVal TargetRange As Variant _
  1585. , Optional ByRef Value As Variant _
  1586. ) As String
  1587. &apos;&apos;&apos; Set the given value in the given range
  1588. &apos;&apos;&apos; The full range is updated and the remainder of the sheet is left untouched
  1589. &apos;&apos;&apos; If the size of Value &lt; the size of Range, then the other cells are emptied
  1590. &apos;&apos;&apos; If the size of Value &gt; the size of Range, then Value is only partially copied
  1591. &apos;&apos;&apos; Vectors are always expanded vertically, except if the range has a height of exactly 1 row
  1592. &apos;&apos;&apos; Args:
  1593. &apos;&apos;&apos; TargetRange : the range as a string that should receive a new value
  1594. &apos;&apos;&apos; Value: a scalar, a vector or an array with the new values for each cell of the range.
  1595. &apos;&apos;&apos; The new values should be strings, numeric values or dates. Other types empty the corresponding cell
  1596. &apos;&apos;&apos; Returns:
  1597. &apos;&apos;&apos; A string representing the updated range
  1598. &apos;&apos;&apos; Examples:
  1599. &apos;&apos;&apos; oDoc.SetValue(&quot;A1&quot;, 2)
  1600. &apos;&apos;&apos; oDoc.SetValue(&quot;A1:F1&quot;, Array(1, 2, 3)) &apos; Horizontal vector, partially empty
  1601. &apos;&apos;&apos; oDoc.SetValue(&quot;A1:D2&quot;, SF_Array.AppendRow(Array(1, 2, 3, 4), Array(5, 6, 7, 8)))
  1602. Dim sSet As String &apos; Return value
  1603. Dim oAddress As Object &apos; Alias of TargetRange
  1604. Dim vDataArray As Variant &apos; DataArray compatible with .DataArray UNO property
  1605. Const cstThisSub = &quot;SFDocuments.Calc.SetValue&quot;
  1606. Const cstSubArgs = &quot;TargetRange, Value&quot;
  1607. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1608. sSet = &quot;&quot;
  1609. Check:
  1610. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1611. If Not [_Super]._IsStillAlive() Then GoTo Finally
  1612. If Not ScriptForge.SF_Utils._Validate(TargetRange, &quot;TargetRange&quot;, V_STRING) Then GoTo Finally
  1613. If IsArray(Value) Then
  1614. If Not ScriptForge.SF_Utils._ValidateArray(Value, &quot;Value&quot;) Then GoTo Finally
  1615. Else
  1616. If Not ScriptForge.SF_Utils._Validate(Value, &quot;Value&quot;) Then GoTo Finally
  1617. End If
  1618. End If
  1619. Try:
  1620. Set oAddress = _ParseAddress(TargetRange)
  1621. With oAddress
  1622. &apos; Convert to data array and limit its size to the size of the initial range
  1623. vDataArray = _ConvertToDataArray(Value, .Height - 1, .Width - 1)
  1624. If UBound(vDataArray) &lt; LBound(vDataArray) Then GoTo Finally
  1625. .XCellRange.setDataArray(vDataArray)
  1626. sSet = .RangeName
  1627. End With
  1628. Finally:
  1629. SetValue = sSet
  1630. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1631. Exit Function
  1632. Catch:
  1633. GoTo Finally
  1634. End Function &apos; SF_Documents.SF_Calc.SetValue
  1635. REM -----------------------------------------------------------------------------
  1636. Public Function SortRange(Optional ByVal Range As Variant _
  1637. , Optional ByVal SortKeys As Variant _
  1638. , Optional ByVal SortOrder As Variant _
  1639. , Optional ByVal DestinationCell As Variant _
  1640. , Optional ByVal ContainsHeader As Variant _
  1641. , Optional ByVal CaseSensitive As Variant _
  1642. , Optional ByVal SortColumns As Variant _
  1643. ) As Variant
  1644. &apos;&apos;&apos; Sort the given range on maximum 3 columns/rows. The sorting order may vary by column/row
  1645. &apos;&apos;&apos; Args:
  1646. &apos;&apos;&apos; Range: the range to sort as a string
  1647. &apos;&apos;&apos; SortKeys: a scalar (if 1 column/row) or an array of column/row numbers starting from 1
  1648. &apos;&apos;&apos; SortOrder: a scalar or an array of strings: &quot;ASC&quot; or &quot;DESC&quot;
  1649. &apos;&apos;&apos; Each item is paired with the corresponding item in SortKeys
  1650. &apos;&apos;&apos; If the SortOrder array is shorter than SortKeys, the remaining keys are sorted
  1651. &apos;&apos;&apos; in ascending order
  1652. &apos;&apos;&apos; DestinationCell: the destination of the sorted range of cells, as a string
  1653. &apos;&apos;&apos; If given as range, the destination will be reduced to its top-left cell
  1654. &apos;&apos;&apos; By default, Range is overwritten with its sorted content
  1655. &apos;&apos;&apos; ContainsHeader: when True, the first row/column is not sorted
  1656. &apos;&apos;&apos; CaseSensitive: only for string comparisons, default = False
  1657. &apos;&apos;&apos; SortColumns: when True, the columns are sorted from left to right
  1658. &apos;&apos;&apos; Default = False: rows are sorted from top to bottom.
  1659. &apos;&apos;&apos; Returns:
  1660. &apos;&apos;&apos; The modified range of cells as a string
  1661. &apos;&apos;&apos; Example:
  1662. &apos;&apos;&apos; oDoc.SortRange(&quot;A2:J200&quot;, Array(1, 3), , Array(&quot;ASC&quot;, &quot;DESC&quot;), CaseSensitive := True)
  1663. &apos;&apos;&apos; &apos; Sort on columns A (ascending) and C (descending)
  1664. Dim sSort As String &apos; Return value
  1665. Dim oRangeAddress As _Address &apos; Parsed range
  1666. Dim oRange As Object &apos; com.sun.star.table.XCellRange
  1667. Dim oDestRange As Object &apos; Destination as a range
  1668. Dim oDestAddress As Object &apos; com.sun.star.table.CellRangeAddress
  1669. Dim oDestCell As Object &apos; com.sun.star.table.CellAddress
  1670. Dim vSortDescriptor As Variant &apos; Array of com.sun.star.beans.PropertyValue
  1671. Dim vSortFields As Variant &apos; Array of com.sun.star.table.TableSortField
  1672. Dim sOrder As String &apos; Item in SortOrder
  1673. Dim i As Long
  1674. Const cstThisSub = &quot;SFDocuments.Calc.SortRange&quot;
  1675. Const cstSubArgs = &quot;Range, SortKeys, [TargetRange=&quot;&quot;&quot;&quot;], [SortOrder=&quot;&quot;ASC&quot;&quot;], [ContainsHeader=False], [CaseSensitive=False], [SortColumns=False]&quot;
  1676. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1677. sSort = &quot;&quot;
  1678. Check:
  1679. If IsMissing(SortKeys) Or IsEmpty(SortKeys) Then
  1680. SortKeys = Array(1)
  1681. ElseIf Not IsArray(SortKeys) Then
  1682. SortKeys = Array(SortKeys)
  1683. End If
  1684. If IsMissing(DestinationCell) Or IsEmpty(DestinationCell) Then DestinationCell = &quot;&quot;
  1685. If IsMissing(SortOrder) Or IsEmpty(SortOrder) Then
  1686. SortOrder = Array(&quot;ASC&quot;)
  1687. ElseIf Not IsArray(SortOrder) Then
  1688. SortOrder = Array(SortOrder)
  1689. End If
  1690. If IsMissing(ContainsHeader) Or IsEmpty(ContainsHeader) Then ContainsHeader = False
  1691. If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
  1692. If IsMissing(SortColumns) Or IsEmpty(SortColumns) Then SortColumns = False
  1693. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1694. If Not [_Super]._IsStillAlive() Then GoTo Finally
  1695. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  1696. If Not ScriptForge.SF_Utils._ValidateArray(SortKeys, &quot;SortKeys&quot;, 1, V_NUMERIC, True) Then GoTo Finally
  1697. If Not ScriptForge.SF_Utils._Validate(DestinationCell, &quot;DestinationCell&quot;, V_STRING) Then GoTo Finally
  1698. If Not ScriptForge.SF_Utils._ValidateArray(SortOrder, &quot;SortOrder&quot;, 1, V_STRING, True) Then GoTo Finally
  1699. If Not ScriptForge.SF_Utils._Validate(ContainsHeader, &quot;ContainsHeader&quot;, V_BOOLEAN) Then GoTo Finally
  1700. If Not ScriptForge.SF_Utils._Validate(CaseSensitive, &quot;CaseSensitive&quot;, V_BOOLEAN) Then GoTo Finally
  1701. If Not ScriptForge.SF_Utils._Validate(SortColumns, &quot;SortColumns&quot;, V_BOOLEAN) Then GoTo Finally
  1702. End If
  1703. Set oRangeAddress = _ParseAddress(Range)
  1704. If Len(DestinationCell) &gt; 0 Then Set oDestRange = _ParseAddress(DestinationCell)
  1705. Try:
  1706. &apos; Initialize the sort descriptor
  1707. Set oRange = oRangeAddress.XCellRange
  1708. vSortDescriptor = oRange.createSortDescriptor
  1709. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;IsSortColumns&quot;, SortColumns)
  1710. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;ContainsHeader&quot;, ContainsHeader)
  1711. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;BindFormatsToContent&quot;, True)
  1712. If Len(DestinationCell) = 0 Then
  1713. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;CopyOutputData&quot;, False)
  1714. Else
  1715. Set oDestAddress = oDestRange.XCellRange.RangeAddress
  1716. Set oDestCell = New com.sun.star.table.CellAddress
  1717. With oDestAddress
  1718. oDestCell.Sheet = .Sheet
  1719. oDestCell.Column = .StartColumn
  1720. oDestCell.Row = .StartRow
  1721. End With
  1722. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;CopyOutputData&quot;, true)
  1723. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;OutputPosition&quot;, oDestCell)
  1724. End If
  1725. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;IsUserListEnabled&quot;, False)
  1726. &apos; Define the sorting keys
  1727. vSortFields = Array()
  1728. ReDim vSortFields(0 To UBound(SortKeys))
  1729. For i = 0 To UBound(SortKeys)
  1730. vSortFields(i) = New com.sun.star.table.TableSortField
  1731. If i &gt; UBound(SortOrder) Then sOrder = &quot;&quot; Else sOrder = SortOrder(i)
  1732. If Len(sOrder) = 0 Then sOrder = &quot;ASC&quot;
  1733. With vSortFields(i)
  1734. .Field = SortKeys(i) - 1
  1735. .IsAscending = ( UCase(sOrder) = &quot;ASC&quot; )
  1736. .IsCaseSensitive = CaseSensitive
  1737. End With
  1738. Next i
  1739. &apos; Associate the keys and the descriptor, and sort
  1740. ScriptForge.SF_Utils._SetPropertyValue(vSortDescriptor, &quot;SortFields&quot;, vSortFields)
  1741. oRange.sort(vSortDescriptor)
  1742. &apos; Compute the changed area
  1743. If Len(DestinationCell) = 0 Then
  1744. sSort = oRangeAddress.RangeName
  1745. Else
  1746. With oRangeAddress
  1747. sSort = _Offset(oDestRange, 0, 0, .Height, .Width).RangeName
  1748. End With
  1749. End If
  1750. Finally:
  1751. SortRange = sSort
  1752. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1753. Exit Function
  1754. Catch:
  1755. GoTo Finally
  1756. End Function &apos; SF_Documents.SF_Calc.SortRange
  1757. REM ======================================================= SUPERCLASS PROPERTIES
  1758. REM -----------------------------------------------------------------------------
  1759. Property Get CustomProperties() As Variant
  1760. CustomProperties = [_Super].GetProperty(&quot;CustomProperties&quot;)
  1761. End Property &apos; SFDocuments.SF_Calc.CustomProperties
  1762. REM -----------------------------------------------------------------------------
  1763. Property Let CustomProperties(Optional ByVal pvCustomProperties As Variant)
  1764. [_Super].CustomProperties = pvCustomProperties
  1765. End Property &apos; SFDocuments.SF_Calc.CustomProperties
  1766. REM -----------------------------------------------------------------------------
  1767. Property Get Description() As Variant
  1768. Description = [_Super].GetProperty(&quot;Description&quot;)
  1769. End Property &apos; SFDocuments.SF_Calc.Description
  1770. REM -----------------------------------------------------------------------------
  1771. Property Let Description(Optional ByVal pvDescription As Variant)
  1772. [_Super].Description = pvDescription
  1773. End Property &apos; SFDocuments.SF_Calc.Description
  1774. REM -----------------------------------------------------------------------------
  1775. Property Get DocumentProperties() As Variant
  1776. DocumentProperties = [_Super].GetProperty(&quot;DocumentProperties&quot;)
  1777. End Property &apos; SFDocuments.SF_Calc.DocumentProperties
  1778. REM -----------------------------------------------------------------------------
  1779. Property Get DocumentType() As String
  1780. DocumentType = [_Super].GetProperty(&quot;DocumentType&quot;)
  1781. End Property &apos; SFDocuments.SF_Calc.DocumentType
  1782. REM -----------------------------------------------------------------------------
  1783. Property Get IsBase() As Boolean
  1784. IsBase = [_Super].GetProperty(&quot;IsBase&quot;)
  1785. End Property &apos; SFDocuments.SF_Calc.IsBase
  1786. REM -----------------------------------------------------------------------------
  1787. Property Get IsCalc() As Boolean
  1788. IsCalc = [_Super].GetProperty(&quot;IsCalc&quot;)
  1789. End Property &apos; SFDocuments.SF_Calc.IsCalc
  1790. REM -----------------------------------------------------------------------------
  1791. Property Get IsDraw() As Boolean
  1792. IsDraw = [_Super].GetProperty(&quot;IsDraw&quot;)
  1793. End Property &apos; SFDocuments.SF_Calc.IsDraw
  1794. REM -----------------------------------------------------------------------------
  1795. Property Get IsImpress() As Boolean
  1796. IsImpress = [_Super].GetProperty(&quot;IsImpress&quot;)
  1797. End Property &apos; SFDocuments.SF_Calc.IsImpress
  1798. REM -----------------------------------------------------------------------------
  1799. Property Get IsMath() As Boolean
  1800. IsMath = [_Super].GetProperty(&quot;IsMath&quot;)
  1801. End Property &apos; SFDocuments.SF_Calc.IsMath
  1802. REM -----------------------------------------------------------------------------
  1803. Property Get IsWriter() As Boolean
  1804. IsWriter = [_Super].GetProperty(&quot;IsWriter&quot;)
  1805. End Property &apos; SFDocuments.SF_Calc.IsWriter
  1806. REM -----------------------------------------------------------------------------
  1807. Property Get Keywords() As Variant
  1808. Keywords = [_Super].GetProperty(&quot;Keywords&quot;)
  1809. End Property &apos; SFDocuments.SF_Calc.Keywords
  1810. REM -----------------------------------------------------------------------------
  1811. Property Let Keywords(Optional ByVal pvKeywords As Variant)
  1812. [_Super].Keywords = pvKeywords
  1813. End Property &apos; SFDocuments.SF_Calc.Keywords
  1814. REM -----------------------------------------------------------------------------
  1815. Property Get Readonly() As Variant
  1816. Readonly = [_Super].GetProperty(&quot;Readonly&quot;)
  1817. End Property &apos; SFDocuments.SF_Calc.Readonly
  1818. REM -----------------------------------------------------------------------------
  1819. Property Get Subject() As Variant
  1820. Subject = [_Super].GetProperty(&quot;Subject&quot;)
  1821. End Property &apos; SFDocuments.SF_Calc.Subject
  1822. REM -----------------------------------------------------------------------------
  1823. Property Let Subject(Optional ByVal pvSubject As Variant)
  1824. [_Super].Subject = pvSubject
  1825. End Property &apos; SFDocuments.SF_Calc.Subject
  1826. REM -----------------------------------------------------------------------------
  1827. Property Get Title() As Variant
  1828. Title = [_Super].GetProperty(&quot;Title&quot;)
  1829. End Property &apos; SFDocuments.SF_Calc.Title
  1830. REM -----------------------------------------------------------------------------
  1831. Property Let Title(Optional ByVal pvTitle As Variant)
  1832. [_Super].Title = pvTitle
  1833. End Property &apos; SFDocuments.SF_Calc.Title
  1834. REM -----------------------------------------------------------------------------
  1835. Property Get XComponent() As Variant
  1836. XComponent = [_Super].GetProperty(&quot;XComponent&quot;)
  1837. End Property &apos; SFDocuments.SF_Calc.XComponent
  1838. REM ========================================================== SUPERCLASS METHODS
  1839. REM -----------------------------------------------------------------------------
  1840. &apos;Public Function Activate() As Boolean
  1841. &apos; Activate = [_Super].Activate()
  1842. &apos;End Function &apos; SFDocuments.SF_Calc.Activate
  1843. REM -----------------------------------------------------------------------------
  1844. Public Function CloseDocument(Optional ByVal SaveAsk As Variant) As Boolean
  1845. CloseDocument = [_Super].CloseDocument(SaveAsk)
  1846. End Function &apos; SFDocuments.SF_Calc.CloseDocument
  1847. REM -----------------------------------------------------------------------------
  1848. Public Sub RunCommand(Optional ByVal Command As Variant)
  1849. [_Super].RunCommand(Command)
  1850. End Sub &apos; SFDocuments.SF_Calc.RunCommand
  1851. REM -----------------------------------------------------------------------------
  1852. Public Function Save() As Boolean
  1853. Save = [_Super].Save()
  1854. End Function &apos; SFDocuments.SF_Calc.Save
  1855. REM -----------------------------------------------------------------------------
  1856. Public Function SaveAs(Optional ByVal FileName As Variant _
  1857. , Optional ByVal Overwrite As Variant _
  1858. , Optional ByVal Password As Variant _
  1859. , Optional ByVal FilterName As Variant _
  1860. , Optional ByVal FilterOptions As Variant _
  1861. ) As Boolean
  1862. SaveAs = [_Super].SaveAs(FileName, Overwrite, Password, FilterName, FilterOptions)
  1863. End Function &apos; SFDocuments.SF_Calc.SaveAs
  1864. REM -----------------------------------------------------------------------------
  1865. Public Function SaveCopyAs(Optional ByVal FileName As Variant _
  1866. , Optional ByVal Overwrite As Variant _
  1867. , Optional ByVal Password As Variant _
  1868. , Optional ByVal FilterName As Variant _
  1869. , Optional ByVal FilterOptions As Variant _
  1870. ) As Boolean
  1871. SaveCopyAs = [_Super].SaveCopyAs(FileName, Overwrite, Password, FilterName, FilterOptions)
  1872. End Function &apos; SFDocuments.SF_Calc.SaveCopyAs
  1873. REM =========================================================== PRIVATE FUNCTIONS
  1874. REM -----------------------------------------------------------------------------
  1875. Public Function _ConvertFromDataArray(ByRef pvDataArray As Variant) As Variant
  1876. &apos;&apos;&apos; Convert a data array to a scalar, a vector or a 2D array
  1877. &apos;&apos;&apos; Args:
  1878. &apos;&apos;&apos; pvDataArray: an array as returned by the XCellRange.getDataArray or .getFormulaArray methods
  1879. &apos;&apos;&apos; Returns:
  1880. &apos;&apos;&apos; A scalar, a zero-based 1D array or a zero-based 2D array of strings and/or doubles
  1881. &apos;&apos;&apos; To convert doubles to dates, use the CDate builtin function
  1882. Dim vArray As Variant &apos; Return value
  1883. Dim lMax1 As Long &apos; UBound of pvDataArray
  1884. Dim lMax2 As Long &apos; UBound of pvDataArray items
  1885. Dim i As Long
  1886. Dim j As Long
  1887. vArray = Empty
  1888. Try:
  1889. &apos; Convert the data array to scalar, vector or array
  1890. lMax1 = UBound(pvDataArray)
  1891. If lMax1 &gt;= 0 Then
  1892. lMax2 = UBound(pvDataArray(0))
  1893. If lMax2 &gt;= 0 Then
  1894. If lMax1 + lMax2 &gt; 0 Then vArray = Array()
  1895. Select Case True
  1896. Case lMax1 = 0 And lMax2 = 0 &apos; Scalar
  1897. vArray = pvDataArray(0)(0)
  1898. Case lMax1 &gt; 0 And lMax2 = 0 &apos; Vertical vector
  1899. ReDim vArray(0 To lMax1)
  1900. For i = 0 To lMax1
  1901. vArray(i) = pvDataArray(i)(0)
  1902. Next i
  1903. Case lMax1 = 0 And lMax2 &gt; 0 &apos; Horizontal vector
  1904. ReDim vArray(0 To lMax2)
  1905. For j = 0 To lMax2
  1906. vArray(j) = pvDataArray(0)(j)
  1907. Next j
  1908. Case Else &apos; Array
  1909. ReDim vArray(0 To lMax1, 0 To lMax2)
  1910. For i = 0 To lMax1
  1911. For j = 0 To lMax2
  1912. vArray(i, j) = pvDataArray(i)(j)
  1913. Next j
  1914. Next i
  1915. End Select
  1916. End If
  1917. End If
  1918. Finally:
  1919. _ConvertFromDataArray = vArray
  1920. End Function &apos; SF_Documents.SF_Calc._ConvertFromDataArray
  1921. REM -----------------------------------------------------------------------------
  1922. Private Function _ConvertToCellValue(ByVal pvItem As Variant) As Variant
  1923. &apos;&apos;&apos; Convert the argument to a valid Calc cell content
  1924. Dim vCell As Variant &apos; Return value
  1925. Try:
  1926. Select Case ScriptForge.SF_Utils._VarTypeExt(pvItem)
  1927. Case V_STRING : vCell = pvItem
  1928. Case V_DATE : vCell = CDbl(pvItem)
  1929. Case ScriptForge.V_NUMERIC : vCell = CDbl(pvItem)
  1930. Case ScriptForge.V_BOOLEAN : vCell = CDbl(Iif(pvItem, 1, 0))
  1931. Case Else : vCell = &quot;&quot;
  1932. End Select
  1933. Finally:
  1934. _ConvertToCellValue = vCell
  1935. Exit Function
  1936. End Function &apos; SF_Documents.SF_Calc._ConvertToCellValue
  1937. REM -----------------------------------------------------------------------------
  1938. Private Function _ConvertToDataArray(ByRef pvArray As Variant _
  1939. , Optional ByVal plRows As Long _
  1940. , Optional ByVal plColumns As Long _
  1941. ) As Variant
  1942. &apos;&apos;&apos; Create a 2-dimensions nested array (compatible with the ranges .DataArray property)
  1943. &apos;&apos;&apos; from a scalar, a 1D array or a 2D array
  1944. &apos;&apos;&apos; Array items are converted to (possibly empty) strings or doubles
  1945. &apos;&apos;&apos; Args:
  1946. &apos;&apos;&apos; pvArray: the input scalar or array. If array, must be 1 or 2D otherwise it is ignored.
  1947. &apos;&apos;&apos; plRows, plColumns: the upper bounds of the data array
  1948. &apos;&apos;&apos; If bigger than input array, fill with zero-length strings
  1949. &apos;&apos;&apos; If smaller than input array, truncate
  1950. &apos;&apos;&apos; If plRows = 0 and the input array is a vector, the data array is aligned horizontally
  1951. &apos;&apos;&apos; They are either both present or both absent
  1952. &apos;&apos;&apos; When absent
  1953. &apos;&apos;&apos; The size of the output is fully determined by the input array
  1954. &apos;&apos;&apos; Vectors are aligned vertically
  1955. &apos;&apos;&apos; Returns:
  1956. &apos;&apos;&apos; A data array compatible with ranges .DataArray property
  1957. &apos;&apos;&apos; The output is always an array of nested arrays
  1958. Dim vDataArray() As Variant &apos; Return value
  1959. Dim vVector() As Variant &apos; A temporary 1D array
  1960. Dim vItem As Variant &apos; A single input item
  1961. Dim iDims As Integer &apos; Number of dimensions of the input argument
  1962. Dim lMin1 As Long &apos; Lower bound of input array
  1963. Dim lMax1 As Long &apos; Upper bound
  1964. Dim lMin2 As Long &apos; Lower bound
  1965. Dim lMax2 As Long &apos; Upper bound
  1966. Dim lRows As Long &apos; Upper bound of vDataArray
  1967. Dim lCols As Long &apos; Upper bound of vVector
  1968. Dim bHorizontal As Boolean &apos; Horizontal vector
  1969. Dim i As Long
  1970. Dim j As Long
  1971. Const cstEmpty = &quot;&quot; &apos; Empty cell
  1972. If IsMissing(plRows) Or IsEmpty(plRows) Then plRows = -1
  1973. If IsMissing(plColumns) Or IsEmpty(plColumns) Then plColumns = -1
  1974. vDataArray = Array()
  1975. Try:
  1976. &apos; Check the input argument and know its boundaries
  1977. iDims = ScriptForge.SF_Array.CountDims(pvArray)
  1978. If iDims = 0 Or iDims &gt; 2 Then Exit Function
  1979. lMin1 = 0 : lMax1 = 0 &apos; Default values
  1980. lMin2 = 0 : lMax2 = 0
  1981. Select Case iDims
  1982. Case -1 &apos; Scalar value
  1983. Case 1
  1984. bHorizontal = ( plRows = 0 And plColumns &gt; 0)
  1985. If Not bHorizontal Then
  1986. lMin1 = LBound(pvArray) : lMax1 = UBound(pvArray)
  1987. Else
  1988. lMin2 = LBound(pvArray) : lMax2 = UBound(pvArray)
  1989. End If
  1990. Case 2
  1991. lMin1 = LBound(pvArray, 1) : lMax1 = UBound(pvArray, 1)
  1992. lMin2 = LBound(pvArray, 2) : lMax2 = UBound(pvArray, 2)
  1993. End Select
  1994. &apos; Set the output dimensions accordingly
  1995. If plRows &gt;= 0 Then &apos; Dimensions of output are imposed
  1996. lRows = plRows
  1997. lCols = plColumns
  1998. Else &apos; Dimensions of output determined by input argument
  1999. lRows = 0 : lCols = 0 &apos; Default values
  2000. Select Case iDims
  2001. Case -1 &apos; Scalar value
  2002. Case 1 &apos; Vectors are aligned vertically
  2003. lRows = lMax1 - lMin1
  2004. Case 2
  2005. lRows = lMax1 - lMin1
  2006. lCols = lMax2 - lMin2
  2007. End Select
  2008. End If
  2009. ReDim vDataArray(0 To lRows)
  2010. &apos; Feed the output array row by row, each row being a vector
  2011. For i = 0 To lRows
  2012. ReDim vVector(0 To lCols)
  2013. For j = 0 To lCols
  2014. If i &gt; lMax1 - lMin1 Then
  2015. vVector(j) = cstEmpty
  2016. ElseIf j &gt; lMax2 - lMin2 Then
  2017. vVector(j) = cstEmpty
  2018. Else
  2019. Select Case iDims
  2020. Case -1 : vItem = _ConvertToCellValue(pvArray)
  2021. Case 1
  2022. If bHorizontal Then
  2023. vItem = _ConvertToCellValue(pvArray(j + lMin2))
  2024. Else
  2025. vItem = _ConvertToCellValue(pvArray(i + lMin1))
  2026. End If
  2027. Case 2
  2028. vItem = _ConvertToCellValue(pvArray(i + lMin1, j + lMin2))
  2029. End Select
  2030. vVector(j) = vItem
  2031. End If
  2032. vDataArray(i) = vVector
  2033. Next j
  2034. Next i
  2035. Finally:
  2036. _ConvertToDataArray = vDataArray
  2037. Exit Function
  2038. End Function &apos; SF_Documents.SF_Calc._ConvertToDataArray
  2039. REM -----------------------------------------------------------------------------
  2040. Private Function _DFunction(ByVal psFunction As String _
  2041. , Optional ByVal Range As Variant _
  2042. ) As Double
  2043. &apos;&apos;&apos; Apply the given function on all the numeric values stored in the given range
  2044. &apos;&apos;&apos; Args:
  2045. &apos;&apos;&apos; Range : the range as a string where to apply the function on
  2046. &apos;&apos;&apos; Returns:
  2047. &apos;&apos;&apos; The resulting value as a double
  2048. Dim dblGet As Double &apos; Return value
  2049. Dim oAddress As Object &apos; Alias of Range
  2050. Dim vFunction As Variant &apos; com.sun.star.sheet.GeneralFunction.XXX
  2051. Dim cstThisSub As String : cstThisSub = &quot;SFDocuments.Calc.&quot; &amp; psFunction
  2052. Const cstSubArgs = &quot;Range&quot;
  2053. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  2054. dblGet = 0
  2055. Check:
  2056. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  2057. If Not [_Super]._IsStillAlive() Then GoTo Finally
  2058. If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
  2059. End If
  2060. Try:
  2061. &apos; Get the data
  2062. Set oAddress = _ParseAddress(Range)
  2063. Select Case psFunction
  2064. Case &quot;DAvg&quot; : vFunction = com.sun.star.sheet.GeneralFunction.AVERAGE
  2065. Case &quot;DCount&quot; : vFunction = com.sun.star.sheet.GeneralFunction.COUNTNUMS
  2066. Case &quot;DMax&quot; : vFunction = com.sun.star.sheet.GeneralFunction.MAX
  2067. Case &quot;DMin&quot; : vFunction = com.sun.star.sheet.GeneralFunction.MIN
  2068. Case &quot;DSum&quot; : vFunction = com.sun.star.sheet.GeneralFunction.SUM
  2069. Case Else : GoTo Finally
  2070. End Select
  2071. dblGet = oAddress.XCellRange.computeFunction(vFunction)
  2072. Finally:
  2073. _DFunction = dblGet
  2074. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  2075. Exit Function
  2076. Catch:
  2077. GoTo Finally
  2078. End Function &apos; SF_Documents.SF_Calc._DFunction
  2079. REM -----------------------------------------------------------------------------
  2080. Function _GetColumnName(ByVal plColumnNumber As Long) As String
  2081. &apos;&apos;&apos; Convert a column number (range 1, 2,..1024) into its letter counterpart (range &apos;A&apos;, &apos;B&apos;,..&apos;AMJ&apos;).
  2082. &apos;&apos;&apos; Args:
  2083. &apos;&apos;&apos; ColumnNumber: the column number, must be in the interval 1 ... 1024
  2084. &apos;&apos;&apos; Returns:
  2085. &apos;&apos;&apos; a string representation of the column name, in range &apos;A&apos;..&apos;AMJ&apos;
  2086. &apos;&apos;&apos; Adapted from a Python function by sundar nataraj
  2087. &apos;&apos;&apos; http://stackoverflow.com/questions/23861680/convert-spreadsheet-number-to-column-letter
  2088. Dim sCol As String &apos; Return value
  2089. Dim lDiv As Long &apos; Intermediate result
  2090. Dim lMod As Long &apos; Result of modulo 26 operation
  2091. Try:
  2092. lDiv = plColumnNumber
  2093. Do While lDiv &gt; 0
  2094. lMod = (lDiv - 1) Mod 26
  2095. sCol = Chr(65 + lMod) + sCol
  2096. lDiv = Int((lDiv - lMod)/26)
  2097. Loop
  2098. Finally:
  2099. _GetColumnName = sCol
  2100. End Function &apos; SFDocuments.SF_Calc._GetColumnName
  2101. REM -----------------------------------------------------------------------------
  2102. Private Function _LastCell(ByRef poSheet As Object) As Variant
  2103. &apos;&apos;&apos; Returns in an array the coordinates of the last used cell in the given sheet
  2104. Dim oCursor As Object &apos; Cursor on the cell
  2105. Dim oRange As Object &apos; The used range
  2106. Dim vCoordinates(0 To 1) As Long &apos; Return value: (0) = Column, (1) = Row
  2107. Try:
  2108. Set oCursor = poSheet.createCursorByRange(poSheet.getCellRangeByName(&quot;A1&quot;))
  2109. oCursor.gotoEndOfUsedArea(True)
  2110. Set oRange = poSheet.getCellRangeByName(oCursor.AbsoluteName)
  2111. vCoordinates(0) = oRange.RangeAddress.EndColumn + 1
  2112. vCoordinates(1) = oRange.RangeAddress.EndRow + 1
  2113. Finally:
  2114. _LastCell = vCoordinates
  2115. End Function &apos; SFDocuments.SF_Calc._LastCell
  2116. REM -----------------------------------------------------------------------------
  2117. Public Function _Offset(ByRef pvRange As Variant _
  2118. , ByVal plRows As Long _
  2119. , ByVal plColumns As Long _
  2120. , ByVal plHeight As Long _
  2121. , ByVal plWidth As Long _
  2122. ) As Object
  2123. &apos;&apos;&apos; Returns a new range offset by a certain number of rows and columns from a given range
  2124. &apos;&apos;&apos; Args:
  2125. &apos;&apos;&apos; pvRange : the range, as a string or an object, from which the function searches for the new range
  2126. &apos;&apos;&apos; plRows : the number of rows by which the reference was corrected up (negative value) or down.
  2127. &apos;&apos;&apos; plColumns : the number of columns by which the reference was corrected to the left (negative value) or to the right.
  2128. &apos;&apos;&apos; plHeight : the vertical height for an area that starts at the new reference position.
  2129. &apos;&apos;&apos; plWidth : the horizontal width for an area that starts at the new reference position.
  2130. &apos;&apos;&apos; Arguments Rows and Columns must not lead to zero or negative start row or column.
  2131. &apos;&apos;&apos; Arguments Height and Width must not lead to zero or negative count of rows or columns.
  2132. &apos;&apos;&apos; Returns:
  2133. &apos;&apos;&apos; A new range as object of type _Address
  2134. &apos;&apos;&apos; Exceptions:
  2135. &apos;&apos;&apos; OFFSETADDRESSERROR The computed range of cells falls beyond the sheet boundaries
  2136. Dim oOffset As Object &apos; Return value
  2137. Dim oAddress As Object &apos; Alias of Range
  2138. Dim oSheet As Object &apos; com.sun.star.sheet.XSpreadsheet
  2139. Dim oRange As Object &apos; com.sun.star.table.XCellRange
  2140. Dim oNewRange As Object &apos; com.sun.star.table.XCellRange
  2141. Dim lLeft As Long &apos; New range coordinates
  2142. Dim lTop As Long
  2143. Dim lRight As Long
  2144. Dim lBottom As Long
  2145. Set oOffset = Nothing
  2146. Check:
  2147. If plHeight &lt; 0 Or plWidth &lt; 0 Then GoTo CatchAddress
  2148. Try:
  2149. If VarType(pvRange) = V_STRING Then Set oAddress = _ParseAddress(pvRange) Else Set oAddress = pvRange
  2150. Set oSheet = oAddress.XSpreadSheet
  2151. Set oRange = oAddress.XCellRange.RangeAddress
  2152. &apos; Compute and validate new coordinates
  2153. With oRange
  2154. lLeft = .StartColumn + plColumns
  2155. lTop = .StartRow + plRows
  2156. lRight = lLeft + Iif(plWidth = 0, .EndColumn - .StartColumn, plWidth - 1)
  2157. lBottom = lTop + Iif(plHeight = 0, .EndRow - .StartRow, plHeight - 1)
  2158. If lLeft &lt; 0 Or lRight &lt; 0 Or lTop &lt; 0 Or lBottom &lt; 0 _
  2159. Or lLeft &gt; MAXCOLS Or lRight &gt; MAXCOLS _
  2160. Or lTop &gt; MAXROWS Or lBottom &gt; MAXROWS _
  2161. Then GoTo CatchAddress
  2162. Set oNewRange = oSheet.getCellRangeByPosition(lLeft, lTop, lRight, lBottom)
  2163. End With
  2164. &apos; Define the new range address
  2165. Set oOffset = New _Address
  2166. With oOffset
  2167. .ObjectType = CALCREFERENCE
  2168. .RawAddress = oNewRange.AbsoluteName
  2169. .Component = _Component
  2170. .XSpreadsheet = oNewRange.Spreadsheet
  2171. .SheetName = .XSpreadsheet.Name
  2172. .SheetIndex = .XSpreadsheet.RangeAddress.Sheet
  2173. .RangeName = .RawAddress
  2174. .XCellRange = oNewRange
  2175. .Height = oNewRange.RangeAddress.EndRow - oNewRange.RangeAddress.StartRow + 1
  2176. .Width = oNewRange.RangeAddress.EndColumn - oNewRange.RangeAddress.StartColumn + 1
  2177. End With
  2178. Finally:
  2179. Set _Offset = oOffset
  2180. Exit Function
  2181. Catch:
  2182. GoTo Finally
  2183. CatchAddress:
  2184. ScriptForge.SF_Exception.RaiseFatal(OFFSETADDRESSERROR, &quot;Range&quot;, oAddress.RawAddress _
  2185. , &quot;Rows&quot;, plRows, &quot;Columns&quot;, plColumns, &quot;Height&quot;, plHeight, &quot;Width&quot;, plWidth _
  2186. , &quot;Document&quot;, [_Super]._FileIdent())
  2187. GoTo Finally
  2188. End Function &apos; SF_Documents.SF_Calc._Offset
  2189. REM -----------------------------------------------------------------------------
  2190. Private Function _ParseAddress(ByVal psAddress As String) As Object
  2191. &apos;&apos;&apos; Parse and validate a sheet or range reference
  2192. &apos;&apos;&apos; Syntax to parse:
  2193. &apos;&apos;&apos; [Sheet].[Range]
  2194. &apos;&apos;&apos; Sheet =&gt; [&apos;][$]sheet[&apos;] or document named range or ~
  2195. &apos;&apos;&apos; Range =&gt; A1:D10, A1, A:D, 10:10 ($ ignored), or sheet named range or ~
  2196. &apos;&apos;&apos; Returns:
  2197. &apos;&apos;&apos; An object of type _Address
  2198. &apos;&apos;&apos; Exceptions:
  2199. &apos;&apos;&apos; CALCADDRESSERROR &apos; Address could not be parsed to a valid address
  2200. Dim oAddress As _Address &apos; Return value
  2201. Dim lStart As Long &apos; Position of found regex
  2202. Dim sSheet As String &apos; Sheet component
  2203. Dim sRange As String &apos; Range component
  2204. Dim oSheets As Object &apos; com.sun.star.sheet.XSpreadsheets
  2205. Dim oNamedRanges As Object &apos; com.sun.star.sheet.XNamedRanges
  2206. Dim oRangeAddress As Object &apos; Alias for rangeaddress
  2207. Dim vLastCell As Variant &apos; Result of _LastCell() method
  2208. Dim oSelect As Object &apos; Current selection
  2209. With oAddress
  2210. sSheet = &quot;&quot; : sRange = &quot;&quot;
  2211. .SheetName = &quot;&quot; : .RangeName = &quot;&quot;
  2212. .ObjectType = CALCREFERENCE
  2213. .RawAddress = psAddress
  2214. Set .XSpreadSheet = Nothing : Set .XCellRange = Nothing
  2215. &apos; Split in sheet and range components - Check presence of surrounding single quotes or dot
  2216. If Left(psAddress, 1) = &quot;&apos;&quot; Then
  2217. lStart = 1
  2218. sSheet = ScriptForge.SF_String.FindRegex(psAddress, &quot;^&apos;[^\[\]*?:\/\\]+&apos;&quot;)
  2219. If lStart = 0 Then GoTo CatchAddress &apos; Invalid sheet name
  2220. If Len(psAddress) &gt; Len(sSheet) + 1 Then
  2221. If Mid(psAddress, Len(sSheet) + 1, 1) = &quot;.&quot; then sRange = Mid(psAddress, Len(sSheet) + 2)
  2222. End If
  2223. sSheet = Replace(Replace(sSheet, &quot;$&quot;, &quot;&quot;), &quot;&apos;&quot;, &quot;&quot;)
  2224. ElseIf InStr(psAddress, &quot;.&quot;) &gt; 0 Then
  2225. sSheet = Replace(Split(psAddress, &quot;.&quot;)(0), &quot;$&quot;, &quot;&quot;)
  2226. sRange = Replace(Split(psAddress, &quot;.&quot;)(1), &quot;$&quot;, &quot;&quot;)
  2227. Else
  2228. sSheet = psAddress
  2229. End If
  2230. &apos; Resolve sheet part: either a document named range, or the active sheet or a real sheet
  2231. Set oSheets = _Component.getSheets()
  2232. Set oNamedRanges = _Component.NamedRanges
  2233. If oSheets.hasByName(sSheet) Then
  2234. ElseIf sSheet = &quot;~&quot; And Len(sRange) &gt; 0 Then
  2235. sSheet = _Component.CurrentController.ActiveSheet.Name
  2236. ElseIf oNamedRanges.hasByName(sSheet) Then
  2237. .XCellRange = oNamedRanges.getByName(sSheet).ReferredCells
  2238. sSheet = oSheets.getByIndex(oNamedRanges.getByName(sSheet).ReferencePosition.Sheet).Name
  2239. Else
  2240. sRange = sSheet
  2241. sSheet = _Component.CurrentController.ActiveSheet.Name
  2242. End If
  2243. .SheetName = sSheet
  2244. .XSpreadSheet = oSheets.getByName(sSheet)
  2245. .SheetIndex = .XSpreadSheet.RangeAddress.Sheet
  2246. &apos; Resolve range part - either a sheet named range or the current selection or a real range or &quot;&quot;
  2247. If IsNull(.XCellRange) Then
  2248. Set oNamedRanges = .XSpreadSheet.NamedRanges
  2249. If sRange = &quot;~&quot; Then
  2250. Set oSelect = _Component.CurrentController.getSelection()
  2251. If oSelect.supportsService(&quot;com.sun.star.sheet.SheetCellRanges&quot;) Then &apos; Multiple selections
  2252. Set .XCellRange = oSelect.getByIndex(0)
  2253. Else
  2254. Set .XCellRange = oSelect
  2255. End If
  2256. ElseIf sRange = &quot;*&quot; Or sRange = &quot;&quot; Then
  2257. vLastCell = _LastCell(.XSpreadSheet)
  2258. sRange = &quot;A1:&quot; &amp; _GetColumnName(vLastCell(0)) &amp; CStr(vLastCell(1))
  2259. Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
  2260. ElseIf oNamedRanges.hasByName(sRange) Then
  2261. .XCellRange = oNamedRanges.getByName(sRange).ReferredCells
  2262. Else
  2263. On Local Error GoTo CatchError
  2264. Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
  2265. &apos; If range reaches the limits of the sheets, reduce it up to the used area
  2266. Set oRangeAddress = .XCellRange.RangeAddress
  2267. If oRangeAddress.StartColumn = 0 And oRangeAddress.EndColumn = MAXCOLS - 1 Then
  2268. vLastCell = _LastCell(.XSpreadSheet)
  2269. sRange = &quot;A&quot; &amp; CStr(oRangeAddress.StartRow + 1) &amp; &quot;:&quot; _
  2270. &amp; _GetColumnName(vLastCell(0)) &amp; CStr(oRangeAddress.EndRow + 1)
  2271. Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
  2272. ElseIf oRangeAddress.StartRow = 0 And oRangeAddress.EndRow = MAXROWS - 1 Then
  2273. vLastCell = _LastCell(.XSpreadSheet)
  2274. sRange = _GetColumnName(oRangeAddress.StartColumn + 1) &amp; &quot;1&quot; &amp; &quot;:&quot; _
  2275. &amp; _GetColumnName(oRangeAddress.EndColumn + 1) &amp; CStr(_LastCell(.XSpreadSheet)(1))
  2276. Set .XCellRange = .XSpreadSheet.getCellRangeByName(sRange)
  2277. End If
  2278. End If
  2279. End If
  2280. If IsNull(.XCellRange) Then GoTo CatchAddress
  2281. Set oRangeAddress = .XCellRange.RangeAddress
  2282. .RangeName = _RangeToString(oRangeAddress)
  2283. .Height = oRangeAddress.EndRow - oRangeAddress.StartRow + 1
  2284. .Width = oRangeAddress.EndColumn - oRangeAddress.StartColumn + 1
  2285. &apos; Remember the current component in case of use outside the current instance
  2286. Set .Component = _Component
  2287. End With
  2288. Finally:
  2289. Set _ParseAddress = oAddress
  2290. Exit Function
  2291. CatchError:
  2292. ScriptForge.SF_Exception.Clear()
  2293. CatchAddress:
  2294. ScriptForge.SF_Exception.RaiseFatal(CALCADDRESSERROR, &quot;Range&quot;, psAddress _
  2295. , &quot;Document&quot;, [_Super]._FileIdent())
  2296. GoTo Finally
  2297. End Function &apos; SFDocuments.SF_Calc._ParseAddress
  2298. REM -----------------------------------------------------------------------------
  2299. Private Function _PropertyGet(Optional ByVal psProperty As String _
  2300. , Optional ByVal pvArg As Variant _
  2301. ) As Variant
  2302. &apos;&apos;&apos; Return the value of the named property
  2303. &apos;&apos;&apos; Args:
  2304. &apos;&apos;&apos; psProperty: the name of the property
  2305. Dim oProperties As Object &apos; Document or Custom properties
  2306. Dim vLastCell As Variant &apos; Coordinates of last used cell in a sheet
  2307. Dim oSelect As Object &apos; Current selection
  2308. Dim vRanges As Variant &apos; List of selected ranges
  2309. Dim i As Long
  2310. Dim cstThisSub As String
  2311. Const cstSubArgs = &quot;&quot;
  2312. _PropertyGet = False
  2313. cstThisSub = &quot;SFDocuments.SF_Calc.get&quot; &amp; psProperty
  2314. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  2315. If Not [_Super]._IsStillAlive() Then GoTo Finally
  2316. Select Case psProperty
  2317. Case &quot;CurrentSelection&quot;
  2318. Set oSelect = _Component.CurrentController.getSelection()
  2319. If IsNull(oSelect) Then
  2320. _PropertyGet = Array()
  2321. ElseIf oSelect.supportsService(&quot;com.sun.star.sheet.SheetCellRanges&quot;) Then &apos; Multiple selections
  2322. vRanges = Array()
  2323. For i = 0 To oSelect.Count - 1
  2324. vRanges = ScriptForge.SF_Array.Append(vRanges, oSelect.getByIndex(i).AbsoluteName)
  2325. Next i
  2326. _PropertyGet = vRanges
  2327. Else
  2328. _PropertyGet = oSelect.AbsoluteName
  2329. End If
  2330. Case &quot;Height&quot;
  2331. If IsMissing(pvArg) Or IsEmpty(pvArg) Then
  2332. _PropertyGet = 0
  2333. Else
  2334. If Not ScriptForge.SF_Utils._Validate(pvArg, &quot;Range&quot;, V_STRING) Then GoTo Finally
  2335. _PropertyGet = _ParseAddress(pvArg).Height
  2336. End If
  2337. Case &quot;LastCell&quot;, &quot;LastColumn&quot;, &quot;LastRow&quot;
  2338. If IsMissing(pvArg) Or IsEmpty(pvArg) Then &apos; Avoid errors when instance is watched in Basic IDE
  2339. _PropertyGet = -1
  2340. Else
  2341. If Not _ValidateSheet(pvArg, &quot;SheetName&quot;, , True) Then GoTo Finally
  2342. vLastCell = _LastCell(_Component.getSheets.getByName(pvArg))
  2343. If psProperty = &quot;LastRow&quot; Then
  2344. _PropertyGet = vLastCell(1)
  2345. ElseIf psProperty = &quot;LastColumn&quot; Then
  2346. _PropertyGet = vLastCell(0)
  2347. Else
  2348. _PropertyGet = GetColumnName(vLastCell(0)) &amp; CStr(vLastCell(1))
  2349. End If
  2350. End If
  2351. Case &quot;Range&quot;
  2352. If IsMissing(pvArg) Or IsEmpty(pvArg) Then
  2353. Set _PropertyGet = Nothing
  2354. Else
  2355. If Not ScriptForge.SF_Utils._Validate(pvArg, &quot;Range&quot;, V_STRING) Then GoTo Finally
  2356. Set _PropertyGet = _ParseAddress(pvArg)
  2357. End If
  2358. Case &quot;Sheet&quot;
  2359. If IsMissing(pvArg) Or IsEmpty(pvArg) Then
  2360. Set _PropertyGet = Nothing
  2361. Else
  2362. If Not _ValidateSheet(pvArg, &quot;SheetName&quot;, , True) Then GoTo Finally
  2363. Set _PropertyGet = _ParseAddress(pvArg)
  2364. End If
  2365. Case &quot;Sheets&quot;
  2366. _PropertyGet = _Component.getSheets.getElementNames()
  2367. Case &quot;Width&quot;
  2368. If IsMissing(pvArg) Or IsEmpty(pvArg) Then
  2369. _PropertyGet = 0
  2370. Else
  2371. If Not ScriptForge.SF_Utils._Validate(pvArg, &quot;Range&quot;, V_STRING) Then GoTo Finally
  2372. _PropertyGet = _ParseAddress(pvArg).Width
  2373. End If
  2374. Case &quot;XCellRange&quot;
  2375. If IsMissing(pvArg) Or IsEmpty(pvArg) Then
  2376. Set _PropertyGet = Nothing
  2377. Else
  2378. If Not ScriptForge.SF_Utils._Validate(pvArg, &quot;Range&quot;, V_STRING) Then GoTo Finally
  2379. Set _PropertyGet = _ParseAddress(pvArg).XCellRange
  2380. End If
  2381. Case &quot;XSpreadsheet&quot;
  2382. If IsMissing(pvArg) Or IsEmpty(pvArg) Then
  2383. Set _PropertyGet = Nothing
  2384. Else
  2385. If Not _ValidateSheet(pvArg, &quot;SheetName&quot;, , True) Then GoTo Finally
  2386. Set _PropertyGet = _Component.getSheets.getByName(pvArg)
  2387. End If
  2388. Case Else
  2389. _PropertyGet = Null
  2390. End Select
  2391. Finally:
  2392. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  2393. Exit Function
  2394. End Function &apos; SFDocuments.SF_Calc._PropertyGet
  2395. REM -----------------------------------------------------------------------------
  2396. Private Function _RangeToString(ByRef poAddress As Object) As String
  2397. &apos;&apos;&apos; Converts a range address to its A1 notation)
  2398. With poAddress
  2399. _RangeToString = _GetColumnName(.StartColumn + 1) &amp; CStr(.StartRow + 1) &amp; &quot;:&quot; _
  2400. &amp; _GetColumnName(.EndColumn + 1) &amp; CStr(.EndRow + 1)
  2401. End With
  2402. End Function &apos; SFDocuments.SF_Calc._RangeToString
  2403. REM -----------------------------------------------------------------------------
  2404. Private Function _Repr() As String
  2405. &apos;&apos;&apos; Convert the SF_Calc instance to a readable string, typically for debugging purposes (DebugPrint ...)
  2406. &apos;&apos;&apos; Args:
  2407. &apos;&apos;&apos; Return:
  2408. &apos;&apos;&apos; &quot;[DOCUMENT]: Type/File&quot;
  2409. _Repr = &quot;[Calc]: &quot; &amp; [_Super]._FileIdent()
  2410. End Function &apos; SFDocuments.SF_Calc._Repr
  2411. REM -----------------------------------------------------------------------------
  2412. Private Sub _RestoreSelections(ByRef pvComponent As Variant _
  2413. , ByRef pvSelection As Variant _
  2414. )
  2415. &apos;&apos;&apos; Set the selection to a single or a multiple range
  2416. &apos;&apos;&apos; Does not work well when multiple selections and macro terminating in Basic IDE
  2417. &apos;&apos;&apos; Called by the CopyToCell and CopyToRange methods
  2418. &apos;&apos;&apos; Args:
  2419. &apos;&apos;&apos; pvComponent: should work for foreign instances as well
  2420. &apos;&apos;&apos; pvSelection: the stored selection done previously by Component.CurrentController.getSelection()
  2421. Dim oCellRanges As Object &apos; com.sun.star.sheet.SheetCellRanges
  2422. Dim vRangeAddresses As Variant &apos; Array of com.sun.star.table.CellRangeAddress
  2423. Dim i As Long
  2424. Try:
  2425. If IsArray(pvSelection) Then
  2426. Set oCellRanges = pvComponent.createInstance(&quot;com.sun.star.sheet.SheetCellRanges&quot;)
  2427. vRangeAddresses = Array()
  2428. ReDim vRangeAddresses(0 To UBound(pvSelection))
  2429. For i = 0 To UBound(pvSelection)
  2430. vRangeAddresses(i) = pvSelection.getByIndex(i).RangeAddress
  2431. Next i
  2432. oCellRanges.addRangeAddresses(vRangeAddresses, False)
  2433. pvComponent.CurrentController.select(oCellRanges)
  2434. Else
  2435. pvComponent.CurrentController.select(pvSelection)
  2436. End If
  2437. Finally:
  2438. Exit Sub
  2439. End Sub &apos; SFDocuments.SF_Calc._RestoreSelections
  2440. REM -----------------------------------------------------------------------------
  2441. Private Function _ValidateSheet(Optional ByRef pvSheetName As Variant _
  2442. , Optional ByVal psArgName As String _
  2443. , Optional ByVal pvNew As Variant _
  2444. , Optional ByVal pvActive As Variant _
  2445. , Optional ByVal pvOptional as Variant _
  2446. , Optional ByVal pvNumeric As Variant _
  2447. , Optional ByVal pvReference As Variant _
  2448. ) As Boolean
  2449. &apos;&apos;&apos; Sheet designation validation function similar to the SF_Utils._ValidateXXX functions
  2450. &apos;&apos;&apos; Args:
  2451. &apos;&apos;&apos; pvSheetName: string or numeric position
  2452. &apos;&apos;&apos; pvNew: if True, sheet must not exist (default = False)
  2453. &apos;&apos;&apos; pvActive: if True, the shortcut &quot;~&quot; is accepted (default = False)
  2454. &apos;&apos;&apos; pvOptional: if True, a zero-length string is accepted (default = False)
  2455. &apos;&apos;&apos; pvNumeric: if True, the sheet position is accepted (default = False)
  2456. &apos;&apos;&apos; pvReference: if True, a sheet reference is acceptable (default = False)
  2457. &apos;&apos;&apos; pvNumeric and pvReference must not both be = True
  2458. &apos;&apos;&apos; Returns
  2459. &apos;&apos;&apos; True if valid. SheetName is reset to current value if = &quot;~&quot;
  2460. &apos;&apos;&apos; Exceptions
  2461. &apos;&apos;&apos; DUPLICATESHEETERROR A sheet with the given name exists already
  2462. Dim vSheets As Variant &apos; List of sheets
  2463. Dim vTypes As Variant &apos; Array of accepted variable types
  2464. Dim bValid As Boolean &apos; Return value
  2465. Check:
  2466. If IsMissing(pvNew) Or IsEmpty(pvNew) Then pvNew = False
  2467. If IsMissing(pvActive) Or IsEmpty(pvActive) Then pvActive = False
  2468. If IsMissing(pvOptional) Or IsEmpty(pvOptional) Then pvOptional = False
  2469. If IsMissing(pvNumeric) Or IsEmpty(pvNumeric) Then pvNumeric = False
  2470. If IsMissing(pvReference) Or IsEmpty(pvReference) Then pvReference = False
  2471. &apos; Define the acceptable variable types
  2472. If pvNumeric Then
  2473. vTypes = Array(V_STRING, V_NUMERIC)
  2474. ElseIf pvReference Then
  2475. vTypes = Array(V_STRING, ScriptForge.V_OBJECT)
  2476. Else
  2477. vTypes = V_STRING
  2478. End If
  2479. If Not ScriptForge.SF_Utils._Validate(pvSheetName, psArgName, vTypes, , , Iif(pvReference, CALCREFERENCE, &quot;&quot;)) Then GoTo Finally
  2480. bValid = False
  2481. Try:
  2482. If VarType(pvSheetName) = V_STRING Then
  2483. If pvOptional And Len(pvSheetName) = 0 Then
  2484. ElseIf pvActive And pvSheetName = &quot;~&quot; Then
  2485. pvSheetName = _Component.CurrentController.ActiveSheet.Name
  2486. Else
  2487. vSheets = _Component.getSheets.getElementNames()
  2488. If pvNew Then
  2489. If ScriptForge.SF_Array.Contains(vSheets, pvSheetName) Then GoTo CatchDuplicate
  2490. Else
  2491. If Not ScriptForge.SF_Utils._Validate(pvSheetName, psArgName, V_STRING, vSheets) Then GoTo Finally
  2492. End If
  2493. End If
  2494. End If
  2495. bValid = True
  2496. Finally:
  2497. _ValidateSheet = bValid
  2498. Exit Function
  2499. CatchDuplicate:
  2500. ScriptForge.SF_Exception.RaiseFatal(DUPLICATESHEETERROR, psArgName, pvSheetName, &quot;Document&quot;, [_Super]._FileIdent())
  2501. GoTo Finally
  2502. End Function &apos; SFDocuments.SF_Calc._ValidateSheet
  2503. REM ============================================ END OF SFDOCUMENTS.SF_CALC
  2504. </script:module>