【问题标题】:Find a string within a cell using VBA使用 VBA 在单元格中查找字符串
【发布时间】:2012-06-09 20:47:49
【问题描述】:

我已经为此发疯了一天,到处搜索,可能是想变得太可爱,所以我完全被困住了。

我正在尝试运行一个简单的 if then

如果一个单元格包含“%”,我希望它做一件事,如果不是另一件事。由于我不明白的原因,我无法解决它。我显然从其他地方获得了一些想法,但仍然无法实现。

复杂因素 - 我不想在整个列上运行它,只是在一个表上运行,所以它使用很多或相对 ActiveCells 嵌入到更大的子中。我永远不知道我将在 A 列中的哪个位置遇到“% Change”,因此 Range 始终必须是可变的。我希望 VBA/VBE 在遇到带有“%”的单元格时做一些不同的事情。所以

这是原始数据的样子

Initial Value (6/30/06)

Value (12/31/06)

Net Additions (9/30/07)

Withdrawal (12/07)

Value (12/31/07)

Withdrawal (2008)

Value (12/31/08)

Addition (8/26/09)

Value (12/31/09)

Value (12/31/10)

Value (12/30/11)

Value (3/31/12)

% Change 1st Quarter

% Change Since Inception

但是当我运行以下命令时,它陷入了一个错误的循环,它应该拉到“If Then”而不是 sub 的“Else”部分。

Sub IfTest()
 'This should split the information in a table up into cells
 Dim Splitter() As String
 Dim LenValue As Integer     'Gives the number of characters in date string
 Dim LeftValue As Integer    'One less than the LenValue to drop the ")"
 Dim rng As Range, cell As Range
 Set rng = ActiveCell

Do While ActiveCell.Value <> Empty
    If InStr(rng, "%") = True Then
        ActiveCell.Offset(0, 0).Select
        Splitter = Split(ActiveCell.Value, "% Change")
        ActiveCell.Offset(0, 10).Select
        ActiveCell.Value = Splitter(1)
        ActiveCell.Offset(0, -1).Select
        ActiveCell.Value = "% Change"
        ActiveCell.Offset(1, -9).Select
    Else
        ActiveCell.Offset(0, 0).Select
        Splitter = Split(ActiveCell.Value, "(")
        ActiveCell.Offset(0, 9).Select
        ActiveCell.Value = Splitter(0)
        ActiveCell.Offset(0, 1).Select
        LenValue = Len(Splitter(1))
        LeftValue = LenValue - 1
        ActiveCell.Value = Left(Splitter(1), LeftValue)
        ActiveCell.Offset(1, -10).Select
    End If
Loop
End Sub

感谢所有帮助,谢谢!

