简体   繁体   English

在 VBA 中的单列中匹配一系列行中的“文本”

[英]Matching 'text' in a range of rows in a single column in VBA

Dear stack overflow community:亲爱的堆栈溢出社区:

To be brief, the goal of this program is to allow user to input text in Cell C53 and for the program to find matching text in a string in contained in each row within Column A, then return the text in column B on the same row if found (otherwise, return "Use your best judgement".)简而言之,该程序的目标是允许用户在 C53 单元格中输入文本,并让程序在 A 列中每一行包含的字符串中查找匹配文本,然后返回同一行 B 列中的文本如果找到(否则,返回“使用您的最佳判断”。)

I've successfully created the VBA code to find a matching text in a specific row in Column A and return the value in the same row in column B. However, it only works on one row hardcoded into the code.我已经成功地创建了 VBA 代码以在 A 列的特定行中查找匹配的文本并返回 B 列中同一行中的值。但是,它仅适用于硬编码到代码中的一行。 I need to adjust it to loop through a range of rows in column A because there may be matching text in other rows.我需要调整它以遍历 A 列中的一系列行,因为其他行中可能有匹配的文本。

My code currently looks like this:我的代码目前看起来像这样:

Sub Test_2()

Dim SearchString, SearchText

SearchKey = Range("A1")

SearchNote = Range("C53")

    If InStr(SearchNote, SearchKey) > 0 Then
        Range("C59").Value = Range("B1").Value
    Else
        Range("C59").Value = "Please use your best judgement."
    End If

End Sub

Hence, if A1 contains "limit", and I type into C53 "client wants to upgrade limit", it will return to C59 the text in B1 because it was found.因此,如果 A1 包含“限制”,并且我在 C53 中输入“客户想要升级限制”,它会将 B1 中的文本返回给 C59,因为它已被找到。

The only addition I have been trying to make is nesting what I currently have into a loop to check other rows in Column A. For example, if A1 was "cheque" and A2 was "limit", my current code would only check A1 and not find a match resulting in the prompt "Please use your best judgement."我一直在尝试做的唯一添加是将我当前拥有的内容嵌套到循环中以检查 A 列中的其他行。例如,如果 A1 是“支票”而 A2 是“限制”,我当前的代码只会检查 A1 和找不到匹配项,导致提示“请使用您的最佳判断”。 It should be able to check A1, A2, A3 ... A50 ...它应该能够检查A1,A2,A3 ... A50 ...

I've been having difficulties translating this to code in VBA, and was hoping for some assistance.我在将其转换为 VBA 代码时遇到了困难,希望得到一些帮助。

Find Word in Sentence在句子中查找单词

  • The 1st code goes into a standard module eg Module1 .第一个代码进入标准模块,例如Module1 Only run the 1st procedure which is calling the 2nd procedure when needed.仅在需要时运行调用第二个过程的第一个过程。

  • Adjust the const ants as you see fit.根据您的需要调整常量 If this is used in one worksheet only then you have to change srcName and tgtName to the same string.如果这仅在一个工作表中使用,则必须将srcNametgtName更改为相同的字符串。

  • To automate this, copy the second short code to the sheet module (eg Sheet1 ) worksheet where the Answer and Question Cells are.要自动执行此操作,请将第二个短代码复制到答案和问题单元格所在的工作表模块(例如Sheet1 )工作表中。 Then you run nothing, it's automatic.然后你什么都不运行,它是自动的。

Standard Module eg Module1标准模块,例如Module1

Option Explicit

Public Const queCell As String = "C53"               ' Question Cell

Sub writeAnswer()

    ' Data
    Const srcName As String = "Sheet1"               ' Source Worksheet Name
    Const srcFirstRow As Long = 1                    ' Source First Row Number
    Const srcLastRowCol As String = "A"              ' Source Last Row Column ID
    Dim Cols As Variant: Cols = Array("A", "B")  ' Source Column IDs
    ' Target
    Const tgtName As String = "Sheet1"               ' Target Worksheet Name
    Const ansCell As String = "C59"                  ' Answer Cell
    ' Other
    Const msg As String = "Please use your best judgement." ' Not Found Message
    Dim wb As Workbook: Set wb = ThisWorkbook ' The workbook with this code.
    
    ' Define column range.
    Dim src As Worksheet: Set src = wb.Worksheets(srcName)
    Dim rng As Range
    Set rng = src.Columns(srcLastRowCol).Find("*", , xlValues, , , xlPrevious)
    If rng Is Nothing Then Exit Sub
    If rng.Row < srcFirstRow Then Exit Sub
    Set rng = src.Range(src.Cells(srcFirstRow, srcLastRowCol), rng)

    ' Write values from column range to jagged array (Data(0) & Data(1)).
    Dim ubc As Long: ubc = UBound(Cols)
    Dim Data As Variant: ReDim Data(ubc)
    Dim j As Long
    For j = 0 To ubc
        getRange(Data(j), rng.Offset(, src.Columns(Cols(j)).Column _
                                          - src.Columns(srcLastRowCol).Column))
        If IsEmpty(Data) Then Exit Sub
    Next

    ' Search Data(0) Array for string contained in Question Cell
    ' and write result from Data(1) Array to Answer Cell.
    Dim tgt As Worksheet: Set tgt = wb.Worksheets(tgtName)
    Dim Sentence As String: Sentence = tgt.Range(queCell).Value
    Dim i As Long
    For i = 1 To UBound(Data(0))
        If Sentence = "" Then Exit For
        If Trim(Data(0)(i, 1)) <> "" Then
            If InStr(1, Sentence, Trim(Data(0)(i, 1)), vbTextCompare) > 0 Then
                tgt.Range(ansCell).Value = Data(1)(i, 1)
                Exit Sub
            End If
        End If
    Next i
    
    ' If string not found, write Not Found Message to Answer Cell.
    tgt.Range(ansCell).Value = msg

End Sub

' Writes the values of a range to a 2D one-based array.
Sub getRange(ByRef Data As Variant, DataRange As Range)
    
    Data = Empty
    If DataRange Is Nothing Then Exit Sub
    
    If DataRange.Rows.Count > 1 Or DataRange.Columns.Count > 1 Then
        Data = DataRange.Value
    Else
        ReDim Data(1 To 1, 1 To 1): Data(1, 1) = DataRange.Value
    End If
    
End Sub

Sheet Module eg Sheet1片模块例如Sheet1

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Me.Range(queCell), Target) Is Nothing Then
        writeAnswer
    End If
End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM