NamedRanges.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #
  2. # This file is part of the LibreOffice project.
  3. #
  4. # This Source Code Form is subject to the terms of the Mozilla Public
  5. # License, v. 2.0. If a copy of the MPL was not distributed with this
  6. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
  7. #
  8. import uno
  9. from com.sun.star.container import NoSuchElementException
  10. def DefineNamedRange(doc, SheetName, rangeName, rangeReference):
  11. """Defines a new named range. If the named range exists in the document, then
  12. update the rangeReference.
  13. Example: DefineNamedRange(doc, "Sheet1", "test_range", '$A$1:$F$14').
  14. API Reference:
  15. https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1sheet_1_1XNamedRanges.html
  16. """
  17. aName = rangeName
  18. # make sure the sheet name starts with "$"
  19. sheetName = "$" + SheetName.replace("$", "")
  20. aContent = sheetName + "." + rangeReference
  21. try:
  22. # If the named range exists, then update it
  23. doc.NamedRanges.getByName(rangeName)
  24. update = True
  25. except NoSuchElementException:
  26. update = False
  27. if update:
  28. doc.NamedRanges.getByName(rangeName).setContent(aContent)
  29. else:
  30. aPosition = uno.createUnoStruct('com.sun.star.table.CellAddress')
  31. sheet = doc.Sheets.getByName(SheetName)
  32. # the index of the sheet in the doc, 0-based
  33. aPosition.Sheet = sheet.getRangeAddress().Sheet
  34. addressObj = sheet.getCellRangeByName(rangeReference)
  35. # (com.sun.star.table.CellRangeAddress){ Sheet = (short)0x0, StartColumn = (long)0x0, StartRow = (long)0x0, EndColumn = (long)0x5, EndRow = (long)0xd }
  36. address = addressObj.getRangeAddress()
  37. aPosition.Column = address.StartColumn
  38. aPosition.Row = address.StartRow
  39. doc.NamedRanges.addNewByName(aName, aContent, aPosition, 0)
  40. return None
  41. def NamedRanges():
  42. """The main function to be shown on the user interface."""
  43. ctx = uno.getComponentContext()
  44. smgr = ctx.ServiceManager
  45. desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
  46. # Create a blank spreadsheet document, instead of damaging the existing document.
  47. doc = desktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, ())
  48. # Create a new sheet to store our output information
  49. doc.Sheets.insertNewByName("Information", 1)
  50. infoSheet = doc.Sheets.getByName("Information")
  51. # Set text in the information sheet
  52. infoSheet.getCellRangeByName("A1").String = "Operation"
  53. infoSheet.getCellRangeByName("B1").String = "Name of Cell Range"
  54. infoSheet.getCellRangeByName("C1").String = "Content of Named Cell Range"
  55. # Format the information header row
  56. infoHeaderRange = infoSheet.getCellRangeByName("A1:C1")
  57. # 2 = CENTER, see enum CellHoriJustify in https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1table.html
  58. infoHeaderRange.HoriJustify = 2
  59. infoHeaderRange.CellBackColor = 0xdee6ef
  60. # Defines the named range test_range1
  61. dataSheetName = "data"
  62. doc.Sheets[0].Name = dataSheetName
  63. DefineNamedRange(doc, dataSheetName, "test_range1", "$A$1:$F$14")
  64. # Displays the named range information
  65. test_range1 = doc.NamedRanges.getByName("test_range1")
  66. infoSheet.getCellRangeByName("A2").String = "Defined test_range1"
  67. infoSheet.getCellRangeByName("B2").String = test_range1.Name
  68. infoSheet.getCellRangeByName("C2").String = test_range1.Content
  69. # Revise the named ranges.
  70. DefineNamedRange(doc, dataSheetName, "test_range1", "$A$1:$A$10")
  71. infoSheet.getCellRangeByName("A3").String = "Revised test_range1"
  72. infoSheet.getCellRangeByName("B3").String = test_range1.Name
  73. infoSheet.getCellRangeByName("C3").String = test_range1.Content
  74. # Defines the named range test_range2
  75. DefineNamedRange(doc, dataSheetName, "test_range2", "$B$1:$B$10")
  76. test_range2 = doc.NamedRanges.getByName("test_range2")
  77. infoSheet.getCellRangeByName("A4").String = "Defined test_range2"
  78. infoSheet.getCellRangeByName("B4").String = test_range2.Name
  79. infoSheet.getCellRangeByName("C4").String = test_range2.Content
  80. # Set data to test_range1 and test_range2
  81. dataSheet = doc.Sheets.getByName(dataSheetName)
  82. # You should use a tuple for setDataArray. For range e.g. A1:E1 it should
  83. # be in the form tuple((1,2,3,4,5)), and for range e.g. A1:A5 it should be
  84. # in the form tuple((1,), (2,), (3,), (4,), (5,)).
  85. data1 = tuple(((1,),(2,),(3,),(4,),(5,),(6,),(7,),(8,),(9,),(10,)))
  86. dataSheet.getCellRangeByName(test_range1.Content).setDataArray(data1)
  87. infoSheet.getCellRangeByName("A5").String = "Set value to test_range1"
  88. data2 = tuple(((2,),(4,),(6,),(8,),(10,),(12,),(14,),(16,),(18,),(20,)))
  89. dataSheet.getCellRangeByName(test_range2.Content).setDataArray(data2)
  90. infoSheet.getCellRangeByName("A6").String = "Set value to test_range2"
  91. # Calculate sum of test_range1
  92. infoSheet.getCellRangeByName("A8").String = "Sum of test_range1:"
  93. infoSheet.getCellRangeByName("B8").Formula = "=SUM(test_range1)"
  94. # Calculate sum of test_range2
  95. infoSheet.getCellRangeByName("A9").String = "Sum of test_range2:"
  96. infoSheet.getCellRangeByName("B9").Formula = "=SUM(test_range2)"
  97. # Calculate the difference between the two ranges
  98. infoSheet.getCellRangeByName("A10").String = "sum(test_range2) - sum(test_range1):"
  99. infoSheet.getCellRangeByName("B10").Formula = "=B9-B8"
  100. # Format the sum header columns
  101. infoSheet.getCellRangeByName("A8:A10").CellBackColor = 0xdee6ef
  102. # Set column width
  103. infoSheet.Columns.getByName("A").Width = 5590
  104. infoSheet.Columns.getByName("B").Width = 4610
  105. infoSheet.Columns.getByName("C").Width = 4610
  106. g_exportedScripts = (NamedRanges,)
  107. # vim: set shiftwidth=4 softtabstop=4 expandtab: