VBA-如何在表格中途开始选择 [英] VBA - How to start a selection halfway through the text in a table

查看:87
本文介绍了VBA-如何在表格中途开始选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

替代我关于range.find上一个问题 ,我正在尝试Selection.find.

As an alternative to my previous question regarding range.find, I am trying Selection.find.

我发现表内出现缩写.我想从该结果的位置继续搜索.

I have found the occurrence of an abbreviation inside a table. I want to continue my search from the location of that result.

但是,当我获得范围并选择它时,选择项从行的开头开始.

However, when I get the range and select it, the Selection starts from the beginning of the row.

如何将其限制为上一次出现?

How can I restrict it to be from the previous occurrence?

当前代码:

    Private Sub cmdFindNextAbbr_Click()

    Dim myRange As range
    Dim Word, findText As String
    Dim chkAbbrLast, chkAbbrFullLast, fsCountExt, NextAbbrStart, NextAbbrStartTemp, NextAbbrEndTemp As Integer
    Dim firstOccEnd As Long
    Dim abr, abrText, srText As String
    Dim abrtype, ig, absCounter As Integer

    'CREATING DICTONARY for Selected Items
    abr = lstAbbreviations.List(selAbbrIndex, 0)
    abrText = lstAbbreviations.List(selAbbrIndex, 1)
    abrtype = lstAbbreviations.List(selAbbrIndex, 4)

    chkAbbrLast = 0
    chkAbbrFullLast = 0

    If NextAbbrEnd = 0 Then
        NextAbbrEnd = abbrFirstOccEnd
        NextAbbrStart = 0
    End If

    fnCountAbr = fnCountAbr + 1

    ' checking for full text and abbreviations
    vFindText = abrText & "," & abrText & "s," & abr & "," & abr & "s"
    vFindText = Split(vFindText, ",")
    aCount = 0
    For ig = LBound(vFindText) To UBound(vFindText)
        Set myRange = ActiveDocument.range(Start:=NextAbbrEnd + 1, End:=ActiveDocument.range.End)
        absCounter = 0

        srText = vFindText(ig)
        If InStr(srText, abrText) > 0 Then
            bMatchCase = False
        ElseIf InStr(srText, abr) > 0 Then
            bMatchCase = True
        End If

        Dim cached As Long
        cached = ActiveDocument.range.End



        myRange.Find.ClearFormatting
        myRange.Select

        Selection.Find.ClearFormatting
        Do While Selection.Find.Execute( _
                        findText:=srText, _
                        MatchCase:=bMatchCase, _
                        Wrap:=wdFindStop, _
                        MatchWholeWord:=True _
                        )
            ' if the found text starts earlier, set its location as first location
            If Selection.End <> abbrFirstOccEnd Then
                If NextAbbrStartTemp = 0 Or Selection.Start < NextAbbrStartTemp Then
                    NextAbbrStartTemp = Selection.Start
                End If
            End If
            'check for full term and abbreviation
            fsCountExt = Len(abrText & "s (" & abr & "s)")

            If UCase(Selection.Text) = UCase(abrText & "s (" & abr & "s)") Then
                txtNew = abr & "s"
                If Selection.End = NextAbbrStartTemp + fsCountExt Then
                    NextAbbrEndTemp = Selection.End
                    NextAbbrStartTemp = Selection.Start
                End If
                GoTo ContLoop
            Else
                fsCountExt = Len(abrText & " (" & abr & ")")
                Selection.End = Selection.Start + fsCountExt
            End If

            If UCase(Selection.Text) = UCase(abrText & " (" & abr & ")") Then
                txtNew = abr
                If Selection.End = NextAbbrStartTemp + fsCountExt Then
                    NextAbbrEndTemp = Selection.End
                    NextAbbrStartTemp = Selection.Start
                End If
                GoTo ContLoop
            End If

            'check for full term only
            fsCountExt = Len(abrText & "s")
                Selection.End = Selection.Start + fsCountExt

            If UCase(Selection.Text) = UCase(abrText & "s") Then
                txtNew = abr & "s"
                If Selection.End = NextAbbrStartTemp + fsCountExt Then
                    NextAbbrEndTemp = Selection.End
                    NextAbbrStartTemp = Selection.Start
                End If
                GoTo ContLoop
            Else
                fsCountExt = Len(abrText)
                Selection.End = Selection.Start + fsCountExt
            End If

            If UCase(Selection.Text) = UCase(abrText) Then
                txtNew = abr
                If Selection.End = NextAbbrStartTemp + fsCountExt Then
                    NextAbbrEndTemp = Selection.End
                    NextAbbrStartTemp = Selection.Start
                End If
                GoTo ContLoop
            End If

            'check for only abbreviation
            fsCountExt = Len(abr & "s")
                Selection.End = Selection.Start + fsCountExt

            If UCase(Selection.Text) = UCase(abr & "s") Then
                txtNew = abr & "s"
                If Selection.End = NextAbbrStartTemp + fsCountExt Then
                    NextAbbrEndTemp = Selection.End
                    NextAbbrStartTemp = Selection.Start
                End If
                GoTo ContLoop
            Else
                fsCountExt = Len(abr)
                Selection.End = Selection.Start + fsCountExt
            End If

            If UCase(Selection.Text) = UCase(abr) Then
                txtNew = abr
                If Selection.End = NextAbbrStartTemp + fsCountExt Then
                    NextAbbrEndTemp = Selection.End
                    NextAbbrStartTemp = Selection.Start
                End If
                GoTo ContLoop
            End If

            If absCounter > 2 Then GoTo ContSearch
            absCounter = absCounter + 1
