2

我在处理我的大型电子表格时遇到了一些问题。我将大量原始数据引入数据表,然后对数据进行多次查找。使用我想出的内置函数

=IF(ISNA(INDEX(Data!$L$7:$L$1100,MATCH(Data!$I$2&$B$199&$B29&Data!$J$5,Data!$K$7:$K$1100&Data!$J$7:$J$1100&Data!$I$7:$I$1100&Data!$N$7:$N$1100,0))),"0",INDEX(Data!$L$7:$L$1100,MATCH(Data!$I$2&$B$199&$B29&Data!$J$5,Data!$K$7:$K$1100&Data!$J$7:$J$1100&Data!$I$7:$I$1100&Data!$N$7:$N$1100,0)))

不漂亮!基本上,它使用 4 个变量进行两次相同的查找,并将它们与 4 个连接数组进行匹配,然后使用该点作为我想要的值的索引。

我在每行 4 张纸和每张纸 96 行中有 8 个(略有不同)。编辑它们很痛苦!

由于本月数据集大幅增长,外部波段 (x1100) 已被超越(经验教训,大是不够的)。不幸的是,该功能的限制不允许我使用 L:L 或类似的任何有用的东西。

我尝试将代码重写为用户定义的函数,我可以在其中输入 4 个变量并获得答案,但是在组合数组时失败了。

我已经在原始函数名称中给出了上面列出的范围以使事情变得更容易(并将它们扩展为使用更广泛的范围值),因此我可以重写所有函数以仅使用命名范围,但这仍然让我陷入困境如果我需要更改代码。

这是我到目前为止所拥有的:

    Function Windows_Util(itma As String, env As String)

v = "Windows Server" & env & itma & ""
r = Concat(Range("Utilchassis"))
r = r & Concat(Range("Utilenv"))
r = r & Concat(Range("UtilITMA"))
r = r & Concat(Range("UtilOS"))

m = WorksheetFunction.Match(v, r, 0)

i = WorksheetFunction.Index(Range("Utilavg"), m)


If WorksheetFunction.IsNA(i) Then
    Windows_Util = 0
Else
    Windows_Util = i
End If

End Function


Function Concat(myRange As Range, Optional myDelimiter As String)

Dim r As Range

Application.Volatile

For Each r In myRange
   If Len(r.Text) Then
       Concat = Concat & IIf(Concat <> "", myDelimiter, "") & r.Text
   End If
Next

End Function

这不行!它不仅连接不正确(每个范围单独连接,而不是逐行组合),而且它不喜欢其中一个查询中的某种类型。(调试这些东西并不容易,因为函数实际上完成了(它没有任何语法错误),所以我没有可以使用的内置步骤。

非常感谢任何帮助。

希望我已经提供了足够的细节来理解我正在尝试做的事情。

干杯,

史蒂夫

4

3 回答 3

1

我不确定您希望如何连接 Ranges,但我认为您应该看看Application.Union(Range, Range, ...) method

在文章的示例中:

Set bigRange = Application.Union(Range("Range1"), Range("Range2"))

另请参阅Tushar Mehta 撰写的 Daily Dose of Excel 中的文章,他在其中描述了以下自定义 Union(Range, Range) 方法,该方法可以更好地处理“Nothing”(空)输入:

Function Union(Rng1 As Range, Rng2 As Range) As Range
    If Rng1 Is Nothing Then
        Set Union = Rng2
    ElseIf Rng2 Is Nothing Then
        Set Union = Rng1
    Else
        Set Union = Application.Union(Rng1, Rng2)
    End If
End Function

相反,如果您要使用范围地址的字符串连接,那么您必须添加逗号,正如 Barrowc 在他的帖子中所展示的那样。例如Range("MyRange1, MyRange2"),将合并名为“MyRange1”和“MyRange2”的两个范围,而没有逗号的空格分隔符,例如Range("MyRange1 MyRange2")将返回这两个范围的 INTERSECTION(重叠)。

但是,我建议避免串联字符串地址并改用该Application.Union(Range, Range)方法。

希望这可以帮助...

于 2009-01-11T02:22:21.330 回答
1

怎么样:

r = Range("Utilchassis,Utilenv,UtilITMA,UtilOS")

这似乎与您的 Concat 功能相同

于 2009-01-10T04:30:55.547 回答
0

当有多个要匹配的标准时,在 VBA 中使用 MATCH 函数可能会很棘手。在工作表中所做的事情——将不同单元格连接的条件与相同数量的连接范围匹配,在这两种情况下都使用 & 运算符——在 VBA 中是无法实现的,因为 VBA“&”运算符只将字符串作为参数,并且因为在 VBA 中连接范围的其他方式、Union 函数和通过 Range 的多个地址参数进行的赋值,似乎不会产生一个可以与 VBA Match 函数一起使用的数组。

但是,可以通过构造一个结合 MATCH 和数组比较的工作表公式,然后使用 VBA Evaluate 函数执行该公式来实现相同的效果。有关此方法如何工作的详细信息,请参阅我对 这个 SO 问题的回答。

以下代码实质上重新实现了 Steve 提供的原始工作表公式,而不依赖于工作表中先前命名的范围或代码中指定的标准值(与工作表中的特定单元格相反)。它被编写为一个子函数,但可以很容易地转换为用户定义的函数。

  Sub x4match()

    Dim adr1 As String, adr2 As String, adr3 As String, adr4 As String
    Dim Rng1 As Range, Rng2 As Range, Rng3 As Range, Rng4 As Range
    Dim name1 As String, name2 As String, name3 As String, name4 As String
    Dim idx As Variant
    Dim resultRng As Range
    Dim result As Variant

    With ThisWorkbook.Worksheets("Data")

       adr1 = "I2"
       adr2 = "B199"
       adr3 = "B29"
       adr4 = "J5"

       Set Rng1 = .Range("K7:K1100")
       Set Rng2 = .Range("J7:J1100")
       Set Rng3 = .Range("I7:I1100")
       Set Rng4 = .Range("N7:N1100")
       Set resultRng = .Range("L7:L1100")

       .Names.Add Name:="name1", RefersTo:=Rng1
       .Names.Add Name:="name2", RefersTo:=Rng2
       .Names.Add Name:="name3", RefersTo:=Rng3
       .Names.Add Name:="name4", RefersTo:=Rng4

       idx = Evaluate("IFERROR( MATCH(1, --(" & adr1 & "=name1) * --(" & _
                     adr2 & "=name2) * --(" & adr3 & "=name3) * --(" & _ 
                     adr4 & "=name4), 0), 0)")

       If idx <> 0 Then
          result = .Cells(resultRng.Row + idx - 1, resultRng.Column).Value
       End If

      .Names("name1").Delete
      .Names("name2").Delete
      .Names("name3").Delete
      .Names("name4").Delete

    End With

  End Sub
于 2013-01-19T06:27:20.040 回答