在列中搜索字符串并在连续的行中打印结果

时间:2013-02-14 17:16:46

标签: excel vba

我有一列包含.cpp文件名列表,另一列表示测试用例。我想搜索工作表中与测试用例字符串匹配的所有行,并打印该行的文件名。

column 1        column2 
--------       ------------    
file1.cpp      testcase1   
file2.cpp      testcase1   
file3.cpp      testcase3    
...             .......    
....            .......     

所以最后我想要一个看起来像这样的输出:

Testcase1   Testcase2     
file4.cpp   file5.cpp    
file9.cpp   file8.cpp     
file5.cpp   file13.cpp  

这是vba代码:

Function fileToTest(Search_string As String, _
Search_in_col As Range)

Dim result As String   
Dim i As Long   
Dim j As Long   
Dim rArray(20) As String    
Dim rCnt As Long   
Dim rTmp As String   
Dim found As Long   
Dim testCases, Value As Variant   
Dim currentRow As Long    
Dim fCnt As Long    

  For i = 1 To Search_in_col.Count 'search each test case column    
     testCases = Split(Search_in_col.Cells(i, 1), ";")    
     For Each Value In testCases    
         If Search_string = Value Then    

        ActiveCell.Value = Search_in_col.Cells(i, 2).Value    
         ' write the next row after active cell. not sure how to do this
        End If   
      Next Value   
   Next i   


End Function   

当我尝试写入ActiveCell.Value

时,该函数失败

1 个答案:

答案 0 :(得分:0)

您面临的问题是 - 根据您的评论 - 您需要用户定义的功能 - 但随后尝试修改工作表。这是不可能的,因为UDF的体系结构是您不能将任何内容更改为工作表,而只返回您的函数的值 - 然后显示该值。此外,在UDF中,通常不允许读取任何其他单元格的值而不是作为参数移交的单元格的值 - 否则这将导致Excel认为某处存在循环引用。

因此,我看到以下三个选项:

  1. 修改您的UDF
  2. 创建一个填充所有单元格的宏
  3. 仅使用Excel公式
  4. 以下是详细信息:

    <强> 1。修改您的UDF

    假设您在A1中输入'testcase1',构建一个可以像这样调用的UDF:

    =FileToTestCase(A1,1,SourceSheet!A2:A100,SourceSheet!B2:B100)
    

    UDF的VBA定义将是这样的:

    Public Function FileToTestCase(sTestCaseName as String, iElementNumber as Integer, _
        rngFileNames as Range, rngTestcases as Range) as String
        CodeToFigure out the iElementNumer_th entry for sTestCaseName
        FileToTestCase = YourResult
     End Function
    

    然而,这种方法非常低效,因为您每次都需要解析源列表。您可以使用在第一次调用中初始化并稍后使用的一些内部模块范围变量加快速度 - 但是您需要注意检测更改。或者,您可以使用一个大数组公式。但是,这两种方法都付出了相当大的努力。

    <强> 2。创建一个宏,用于填充所有单元格

    而不是UDF,你有一个宏可以在一次冲动中填充所有单元格。如果要自动更新内容,请在每次源数据更改时从Worksheet_Change事件中调用宏。

    此代码应执行此操作:

    Sub FillTestcases(rngFiles As Range, rngTestcases As Range, rngStartResult As Range)
        Dim d As New Scripting.Dictionary
        Dim lRow As Long
        Dim sTestCase As Variant
        Dim sFile As Variant
        Dim rngResult As Range
        Const csSeparator As String = "|"
    
        For lRow = 1 To rngFiles.Rows.Count
            sTestCase = rngTestcases(lRow, 1).Value
            sFile = rngFiles(lRow, 1).Value
            If d.Exists(sTestCase) Then
                d(sTestCase) = d(sTestCase) & csSeparator & sFile
            Else
                d.Add sTestCase, sFile
            End If
        Next
    
        Set rngResult = rngStartResult
        For Each sTestCase In d.Keys
            rngResult.Value = sTestCase
            rngResult.Font.Bold = True
            lRow = 1
            For Each sFile In Split(d(sTestCase), csSeparator)
                rngResult.Offset(lRow) = sFile
                lRow = lRow + 1
            Next sFile
            Set rngResult = rngResult.Offset(, 1)
        Next sTestCase
    End Sub
    

    请注意,您需要添加对 Microsoft Scripting Runtime 的引用才能使用Dictionary类。另请注意,此代码不会合并重复项,因此您可能需要进行调整。

    第3。仅使用Excel公式

    假设您的文件名在A1:A10中,B1:B10中的测试用例和测试用例名称列表在第1行,从F列开始,在F2中使用此公式:

    =IFERROR(INDEX($A$1:$A$10,-INT((LARGE(($B$1:$B$10=F$1)-ROW($B$1:$B$10)/10000,ROW(F1))-1)*10000)),"")
    

    这是一个数组公式,所以输入 Ctrl - Shift - 输入

    HTH!