https://bugs.documentfoundation.org/show_bug.cgi?id=172830

            Bug ID: 172830
           Summary: The API for handling the selection in calc is hard to
                    use
           Product: LibreOffice
           Version: 26.8.0.0 alpha0+ master
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: medium
         Component: sdk
          Assignee: [email protected]
          Reporter: [email protected]

I wanted to write a macro that would store a value in all of the cells of the
current selection in Calc. Looking at the documentation on the wiki, you can
use the XSelectionSupplier interface to get the current selection. This will
return either SheetCell, SheetCellRange or SheetCellRanges depending on whether
a single cell, a range of cells or multiple ranges of cells are selected. So in
order to iterate over all the selected cells, the best I could come up with was
this:

def fill_range(cell_range):
    addressable = cell_range.getRangeAddress()
    width = addressable.EndColumn - addressable.StartColumn + 1
    height = addressable.EndRow - addressable.StartRow + 1
    for y in range(height):
        for x in range(width):
            cell_range.getCellByPosition(x, y).setString("x")


def fill_selection():
    selection = XSCRIPTCONTEXT.getDocument().getCurrentSelection()
    if selection.supportsService("com.sun.star.sheet.SheetCellRanges"):
        # The selection has multiple ranges
        for cell_range in selection:
            fill_range(cell_range)
    else:
        # The selection is one simple range
        fill_range(selection)

It seems like there should be a way to do this with less code.

Meanwhile, if you write in BASIC with VBA compatibility mode you can do this in
one line like this:

Option VBASupport 1

Sub Main
 Selection.Value = "x"
End Sub

Sadly it seems like it’s very difficult to use VBA mode without creating a
document with Microsoft Office. (See tdf#172748).

Another option could be to use the VBA API without enabling VBA support like
this:

Sub Main
  CreateUnoService("ooo.vba.excel.Application").Selection.Value = "x"
End Sub

This doesn’t work for Python because the Application implementation implements
XInvocation which breaks the introspection. (See tdf#172532).

My proposal would be to provide a helper service called something like
CellEnumeration that would implement XEnumeration and would take as a
constructor argument any of the possible values for the current selection. Then
it would be possible to write code like this in Python:

from com.sun.star.sheet import CellEnumeration
for cell in CellEnumeration.create(context, doc.getCurrentSelection()):
  cell.setText("x")

Note that there is already a service called CellsEnumeration but this doesn’t
quite do what we want. As far as I can tell it is only returned from
XSheetCellRanges.getCells() so it only works when multiple ranges are selected
and it also skips cells that don’t have a value.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to