在列中search一个string并打印结果在连续的行中

我有一列列出.cpp文件名和另一列代表testing用例。 我想search工作表中与testing用例string匹配的所有行,并从该行中打印文件名。

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时,该函数失败

你面对的问题是 – 根据你的评论 – 你想要一个用户定义函数 – 但是然后尝试修改工作表。 这是不可能的,因为UDF的体系结构是你不能改变任何东西到工作表中,而只是返回一个你的函数的值 – 然后显示。 另外,在UDF中,通常不允许读取任何其他单元格的值,而不是作为parameter passing的单元格的值 – 否则这将导致Excel认为某处存在循环引用。

所以我看到以下三个select:

  1. 修改你的UDF
  2. 创build一个macros来填充所有单元格
  3. 只使用Excel公式

以下是详细信息:

1.修改你的UDF

假设你在A1中input'testcase1',build立一个你可以这样调用的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 

然而,这种方法非常低效,因为您需要每次parsing源列表。 你可以用一些内部的,模块范围的variables来加速这个variables,这些variables是在第一次调用中初始化的,稍后再用 – 但是你需要注意检测变化。 或者,你用一个大的数组公式来做。 但是,这两种方法都是相当费力的。

2.创build一个macros来填充所有单元格

而不是一个UDF,你有一个macros在一个仓促填充你所有的细胞。 如果要自动更新内容,请每当源数据更改时从Worksheet_Change事件中调用该macros。

这段代码应该这样做:

 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中的testing用例和testing用例名称列表位于第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)), “”)

这是一个数组公式,所以用CtrlShiftEnterinput

HTH!