Move current row up or down

Is there a keyboard shortcut to shift the current row up or down? Effectively swapping the current row with the row above it or below it.

I find this feature in a lot of text editors where you can just press alt up or alt down. Obviously calc isn’t a text editor.

And of course I know the manual way by inserting a blank line where I want to move it to, then moving it, then deleting the line left behind. I’m sure there are several ways to do it. But I’m looking for a simple keyboard shortcut.

I’ve looked here and didn’t see anything.
https://help.libreoffice.org/Calc/Shortcut_Keys_for_Spreadsheets

Of course! After all, the text never contains formulas that can refer to lines below or above and which will not break when moved to another place. If you can describe the behavior of a spreadsheet when moving a row with calculated elements, and not with fixed values, then writing the corresponding commands will not be difficult.

Thanks. In my situation I don’t have any formulas at all. So it really is just about swapping the contents of the rows.

Well. Then use @karolus’s solution. Now the macro only works with two adjacent rows (the top two rows in the selected range), requires prior selection and the absence of a sheet named “non_ex_sisst” in the spreadsheet. However, this is a good starting point that you can improve as you see fit.

that exactly was the reason for the ugly name!

@karolus, Crashing the macro before the line doc.Sheets.removeByName(tname) will create the sheet with the most fancy name in our spreadsheet

the following code hopefully works as intented:

def swap_two_rows(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    tname = "non_ex_sisst"
    sel = doc.CurrentSelection
    sheet = sel.Spreadsheet
    doc.Sheets.insertNewByName(tname, doc.Sheets.Count)
    tsheet = doc.Sheets[tname]
    above, below = sel[0,:].RangeAddress, sel[1,:].RangeAddress
    first, second = sel[0,0].CellAddress, sel[1,0].CellAddress
    tmp, tmprange = tsheet[0,0].CellAddress, tsheet[0,:].RangeAddress
    sheet.copyRange(tmp, above)
    sheet.copyRange(first, below)
    sheet.moveRange(second, tmprange)
    doc.Sheets.removeByName(tname)

probably you need apso.oxt to organize python-code
you should select the 2 Rows to swap, and run the above via some self-defined shortcut.

Nice code. Quick. And does what is ordered (under certain conditions). This is exactly what I was talking about in my remark - it is impossible to foresee the behavior of each cell in a row, it is not the program that should perform the swap, but the human (and be responsible for the consequences)

@JohnSUN I know that the solution may not satisfy all constraints, and I hope the OP knows that too!

btw. the simplest approch assuming there are NO Formulas at all, AND EACH COLUMN (individually) has the SAME FORMATTING:

def swap_simple_Data(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    sel = doc.CurrentSelection
    sel.DataArray = reversed(sel.DataArray)

@karolus Yes, but… Still, working with selection requires more complex code - how about swapping the third and eighth rows?

select them individually and:

……
    doc = XSCRIPTCONTEXT.getDocument()
    sel = doc.CurrentSelection
    sel1, sel2 = sel 
    sel1.DataArray, sel2.DataArray = sel2.DataArray, sel1.DataArray

Wonderful! But now the code doesn’t work with two adjacent rows (one range of two rows).
Also, how about stretching the selection to a full (entire) row? So that the user can select one cell in each of the swap rows? Oh yes! To the right of the current table, there may be other information that cannot be shifted… What if a different number of cells (for example, B2:D2;A4:D4) is randomly selected in the selected rows?..

There is no way to create a “god”-procedure that knows by miracle the user intention…right?
If the user wants the whole Row, he|she should select whole Row[s]

the simple approch extented to work with single Selection, and also with multiple Selections …each the same size as the others:

def swap_simple_Data(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    sel = doc.CurrentSelection
    try:
        sel.Count
        container = [single.DataArray for single in sel]
        for i, single in enumerate(sel,1):
            single.DataArray = container[-i]
    except AttributeError:
        sel.DataArray = reversed(sel.DataArray)

There is another approach - to do exactly what the user asks for. We read the name of the topic - “Move current row up or down”. Since we know that the first row cannot be moved up, and the user rarely gets to the last row (it is too far), we reduce the task to “Move current row down”.
Now it’s simple - remember the current selection, take the first cell of the selection and find out the row number, add 1 and find out the number of the next row, swap only this two rows, (if necessary, move the old selection to a new place). Yes, it’s not creative… but it’s what was asked for, isn’t it?

and what exactly means “up or down” ?? and whats wrong, with the decision to select 2 Rows (or alternativ any range of 2 Rows, and swap them?

(IMHO) The scenario that @librebird writes about can be expressed as follows: I (cursor, active cell) stand on a row in a table. I want to press some combination of keys and move this row one position down. If I need to do this several times, then I will press a combination of hot keys until I achieve the desired result. At the same time, I do not want to remove my hands from the keyboard, look for the mouse, use it to select something in the table. If I wanted to use the mouse, I would use the tricks that IWebb or JohnSUN showed (and this is if I do not have a Mac - fdo#58440 - EDITING: moving columns/rows with <alt+drag&drop> overwrites instead of ousting)

Yes, that does explain just what I’m trying to do.

It seems clear, though, that this is not something that Calc can do. That’s really all I wanted to know.

Perhaps I shouldn’t have described it as swapping lines, because although that is what is happening, that’s not the real goal I am trying to do. Especially if I wanted to move up or down several rows.

Why not? Calc can. It will simply do this with due regard for the restrictions: there are no formulas in the cells that can break when changing the row position; for the first row, upward movement is impossible; for the last row, downward movement is not possible; in the case of multiple selection (with the Ctrl key held down) - do nothing, because it is not clear what to move down; the shift is performed for the entire row at once, and so on

Alt sort of works

The only caveat is you have to manually highlight the data in the rows or columns.

This might help

https://www.youtube.com/watch?v=hGXdWc1swWg&list=PLzad0VvGzlSqpBFs-kqkhz2pgcaf8bT3s&index=69

1 Like