【问题标题】:Counting the number of occurrences of a specific style, within a column of a table在表格的一列中计算特定样式的出现次数
【发布时间】:2023-03-17 12:20:01
【问题描述】:

我需要在表格的一列中计算特定样式的出现次数。我的程序会在整个文档中而不是仅在所选内容中查找出现次数。

Sub Find()
    Selection.Tables(1).Columns(1).Select
    With Selection.Find
        .Style = "Style2"

        iCount = 0
        While .Execute
            iCount = iCount + 1
        Wend

        MsgBox (iCount)
    End With
End Sub

【问题讨论】:

  • 你需要找什么样的风格?如果是段落样式,或许最好避免 Find。也许像下面的伪代码就足够了 - 对于列中的每个单元格:对于单元格/s范围中的每个段落:段落是否具有那种样式? : 下一段 : 下一个单元格。如果是字符样式,可以查看每个单元格范围的字符集合,查找样式的变化。

标签: vba find selection ms-word


【解决方案1】:

在表格内执行 Find 是一个棘手的提议,因为 Find 具有在单元格内“反弹”的令人讨厌的倾向。当我测试您的代码时,没有关于如何在表格单元格中应用样式的信息,宏进入一个循环并且直到我强制它停止才停止。所以我有点惊讶你的代码能正常工作......

在列上进行查找的问题在于,在文档的底层结构中,列不是一组连续的字符,就像它在屏幕上显示的那样。 Word 表格信息在单元格中从上到下运行,从左到右跨行,然后到下一行并重复。列选择是由 Word 应用程序维护的一种错觉。所以基于 Selection 或 Range 的宏代码不能遵循通常适用的规则。

以下内容对我有用。本质上,它在整个表内进行搜索,但是当它命中不在指定列中的单元格时,目标范围将移动到列中的下一个单元格并再次运行搜索。仅计算列中单元格内的“命中”。

Sub FindStyleInstanceInTableColumn()
    Dim iCount As Long, iCellCount As Long, iCounter As Long
    Dim cel As word.Cell
    Dim col As word.Column
    Dim rngFind As word.Range, rngCel As word.Range
    Dim bFound As Boolean
    Set col = Selection.Tables(1).Columns(1)
    iCount = 0
    iCellCount = col.Cells.Count
    iCounter = 1
    Set rngCel = col.Cells(iCounter).Range
    Set rngFind = rngCel.Duplicate
    'Don't include end-of-cell marker
    rngFind.MoveEnd wdCharacter, -1
    rngFind.Select 'For debugging
    With rngFind.Find
        .Style = "Style2"
        bFound = .Execute(wrap:=wdFindStop)
        Do
            rngFind.Select  'For debugging
            If bFound Then
                'If the found range is within a column cell
                'then increase the counter
                If rngFind.InRange(rngCel) Then
                    iCount = iCount + 1
                'If the found range is not in a column cell
                'then the style wasn't found in the cell so
                'go to the next cell
                ElseIf iCounter < iCellCount Then
                    iCounter = iCounter + 1
                    Set rngCel = col.Cells(iCounter).Range
                    rngFind.Start = rngCel.Start
                    rngFind.End = rngCel.Start
                End If
                rngFind.Collapse wdCollapseEnd
            End If
            bFound = .Execute(Format:=True, wrap:=wdFindStop)
        Loop Until iCounter = iCellCount And Not bFound
    End With
    MsgBox (iCount)
End Sub

编辑:调整代码以考虑第一个单元格中没有命中和列的最后一个单元格中的命中。不同之处在于确保 rngFind 的起点与 rngCel 在同一个单元格中。

【讨论】:

  • 非常感谢您的回答。我在我的数据上测试了代码,当可以在第一个单元格中找到指定的样式时它可以工作。但是,如果在第一个单元格中没有找到任何内容(它继续在第一个单元格中搜索),则宏进入无限循环。我添加了几行来克服循环问题;搜索现在成功地继续向下一个单元格。但是,即使强制更新“rngFind”,“.Execute”命令也会返回第一个单元格内的搜索结果(bFound 未更新)。如果您在这方面提供提示,我将不胜感激!
猜你喜欢
  • 2020-03-18
  • 1970-01-01
  • 2020-09-09
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 2018-11-15
  • 1970-01-01
相关资源
最近更新 更多