c# - Word 互操作 : How to obtain valid selected cells collection from Word table when selection area is not a rectangle?

标签 c# vba ms-word office-interop

我正在尝试从 Word 表格中获取选定的单元格。我需要收集选定的表格单元格来创建自定义书签对象,其中包含用户选择的单元格范围的信息。当用户选择单元格的矩形区域时,一切正常。这就是我在 Word 插件中获取选定表格单元格的方式:

Globals.ThisAddIn.Application.Selection.Range.Application.ActiveWindow.Selection.Cells

如果用户选择了非矩形区域或选择了多个区域(同时按住 CTRL 键),此属性将返回无效的单元格集合。我创建了一个简单的 vba 代码,用于使用两个属性测试在表中选择了哪些单元格:

Globals.ThisAddIn.Application.Selection.Range.Application.ActiveWindow.Selection.Cells
Globals.ThisAddIn.Application.Selection.Range.Cells

当用户选择非矩形表格单元格区域时,这两个属性都会返回不同且无效的选定单元格集合。这是我用于测试目的的 vba 代码,当在 Word 表格中选择了单元格范围时:

Sub test()

Dim listaKomorek1 As New Collection
Dim listaKomorek2 As New Collection
Dim indekser1 As Integer
Dim indekser2 As Integer
Dim tekst1 As String
Dim tekst2 As String
Dim tabela As Table

Set tabela = Selection.Range.Tables(1)

indekser1 = 1
indekser2 = 1
liczbaKomorek1 = Selection.Range.Cells.count()
liczbaKomorek2 = Selection.Range.Application.ActiveWindow.Selection.Cells.count()
tekst1 = "Lista komorek 1 (Selection.Range.Cells): " & vbCrLf & vbCrLf & vbCrLf
tekst2 = "Lista komorek 2 (ActiveWindow.Selection.Cells): " & vbCrLf & vbCrLf & vbCrLf

For Each komorka In Selection.Range.Cells
    tekst1 = tekst1 & "#Cell: " & CStr(indekser1) & " Value: " & CStr(komorka.Range.Text) & " Column: " & CStr(komorka.ColumnIndex) & " Row: " & CStr(komorka.RowIndex) & vbCrLf
    indekser1 = indekser1 + 1
Next komorka

For Each komorka In Selection.Range.Application.ActiveWindow.Selection.Cells
    tekst2 = tekst2 & "#Cell: " & CStr(indekser2) & " Value: " & CStr(komorka.Range.Text) & " Column: " & CStr(komorka.ColumnIndex) & " Row: " & CStr(komorka.RowIndex) & vbCrLf
    indekser2 = indekser2 + 1
Next komorka

tekst1 = tekst1 & vbCrLf & "Cells count: " & CStr(liczbaKomorek1)
tekst2 = tekst2 & vbCrLf & "Cells count: " & CStr(liczbaKomorek2)
MsgBox tekst1
MsgBox tekst2
End Sub

我的问题是,当用户在 Word 表格中选择非矩形区域时,如何获得有效的选定单元格集合?

最佳答案

感谢 Tim Williams 发表的文章,我设法找到了解决方案。这个解决方案绝不是完美的,但它提供了而且我没有设法想到更好的东西。为了获得所选单元格的有效集合,当表格中有连续选择时。我们可以更改连续选择支持的属性之一。之后我们可以很容易地找到具有更改属性的单元格,这些单元格将是表格中所有选定的单元格。这是我创建的方法,我使用 Font.Size 来查找选定的单元格:

public static List<System.Drawing.Point> GetSelectedCells()
    {
        //We will use this to hold column and row coordinates for cells
        List<System.Drawing.Point> value = new List<System.Drawing.Point>();
        try
        {
            Microsoft.Office.Interop.Word.Range range = Globals.ThisAddIn.Application.Selection.Range; 
            if (range.Tables.Count > 0)
            {
                Table tempTable = range.Tables[1];
                float[,] backupTable = new float[range.Tables[1].Rows.Count + 1, range.Tables[1].Columns.Count + 1];

                for (int i = 1; i <= tempTable.Rows.Count; i++)
                {
                    for (int j = 1; j <= tempTable.Rows[i].Cells.Count; j++)
                        backupTable[i, j] = tempTable.Rows[i].Cells[j].Range.Font.Size;
                }

                Globals.ThisAddIn.Application.Selection.Font.Size = 1;

                foreach (Row row in range.Tables[1].Rows)
                {
                    foreach (Cell cell in row.Cells)
                    {
                        if (cell.Range.Font.Size == 1)
                        {
                            System.Drawing.Point point = new System.Drawing.Point();
                            point.X = cell.RowIndex;
                            point.Y = cell.ColumnIndex;
                            value.Add(point);
                        }
                    }
                }

                for (int i = 1; i <= tempTable.Rows.Count; i++)
                {
                    for (int j = 1; j <= tempTable.Rows[i].Cells.Count; j++)
                        tempTable.Rows[i].Cells[j].Range.Font.Size = backupTable[i, j];
                }
                Marshal.ReleaseComObject(tempTable);
            }
        }
        catch(Exception)
        {
           //This exception can be used to handle Exception that occurs when there are merged cells in the     table.
        }
        return value;
    }

这不适用于合并的单元格。

关于c# - Word 互操作 : How to obtain valid selected cells collection from Word table when selection area is not a rectangle?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22666219/

相关文章:

c# - 除了互操作之外,还有哪些可用方法来创建 Word 文档并将数据导出到该 Word 文档?

c# - 从 app.config 获取数据的最佳方式是什么?

c# - Windows 启动时运行程序(登录前)

c# - 将文件附加到 MailMessage C# 时文件已损坏

vba - 在宏运行结束时打开 NUMLOCK

excel - 在名称管理器中搜索名称并设置值

c# - 从数据库 LinqToSql 访问值的任何更好的方法

vba - 如何调暗 getElementsBy* 结果

c# - 如何在 c# 的 ms word 文档中设置文本方向 RightToLeft?

java - 无法使用java读取pdf中的unicode字符