在VBA中有两个string匹配时引用特定的单元格值

我试图在VBA中创build一个预测algorithm,它将从数据源中search特定行中的string,并根据行号返回一个值。 这是工作stream程的第一步,最简单的forms有两个表格,如下所示:

来源表:

这是源表,将在其上搜索字符串。

输出表:

在这里输入图像说明

这就是我想要做的:

  1. 拾取输出表(蓝色,黑色)的第1行中的string,并在源表的第1,2,3,4行中search它们。

  2. 如果两个string在一行中匹配,则来自该特定行的“input”单元被复制到“输出”列的输出表中的第1行。

示例(第二次迭代):从输出表第2行中,在源表的所有行中拾取并查询string象牙色,绿色,灰色。 如果在Source Table中的任意一行中有3个string中有2个匹配,则复制该行的input单元格。

在这种情况下,第一行和第四行的象牙和绿色匹配。任何一个input单元都可以工作,但是为了有一个规则,让我们进行最后的匹配(第4行)。 所以'1,8'将被复制到输出表的第2行。

这是我目前正在使用的stream程,但我得到一个不正确的输出:

For i = 2 To 5 For j = 1 To 4 For k = 2 To 5 For l = 1 To 5 If Cells(i, j).Value = Worksheets("SourceTable").Cells(k, l).Value And Cells(i,j).Value <> "" Then For a = 1 To 5 For b = 1 To 4 If Cells(i, b).Value = Worksheets("SourceTable").Cells(k, a).Value And Cells(i, b).Value <> "" Then Cells(i, 15).Value = Worksheets("SourceTable").Cells(k, 5).Value GoTo iLoop End If Next b Next a End If Next l Next k Next j iLoop: Next i 

这两个表将有大约五十万行,我想弄清楚如何减less循环的数量,并在同一时间工作。 任何build议,将不胜感激,这将帮助我节省大量的工时和自动化的一大块过程。 谢谢!

 Sub macro() lastRowOut = Sheets("OutputTable").Range("A" & Rows.Count).End(xlUp).Row lastRowSou = Sheets("SourceTable").Range("A" & Rows.Count).End(xlUp).Row For i = 2 To lastRowOut For j = 2 To lastRowSou If checkRow(j, i) >= 2 Then Sheets("OutputTable").Cells(i, 5) = Sheets("SourceTable").Cells(j, 6) Exit For End If Next j Next i End Sub Function checkRow(sRow, i) lastCol = Split(Sheets("OutputTable").Cells(i, Columns.Count).End(xlToLeft).Address, "$")(1) counter = 0 For Each cell In Sheets("OutputTable").Range("A" & i & ":" & lastCol & i) If Not Sheets("SourceTable").Range("A" & sRow & ":" & "E" & sRow).Find(cell.Value) Is Nothing Then counter = counter + 1 End If Next cell checkRow = counter End Function 

有很多事情是不清楚的,所以这里是我所做的假设:

  • OutputTable中一行中的两个或更多个单元格必须匹配才能进行预测。
  • “输出”和“来源”表格的第一行包含“Col1,Col2”等
  • 你似乎不介意我们是使用第一个还是最后一个匹配的行(从源表),所以我去了第一个。
    这是3循环,而不是6 ..

你可以试试这个

 Option Explicit Sub main() Dim row As Range With Worksheets("OutputTable") For Each row In .Range("D2", .Cells(.Rows.count, 1).End(xlUp)).Rows '<--| change "D" to "OutputTable" sheet last "col" column index (ie the one before "Output" column) SearchSource row Next End With End Sub Sub SearchSource(rng As Range) Dim cell As Range, row As Range Dim nFounds As Long With Worksheets("SourceTable") For Each row In .Range("E2", .Cells(.Rows.count, 1).End(xlUp)).Rows '<--| change "E" to "SourceTable" sheet last "col" column index (ie the one before "Input" column) nFounds = 0 For Each cell In rng.SpecialCells(xlCellTypeConstants) If Not row.Find(what:=cell.Value, lookat:=xlWhole, LookIn:=xlValues) Is Nothing Then nFounds = nFounds + 1 If nFounds = 2 Then Exit For Next If nFounds = 2 Then rng.Cells(, rng.Columns.count + 1).Value = row.Cells(, row.Columns.count + 1).Value Next End With End Sub 