ContLoop:

        Loop

ContSearch:
            Selection.Start = Selection.Start + Len(Selection.Find.Text) + 1
            Selection.End = cached
    Next ig


    'MsgBox "No further occurrences found"

ExitNextSub:

    NextAbbrStart = NextAbbrStartTemp
    NextAbbrEnd = NextAbbrEndTemp
    myRange.Start = NextAbbrStart
    myRange.End = NextAbbrEnd
    myRange.Select
    Application.ScreenRefresh
End Sub

在调试时,我在myRange.Select之后看到以下值.同时检查文件.我看到该行开头的文本已选中

While debugging, I see the below values after myRange.Select. While checking the document. I see that the text from the beginning of the row is selected

myRange.Start : 18838
Selection.Start : 18216

推荐答案

使用(临时)书签来记下要重新启动的位置. 不要尝试依赖StartEnd属性.这些都不可靠.

Use a (temporary) bookmark to note where you want to restart. Do not try to rely on the Start and End properties. Those are not reliable.

当查找"可能最终出现在表中并且找到的术语将继续存在于该位置时,从该点开始搜索到文档的末尾(或开始)将自动包括整行.如果您单击一个单元格,然后按住Shift键并按向右箭头,直到所选内容超出表格,您就可以将此用户看到.

When Find could end up in a table and the found term will continue to exist in that position, searching from that point onwards to the end (or beginning) of the document will automatically include the entire row. You can see this as a user if you click in a cell then hold Shift and press right-arrow until the selection moves beyond the table.

在这种情况下,您需要测试找到的范围是否在表中.如果是这样,则需要逐个单元继续查找循环,直到找到的范围不再在表中为止.

In such a situation you need to test whether the found Range is in a table. If it is, you need to continue the Find loop cell-by-cell until the found Range is no longer in a table.

以下代码演示了该原理.它使用Range对象,而不是Selection对象,因为它更容易控制,并且更易于预测.为了集中于逐个循环一个表格的原理,这也非常简化,这可能有点令人费解. (Debug.Print就在其中,以便在测试时保持跟踪.)

The following code demonstrates the principle. It uses a Range object, not Selection, as that's easier and more predictable to control. It's also very simplified in order to concentrate on the principle of looping a table cell-by-cell which can be a bit mind-boggling. (The Debug.Print is just in there for keeping track while testing.)

查找是否成功存储在布尔变量bFound中.在成功的情况下,将对找到的Range进行表中测试. (请注意,您还可以使用rngFind.Information(wdWithinTable).)如果是,则将Range折叠起来,以使找到的项在它的外部",然后Range扩展到单元格的末尾.

Whether the Find is successful is stored in the boolean variable bFound. In the case of success the found Range is tested for being in a table. (Note that you could also use rngFind.Information(wdWithinTable).) If it is, the Range is collapsed so that the found term is "outside" it, then the Range extended to the end of the cell.

在循环中重复查找,直到在该单元格中找不到更多命中"为止.然后将范围移动到下一个单元格并重复查找,直到找到的范围不再存在于表中.然后,查找将循环循环到正常"过程,直到找不到更多搜索词实例为止.

Find is repeated in the loop until no more "hits" are found in that cell. The Range is then moved to the next cell and Find repeated until the found Range is no longer in a table. Then Find reverts to the "normal" process, in a loop, until no more instances of the search term are found.

Sub FindLoopThroughTables()
    Dim sFindTerm As String
    Dim doc As Word.Document
    Dim rngFind As Word.Range
    Dim cel As Word.Cell
    Dim bFound As Boolean

    Set doc = ActiveDocument
    Set rngFind = doc.content
    rngFind.Find.wrap = wdFindStop
    sFindTerm = "the"

    bFound = rngFind.Find.Execute(sFindTerm)
    Do While bFound
            Debug.Print rngFind.Start
            If rngFind.Tables.Count > 0 Then
                Do While bFound And rngFind.Tables.Count > 0
                    Set cel = rngFind.Cells(1)
                    rngFind.Collapse wdCollapseEnd
                    rngFind.End = cel.Range.End - 1
                    bFound = rngFind.Find.Execute(sFindTerm)
                    If bFound Then
                        Debug.Print rngFind.Start & "in table"
                    Else
                        rngFind.MoveStart wdCell, 1
                        Set cel = rngFind.Cells(1)
                        rngFind.End = cel.Range.End
                        bFound = rngFind.Find.Execute(sFindTerm)
                   End If
                Loop
            Else
                rngFind.Collapse wdCollapseEnd
                rngFind.End = doc.content.End
                bFound = rngFind.Find.Execute(sFindTerm)
            End If
    Loop
End Sub

这篇关于VBA-如何在表格中途开始选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