LibreOfice Basic The Doc object points to the document (ex: Doc=ThisComponent). Access to sheets Calc Work with Sheets objects: Active sheet MySheet = Doc.CurrentController.ActiveSheet Beginner Sheet list AllSheets = Doc.Sheets v. 1.11 – January 13, 2018 Number of sheets NumberSheets = Doc.Sheets.Count Sheet object (by index [base MySheet = Doc.Sheets(index) Writen with LibreOffe v. 5.3.3 – Platform : All 0]) Sheet object (by name) MySheet = Doc.Sheets.getByName("SheetName") LibreOffice Documents Check existence (name) Exist = Doc.Sheets.hasByName("SheetName") Sheet index Index = MySheet.RangeAddress.Sheet Current document Modify sheets Dim Doc As Object Doc = ThisComponent Add a sheet named Name at Doc.Sheets.insertNewByName(Name, p) Open another existing document position p(base 0) Delete a sheet Doc.Sheets.removeByName("SheetName") Visible mode Duplicate a sheet Doc.Sheets.copyByName("SourceName","Target- Dim Doc As Object to the position p (base 0) Name", p) Dim PathDoc As String Dim Props() 'here, this table is not initialized Move sheet Doc.Sheets.moveByName(SheetName, p) PathDoc = ConvertToURL("C:\Path\To\CalcFile.ods") to the position p (base 0) Doc = StarDesktop.loadComponentFromURL(PathDoc, "_blank", 0, _ Manage sheets Props()) MySheet is a sheet object. Invisible mode Activate sheet Doc.CurrentController.ActiveSheet = MySheet Dim Doc As Object Protect sheet MySheet.protect(password) Dim PathDoc As String (password can be empty) Dim Props(0) As New com.sun.star.beans.PropertyValue Unprotect sheet MySheet.unprotect(password) PathDoc = ConvertToURL("C:\Path\To\CalcFile.ods") Tab color MySheet.tabColor = RGB(255, 255, 0) Props(0).Name = "Hidden" 'the document will open hidden" Props(0).Value = True Link a sheet Doc = StarDesktop.loadComponentFromURL(PathDoc, "_blank", 0, _ Link to a file (ex: MySheet.link(URL, "", "Text - txt - csv (StarCalc)", _ Props()) CSV) Filter, com.sun.star.sheet.SheetLinkMode.VALUE) Turn visible a posteriori Break a link MySheet.setLinkMode(com.sun.star.sheet.SheetLinkMod- Doc.CurrentController.Frame.ContainerWindow.Visible = True e.NONE) Doc.CurrentController.Frame.ContainerWindow.toFront() Find last row/column used Create a new Calc document MySheet is the sheet object to explore. Row and Col are information to fetch. From (1) the default template or (2) a specific template. Dim Cur As Object ' cursor on the cell Dim Range As Object ' the used range Dim Doc As Object Dim Row As Long Dim Props() 'here, this table is not initialized Dim Col As Long Model = "private:factory/scalc" '(1) Cur = MySheet.createCursorByRange(MySheet.getCellRangeByName("A1")) 'or Cur.gotoEndOfUsedArea(True) Model = "C:\Path\To\ACalcTemplateFile.ots" '(2) Range = MySheet.getCellRangeByName(Cur.AbsoluteName) Doc = StarDesktop.loadComponentFromURL(Model, "_blank", 0, Props()) Row = Range.RangeAddress.EndRow Col = Range.RangeAddress.EndColumn Save a document The document already exist Cells (cells) (equivalent to File > Save ) Below Cel is an cell object. Use the method store from the document object. Ex : ThisComponent.store Access to cells The document was not yet saved MySheet is a sheet object. Access to cell object: (equivalent to File > Save as ) Cel = MySheet.getCellRangeByName("A4") By cell default notation Dim Doc As Object 'the object document to store By name Cel = MySheet.getCellRangeByName("TVA") Dim PathDoc As String 'the path for saving By coordinates X and Y Cel = MySheet.getCellByPosition(0,3) Dim Props() 'the saving properties. (empty) Wih X=0 (col.A) ; Y=3 (row.4) PathDoc = ConvertToURL("C:\Path\To\CalcFile.ods") Doc.storeAsURL(PathDoc, Props()) Access to active cell ☞ If a copy, it turns to active document Doc is an document object and ActiveCel the active cell object. Save a copy If Doc.currentSelection.supportsService _ Like above but with Doc.storeToURL(PathDoc, Props()) ("com.sun.star.sheet.SheetCell") Then 'It's a cell ☞ The copy does not become the active document. ActiveCel = Doc.currentSelection Close a document End If Use the method close from the document object: ThisComponent.close(True) Select a cell Document information ThisComponent.CurrentController.select(Cel) The document object expose properties Cell coordinates Location The folder of the document. Coordinates (Object) Coord = Cel.CellAddress ☞ Empty string is not yet saved Sheet index (Integer) NumS = Cel.CellAddress.Sheet DocumentProperties (Object) Additional properties (below). Columns index (Long) NumC = Cel.CellAddress.Column DocumentProperties Row index (Long) NumL = Cel.CellAddress.Row Author Author's name ModifyDate Last modification date Sheet container object MySheet = Cel.Spreadsheet CreationDate Creation date. Subject Document subject (string). Absolute coordinates (String) Coord = Cel.AbsoluteName Description Document description Title Document title (un)protect cells ModifiedBy User name who modified the UserDefined- Custom properties Cel.CellProtection can take boolean values: document. Properties (Object). Prevent modification CellProtection.IsLocked = True Is it a Calc document? Hide cell formula CellProtection.IsFormulaHidden = True The Doc object points to the document (ex: Doc=ThisComponent). Hide cell CellProtection.IsHidden = True CalcOK = Doc.SupportsService("com.sun.star.sheet.SpreadsheetDocument") Don't print cell CellProtection.IsPrintHidden = True
Calc – General functionalities Access cell contents
Properties The Doc object points to the document (ex: Doc=ThisComponent). Read text contents MyText = Cel.String Automatic calculation Read numeric contents aNumeber = Cel.Value Active? (Boolean) Auto = Doc.isAutomaticCalculationEnabled Read cell formula (en-US names) TheFormula = Cel.Formula Disable Doc.enableAutomaticCalculation(False) Read cell formula (localized names) LaFormule = Cel.FormulaLocal Enable Doc.enableAutomaticCalculation(True) Cell type TheType = Cel.Type Force recalculation Doc.calculate (only for formulas not updated) Empty a cell Cel.String = "" Doc.calculateAll (all formulas) Contents type ( Type property) Protect document The constants com.sun.star.table.CellContentType.XXX represent the cell informa- Is document protected? Test = Doc.isProtected tion type (Cel.Type, above) : Protect document Doc.protect(password) [password can be EMPTY Empty cell VALUE Numerical value empty] TEXT Text contents FORMULA Formula contents Unprotect document Doc.unprotect(password) Write in a cell Replace existing text Cel.String = "Hello !" Replace an existing value Cel.Value = 1.234 Replace an existing formula Cel.Formula = "=AND(A1="YES";A2="OK")" (localized) Replace an existing formula Cel.FormulaLocal = "=ET(A1="OUI";A2="OK")" LibOBasic_3_Calc_Flat_A4_EN_v111.odt (localized) Ranges (ranges) Rows/Columns (rows/columns) Range = set of cells, (including a single one): Dim MyRange As Object Rows and columns are Sheet and Range objects properties. Access to ranges General MySheet is a sheet object. Get a range object Ran>: Rows (TheRows object) TheRows = MyRange.Rows By cell default notation Ran = MySheet.getCellRangeByName("C2:G14") Columns (TheCols object) TheCols = MyRange.Columns By name Ran = MySheet.getCellRangeByName("RangeName") Counting NbL = MyRange.Rows.Count By coordinates Ran = MySheet.getCellRangeByPosition(2, 1, 6, 13) NbC = MyRange.Columns.Count (X1, Y1, X2, Y2) A row (TheRow object (base 0) TheRow = MyRange.Rows(index) Randomly Ran = ThisComponent.Sheets.getCellRangeByPosition(2, A column (TheCol object (base 0) TheCol = MyRange.Columns(index) (ex third sheet) 2, 1, 6, 13) Row/Columns properties Active range Applies to Row or Rows (resp. Column or Columns). Like active cell, but check "com.sun.star.sheet.SheetCellRange" or "[...].Sheet- Visible / Hidden (Boolean) IsVisible = True CellRanges". Optimal width (Boolean) OptimalWidth = True Range selection Insert/delete rows/columns ThisComponent.CurrentController.select(MyRange) where MyRange is an objetc. Define object RorC, and FirstPos and LastPos the positions of the begining and end of Range coordinates the row set (resp. columns) to add/delete (Long). Coordinates (Object) Coord = MyRange.RangeAddress Insert RorC.insertByIndex(FirstPos, LastPos) Sheet index (Integer) Ran = MyRange.RangeAddress.Sheet Delete RorC.removeByIndex(FirstPos, LastPos) Column rank (Long) NumCHG = MyRange.RangeAddress.StartColumn Freeze row/columns top/left corner Use the Controller object: MyController = ThisComponent.CurrentColtroller Row rank (Long) NumLHG = MyRange.RangeAddress.StartRow Is there one? Freeze = MyController.hasFrozenPanes top/left corner Freeze MyController.freezeAtPosition(1, 2) Column rank (Long) NumCBD = MyRange.RangeAddress.EndColumn Delete MyController.freezeAtPosition(0, 0) bottom/right corner Row rank (Long) NumLBD = MyRow.RangeAddress.EndRow Call a Calc function bottom/right corner MySheet = MyRange.Spreadsheet Use service "com.sun.star.sheet.FunctionAccess" Sheet container object Absolute coordinates (String) Coord = MyRange.AbsoluteName Usage Named ranges Dim FCalc As Object Dim Result As (context dependent) The Doc object points to the document. With Dim TheRanges As Object Dim Params As (context dependent) Named ranges TheRanges = Doc.NamedRanges Dim FunctionName As String Number (Long) Nb = TheRanges.Count FCalc = CreateUnoService("com.sun.star.sheet.FunctionAccess") Get a range (by index) MyRange = TheRanges(index) Results = FCalc.callFunction(FunctionName, Params) Check existence (name) Exist = TheRanges.hasByName("RangeName") ☞ Function name, parameters and type of results depends on the selected function Get range (by name) MyRange = TheRanges.getByName("Range- The function name must be its English name. Name") To get the function English name, switch temporarily to English Calc function names Add TheRanges.addNewByName("Rangename", Co- display, at Tools > Options > LibreOffice Calc > Formula, Use English function names. Coord : range coordinates ord, _ Example 1 (function SUM()) CellRef : reference cell object CellRef.CellAddress, 0) Dim FCalc As Object Delete (by name) TheRanges.removeByName("RangeName") Dim Results As Long FCalc = CreateUnoService("com.sun.star.sheet.FunctionAccess") Erase a range Results = FCalc.callFunction("SUM", Array(1, 55, 321, 8)) Erase MyRange contents MyRange.clearContents(EraseMode) EraseMode is a value that define the type of cleaning. Use com.sun.star.sheet.- Example 2 (function ROUND()) CellFlags.XXX and combine them with +) : Dim FCalc As Object ANNOTATION Comments STRING Text Dim Results As Double DATETIME Date/time formatted numbers VALUE Numbers (except date/time) Dim Params(1) As Variant Params(0) = 1,2345 'number to round FORMULA Formulae Params(1) = 3 '3 places Get cell contents in a range FCalc = CreateUnoService("com.sun.star.sheet.FunctionAccess") Results = FCalc.callFunction("ROUND", Params()) MyRange.DataArray is a table of cell values for MyRange. Copy range contents into another range Create a Calc function Have 2 ranges Source and Target, with same dimensions. Create Copy contents (values) from Source into Target.DataArray = Source.DataArray Target. Example : calculate the area of a trapeze (S = ((B + b) / 2) × H) Write values in a range Function AreaTrapeze(GB As Double, PB As Double, H As Double) As MyRange is a range object and MyTable a table, with same dmensions, where values Double AreaTrapeze = ((GB + PB) / 2) * H must be transfered to the range. End Function Dim MyTable As Variant MyTable = MyRange.DataArray 'MyTable takes the range dimensions Usage in Calc '(give values to the tabel elements) If A2 is the large base, A3 the small base and A4 the height, the area of the trapeze is ob- MyRange.DataArray = MyTable tained inserting the following formula in a cell: =AREATRAPEZE(A2;A3;A4) ☞ .DataArray is an embedded table: use .DataArray(i)(j) ☞ The macro receives the values of the arguments and not the cell object. Traverse cells in a range ☞ The macro returns a value. It does not applies to a cell. ☞ The function must be located in a library accessible at runtime (e.g. Standard library of From a collection (MyRanges.Cells) create an enumeration. Traverse the range calling the document or user) (otherwise, it produces the #VALUE! error). its properties hasMoreElements and NextElement: Dim Plages As Object MyRanges = ThisComponent.createInstance("com.sun.star.sheet.SheetCellRanges") MyRanges.insertByName("", MyRange) LEnum = MyRanges.Cells.CreateEnumeration Do While LEnum.hasMoreElements MyCell = LEnum.NextElement ' apply instructions to object cell Credits Loop Author : Jean-François Nifenecker – jean-francois.nifenecker@laposte.net Empty cells are not traversed ! We are like dwarves perched on the shoulders of giants. If we are able to see more and farther than the Ranges: Miscellaneous latter, and this is not at all because of the acuteness of our sight or the stature of our body, but because we are carried aloft and elevated by the magnitude of the giants (Bernard de Chartres [attr.]) Merge cells of MyRange MyRange.Merge Hisory Range types Version Date Comments Depending of the access mode, ranges implement one of these services: 1.01 01/10/2017 First version. ① com.sun.star.sheet.SheetCell ④ com.sun.star.sheet.SheetCellRange 1.11 13/01/2018 Add range types. ② com.sun.star.table.CellRange ➄ com.sun.star.sheet.SheetCellRanges ③ com.sun.star.sheet.NamedRange Depending on the service implemented, ranges must be employed differently. Test through method supportsService() (ex. below) Cell or range? To know the object type, test supportsService() with service_name below (boolean) on the object (range or cell): If MyObj.supportsService(service_name) Then … Licence Replace service_name by : This reference card is under license Cell ? "com.sun.star.sheet.SheetCell" ① CreativeCommons BY-SA v3 (fr). Single range ? "com.sun.star.sheet.SheetCellRange" ④ Information Multiple range ? "com.sun.star.sheet.SheetCellRanges" ➄ https://creativecommons.org/licenses/by-sa/3.0/fr/ Always test a cell before a single range because a cell is also a single range !