'尝试这个:

首先声明一些variables:

'输出表的行数

  Dim OrNum as integer 

'输出表的列数

  Dim OcNum as integer 

'Source表的行数

  Dim SrNum as integer 

'Source表的列数

  Dim ScNum as integer 

“一些虚拟variables的循环

  Dim rO as integer, cO as integer Dim rS as integer, cS as integer 

'然后假设输出表格的第一个单元格位于输出表格的最上面和最左边,这个单元格取自下面代码中的单元格Z1

'从输出表的第一个单元格开始,通过修改输出表的第一行(rO),然后(外部循环)获得每个'值'下面这样的每一行:

 For rO = 0 to OrNum - 1 For cO = 0 to OcNum - 1 Range("Z1").Offset(rO, cO) Next Next 

'现在你不只有string,所以你需要检查,如果单元格中的值是一个string或数字。 有VBA的function,可以帮助。 它被称为IsNumeric。 如果该值是一个数字值,它会给出“真”。 如果我们有一个string,那么它会给出False。

 For rO = 0 to OrNum - 1 For cO = 0 to OcNum - 1 If IsNumeric(Range("Z1").Offset(rO, cO).Value)=False then 'do something End if Next Next 

对不起,我正在用手机写信,正坐在洗手间里。 我也只有4%。 我会尽快答复。

'尝试这个:

首先声明一些variables:

'输出表的行数

  Dim OrNum as integer 

'输出表的列数

  Dim OcNum as integer 

'Source表的行数

  Dim SrNum as integer 

'Source表的列数

  Dim ScNum as integer 

“一些虚拟variables的循环

  Dim rO as integer, cO as integer Dim rS as integer, cS as integer 

然后声明一个布尔variables(仅供稍后使用)

 Dim bool as boolean 

'然后假设输出表格的第一个单元格位于输出表格的最上面和最左边,这个单元格取自下面代码中的单元格Z1

'从输出表的第一个单元格开始,通过修改输出表的第一行(rO),然后(外部循环)获得每个'值'下面这样的每一行:

 For rO = 0 to OrNum - 1 For cO = 0 to OcNum - 1 Range("Z1").Offset(rO, cO) Next Next 

'现在你不只有string,所以你需要检查,如果单元格中的值是一个string或数字。 有VBA的function,可以帮助。 它被称为IsNumeric。 如果该值是一个数字值,它会给出“真”。 如果我们有一个string,那么它会给出False。 使用函数IsEmpty(),您还可以检查单元格是否为空。 如果单元格为空,则函数IsEmpty将返回True。

 For rO = 0 to OrNum - 1 For cO = 0 to OcNum - 1 bool = IsNumeric(Range("Z1").Offset(rO, cO).Value) bool = bool Or IsEmpty (Range("Z1").Offset(rO, cO).Value) If bool=False then 'we have a string! 'do something End if Next Next 

'尝试这个:

首先声明一些variables:

'输出表格的行数Dim OrNum as integer'输出表格的列数Dim OcNum as integer'源表格的行数Dim SrNum as integer'源表格的列数Dim ScNum作为整数'一些虚拟variables的循环Dim rO作为整数,C0作为整数Dim S作为整数,C作为整数

'然后假设输出表格的第一个单元格位于输出表格的最上面和最左边,这个单元格取自下面代码中的单元格Z1

'从输出表的第一个单元格开始,通过修改输出表的第一行(rO),然后(外部循环)获得每个'值'下面这样的每一行:

 For rO = 0 to OrNum - 1 For cO = 0 to OcNum - 1 Range("Z1").Offset(rO, cO) Next Next 

'现在你不只有string,所以你需要检查,如果单元格中的值是一个string或数字。 有VBA的function,可以帮助。 它被称为IsNumeric。 如果该值是一个数字值,它会给出“真”。 如果我们有一个string,那么它会给出False。

 For rO = 0 to OrNum - 1 For cO = 0 to OcNum - 1 If IsNumeric(Range("Z1").Offset(rO, cO).Value)=False then 'do something End if Next Next