How do define a cursor in a TABLE with a macro?

Why does this code work on normal document text, but if you select text inside a table it causes an error: “End of content node doesn’t have the proper start node.”

Sub Main
	viewCursor = ThisComponent.CurrentController.getViewCursor()
	textCursor = ThisComponent.Text.createTextCursorByRange(viewCursor) 
End Sub

How are you supposed to have a macro that works inside a table?

UPDATE:

OK, let me be more clear. I have a macro that takes the selected text and modifies it. It works fine when running on a normal paragraph, but I get that error when I try to run the macro inside a table or frame. Clearly I need to use a different method in order to get the selected text and the cursor position inside of a table. So what is the code to do that? Thanks.

Andrew Pitonyak, 7.1. Selected Text, What Is It?
It is a common misconception that you use the selected text functions to determine if the cursor is located inside of a text table. A Writer document’s controller returns a view cursor that identifies the location of the cursor. The view cursor contains two properties of interest…

Written many years ago and is still true

Sub cellTextCursor 'example for the cursor operations inside the cell
	dim oDoc as object, oTable as object, oCell as object, oCur as object
	oDoc=ThisComponent
	oTable=oDoc.TextTables.getByIndex(0)
	oCell=oTable.getCellByName("A1")
	oCur=oCell.createTextCursor 'cursor inside the cell
	oCur.goRight(3, true) 'select three characters in A1
	oDoc.CurrentController.Select(oCur)
End Sub

Sub cellCursor 'example for the cursor operations with the cells
	dim oDoc as object, oTable as object, oCellCur as object
	oDoc=ThisComponent
	oTable=oDoc.TextTables.getByIndex(0)
	oCellCur=oTable.createCursorByCellName("A1") 'cursor for the cells
	oCellCur.goRight(1, true) 'select cells A1&A2
	oDoc.CurrentController.Select(oCellCur)
End Sub

Sub viewCursorToB2 'put view cursor to the cell B2
	dim oDoc as object, oTable as object, oCell as object, oVCur as object, oCur as object
	oDoc=ThisComponent
	oVCur=oDoc.CurrentController.getViewCursor() 'view cursor
	oTable=oDoc.TextTables.getByIndex(0)
	oCell=oTable.getCellByName("B2")
	oCur=oCell.createTextCursor 'cursor inside the cell
	oVCur.goToRange(oCur.Start, false) 'put view cursor to the position of the cell text cursor
End Sub

Example - run macros from menu MACRO
table-cursor.odt (17.6 kB)

Uh, thanks. That is not very useful. I need to run a macro on the text that is selected inside a table. These macros just pick a predetermined cell in the table.

The quote in my previous comment is a link. Open the document that you get from this link, find the mentioned chapter 7.1 and read the next three paragraphs - this is the answer to your question. Listing 7.1: Is the cursor in a text table? will allow you to determine the point from which you started the macro. The following listing shows how to find out from which text table and from which cell. Something like

Sub IsACellSelected
  Dim oSels        'All of the selections
  Dim oSel         'A single selection
  Dim i As Integer
  oSels = ThisComponent.getCurrentController().getSelection()
  If oSels.supportsService("com.sun.star.text.TextRanges") Then
    For i=0 to oSels.getCount()-1
      oSel = oSels.getByIndex(i)
      If oSel.supportsService("com.sun.star.text.TextRange") Then
        If ( Not IsEmpty(oSel.TextTable) ) Then 
          Print "Selection in the TextTable '" & oSel.TextTable.LinkDisplayName & "'"
        End If
        If ( Not IsEmpty(oSel.Cell) ) Then 
          Print "Selected Cell '" & oSel.Cell.CellName & "'"
        End If
      End If
    Next
  ElseIf oSels.supportsService("com.sun.star.text.TextTableCursor") Then
    REM At least one entire cell is selected
    Print oSels.getRangeName()
  End If
End Sub

@JohnSUN: Strangely this will not directly help to also get the TextTable as an object in the final case. The API doesn’t make the TextTableCursor tell to what table it belongs. You can move it in some ways, but you can’t ckeck in advance if the target cell exists. To check the structutre (“Simple or complex?” e.g.) you would best analyze the CellNames property probably . You can’t.(With goLeft(), goRight() it may get a nightmare)

The ways I know to get the table object itself require to change the CurrentSelection.

If you know better, please let me participate.

Do you tell that the line
oTable = ThisComponent.getTextTables().getByName(oSel.TextTable.LinkDisplayName)
is not enough “directly” ?

Of course, there were cases where I told nonsense over the years. Sorry! In this special case, I see it differently:

This is the case for which the code @JohnSUN posted is satisfying. I was talking about the final ELSEIF case applying if the CurrentSelection is a TextTableCursor.

The ThisComponent.Text.createTextCursorByRange(…) isn’t functional in the Table or Frame. But you can modify the Text selection directly.

Sub modifySelectedText
	dim oDoc as object, oSel as object, o as object
	oDoc=ThisComponent
	oSel=oDoc.CurrentController.getSelection()
	if oSel.supportsService("com.sun.star.text.TextRanges") then
		o=oSel.getByIndex(0)
		'xray o 'discover the properties of the selection
		o.CharBackColor=RGB(250,220,40)
	end if
End Sub

table2.odt (18.2 kB)