Search code examples
c#ms-wordoffice-interop

Finding the index of a selected cell using Microsoft.Office.Interop.Word


Note: I have solved this problem using a brute force double for loop. I need a faster and more efficient way of solving it in C# specifically.

Consider the Word table below.

enter image description here

I need an efficient method of finding a given column and a given row and placing text in the intersecting cell. For example lets say I'm given 1 as my column and A as my row. Then the text would go into the cell with the index row:2,col:2.

Things I have tried: Iterating over all the rows and columns. This is slow and takes a significant amount of time. To speed it up I attempted to use Range.Find but struggled to know where the found cell was in the context of the table. Here is some rough code of what I was thinking. I am well aware this is missing checks if the items arent found or if there are multiple but I can deal with that later.

int col;
int row;

var searchRange = table.Range;
var isFound = searchRange.Find.Execute(FindText:rowText);
if(isFound){
 searchRange.Select();
col = searchRange.SOME_FUNCTION_THAT_WILL_REVEAL_THE_CELLS_COL_INDEX_WITHIN_THE_TABLE();
}

var searchRange = table.Range;
var isFound = searchRange.Find.Execute(FindText:rowText);
if(isFound){
 searchRange.Select();
row = searchRange.SOME_FUNCTION_THAT_WILL_REVEAL_THE_CELLS_ROW_INDEX_WITHIN_THE_TABLE();
}

table.Cell(row, col).Text = "Some text For Desired Location";

Solution

  • This is exactly what you want. Paste it into a VBA module, first select outside a table and F8 through the code. Next make the mouse cursor select a cell in the table and then F8 through this code:

    Sub SelectionInfo()
         '
        Dim iSelectionRowEnd As Integer
        Dim iSelectionRowStart As Integer
        Dim iSelectionColumnEnd As Integer
        Dim iSelectionColumnStart As Integer
        Dim lngStart As Long
        Dim lngEnd As Long
         
         ' Check if Selection IS in a table
         ' if not, exit Sub after message
        If Selection.Information(wdWithInTable) = False Then
            MsgBox "Selection is not in a table.  Exiting macro."
        Else
            lngStart = Selection.Range.Start
            lngEnd = Selection.Range.End
             
             ' get the numbers for the END of the selection range
            iSelectionRowEnd = Selection.Information(wdEndOfRangeRowNumber)
            iSelectionColumnEnd = Selection.Information(wdEndOfRangeColumnNumber)
             
             ' collapse the selection range
            Selection.Collapse Direction:=wdCollapseStart
             
             ' get the numbers for the END of the selection range
             ' now of course the START of the previous selection
            iSelectionRowStart = Selection.Information(wdEndOfRangeRowNumber)
            iSelectionColumnStart = Selection.Information(wdEndOfRangeColumnNumber)
             
             ' RESELECT the same range
            Selection.MoveEnd Unit:=wdCharacter, Count:=lngEnd - lngStart
             
             ' display the range of cells covered by the selection
            MsgBox "The selection covers " & Selection.Cells.Count & " cells, from Cell(" & _
            iSelectionRowStart & "," & iSelectionColumnStart & ") to Cell(" & _
            iSelectionRowEnd & "," & iSelectionColumnEnd & ")."
        End If
    End Sub
    

    REF: http://www.vbaexpress.com/kb/getarticle.php?kb_id=867