【问题讨论】:

    标签: string search excel vba


    【解决方案1】:

    对于搜索例程,您应该考虑使用FindAutoFilter 或变体数组方法。范围循环通常太慢,如果他们使用Select 会更糟

    下面的代码将在用户选择的范围内查找 strText 变量,然后将任何匹配项添加到范围变量rng2,然后您可以进一步处理

    Option Explicit
    
    Const strText As String = "%"
    
    Sub ColSearch_DelRows()
        Dim rng1 As Range
        Dim rng2 As Range
        Dim rng3 As Range
        Dim cel1 As Range
        Dim cel2 As Range
        Dim strFirstAddress As String
        Dim lAppCalc As Long
    
    
        'Get working range from user
        On Error Resume Next
        Set rng1 = Application.InputBox("Please select range to search for " & strText, "User range selection", Selection.Address(0, 0), , , , , 8)
        On Error GoTo 0
        If rng1 Is Nothing Then Exit Sub
    
        With Application
            lAppCalc = .Calculation
            .ScreenUpdating = False
            .Calculation = xlCalculationManual
        End With
    
        Set cel1 = rng1.Find(strText, , xlValues, xlPart, xlByRows, , False)
    
        'A range variable - rng2 - is used to store the range of cells that contain the string being searched for
        If Not cel1 Is Nothing Then
            Set rng2 = cel1
            strFirstAddress = cel1.Address
            Do
                Set cel1 = rng1.FindNext(cel1)
                Set rng2 = Union(rng2, cel1)
            Loop While strFirstAddress <> cel1.Address
        End If
    
        If Not rng2 Is Nothing Then
            For Each cel2 In rng2
                Debug.Print cel2.Address & " contained " & strText
            Next
        Else
            MsgBox "No " & strText
        End If
    
        With Application
            .ScreenUpdating = True
            .Calculation = lAppCalc
        End With
    
    End Sub
    

    【讨论】:

    • 这对我以后会很有帮助,谢谢!
    【解决方案2】:

    我简化了您的代码以隔离单元格中是否存在“%”的测试。一旦你得到它的工作,你可以添加你的其余代码。

    试试这个:

    Option Explicit
    
    
    Sub DoIHavePercentSymbol()
       Dim rng As Range
    
       Set rng = ActiveCell
    
       Do While rng.Value <> Empty
            If InStr(rng.Value, "%") = 0 Then
                MsgBox "I know nothing about percentages!"
                Set rng = rng.Offset(1)
                rng.Select
            Else
                MsgBox "I contain a % symbol!"
                Set rng = rng.Offset(1)
                rng.Select
            End If
       Loop
    
    End Sub
    

    InStr 将返回搜索文本在字符串中出现的次数。我更改了您的 if 测试以首先检查是否没有匹配项。

    消息框和.Selects 只是为了让您在单步执行代码时查看正在发生的事情。一旦你开始工作,就把它们拿出来。

    【讨论】:

    • 这是我所缺少的简单拼图。我还是比较新的,所以没有想过(好吧,也许知道:) 关于在 if 中执行 set rng.offset 的能力。这很棒,而且非常有帮助。我也一直在使用 true false 而不是 InStr 函数的 = 0,我仍然没有完全理解,但很感激。非常感谢!
    【解决方案3】:

    您永远不会更改 rng 的值,因此它始终指向初始单元格

    Set rng = rng.Offset(1, 0)复制到循环之前的新行

    另外,您的InStr 测试将始终失败
    True 为 -1,但当找到字符串时,InStr 的返回值将大于 0。将测试更改为 remove = True

    新代码:

    Sub IfTest()
     'This should split the information in a table up into cells
     Dim Splitter() As String
     Dim LenValue As Integer     'Gives the number of characters in date string
     Dim LeftValue As Integer    'One less than the LenValue to drop the ")"
     Dim rng As Range, cell As Range
     Set rng = ActiveCell
    
    Do While ActiveCell.Value <> Empty
        If InStr(rng, "%") Then
            ActiveCell.Offset(0, 0).Select
            Splitter = Split(ActiveCell.Value, "% Change")
            ActiveCell.Offset(0, 10).Select
            ActiveCell.Value = Splitter(1)
            ActiveCell.Offset(0, -1).Select
            ActiveCell.Value = "% Change"
            ActiveCell.Offset(1, -9).Select
        Else
            ActiveCell.Offset(0, 0).Select
            Splitter = Split(ActiveCell.Value, "(")
            ActiveCell.Offset(0, 9).Select
            ActiveCell.Value = Splitter(0)
            ActiveCell.Offset(0, 1).Select
            LenValue = Len(Splitter(1))
            LeftValue = LenValue - 1
            ActiveCell.Value = Left(Splitter(1), LeftValue)
            ActiveCell.Offset(1, -10).Select
        End If
    Set rng = rng.Offset(1, 0)
    Loop
    
    End Sub
    

    【讨论】:

    • 很好,感谢inStr测试的讲解!这很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2020-01-14
    • 2015-08-31
    • 1970-01-01
    相关资源
    最近更新 更多