【问题标题】:Array formula to VBA数组公式到 VBA
【发布时间】:2014-02-21 06:30:16
【问题描述】:

我有一个 Excel 电子表格,其中包含两个名为“城市”和“数据”的工作表。 “数据”页面包含 108264 行数据,列一直到 AT 列。

在城市工作表下,我有一个从 B4 到 B214 行的 210 个城市的列表。旁边(C 列)是每个城市使用的代码计数列表(即该城市使用了多少代码)。接下来的 20 列(D 到 W 列)应显示每个城市最常用的代码序列(即最常见到最不常见)。我附上了带有示例伪数据集的图像,以提供我所指内容的图形表示。

如果您以城市“1”为例(第 4 行“城市”),您会注意到它的计数为 5,最常用的代码是 5,然后是 4,然后是 3,然后是 2 和最后 1. 如果您参考“数据”图像,您可以看到相关性。

我用于此示例集的数组公式如下:

在“城市”的 D4 中

      {=IFERROR((MODE(IF(ISNUMBER(SEARCH(B4,Data!$B2:$B6)),IF(ISNUMBER(Data!$K2:$AT6),Data!$K2:$AT6)))),"")}

在“城市”的E4中

{=IFERROR(MODE(IFERROR(SMALL(IF(ISNUMBER(SEARCH($B$4, Data!$B2:$B6))*ISNUMBER(1/Data!$K2:$AT6)*ISNA(MATCH(Data!$K2:$AT6,$D4:D4,0)),Data!$K2:$AT6,""),ROW(INDEX($A:$A,1):INDEX($A:$A,COUNT(Data!$K2:$AT6)))),"")),"")}

然后我把公式从E4往前拖,它会根据上一列的数据自动统计常用代码出现的频率。

目标是这样的:对于“城市”工作表中注明的每个城市,我想通过从“数据”中搜索 B 列和 K 列到 AT 来返回这 20 个最常用的代码” 工作表。所以它会在 B 列中查找城市,然后查看 K 到 AT 列中常用的代码。

我确实有两个用于此的数组公式(即计算最常用的代码,而不是根据上一列中的值返回下一个最常用的代码)。问题是,由于数据集如此庞大,为每个单元格创建一个数组公式变得非常耗时,并且大大降低了 Excel 电子表格的速度。

所以,这是我目前为止尝试过的:

  1. 数组公式(另请参阅随附的表格)
  2. 低于 VBA。第一个返回运行时错误“1004”无法设置 Range 类的 FormulaArray 属性,而第二个什么也不做。

对于加快数组公式或相应地修改 VBA 的任何建议或帮助将不胜感激。如果您也有备用 VBA,那也将不胜感激。

谢谢。

Sub Option1()
     Dim r As Long
     For r = 4 To 214
        Sheet2.Cells(r, 210).FormulaArray = _
        "=IFERROR((MODE(IF(ISNUMBER(SEARCH(C" & CStr(r) & ", Data!$B$2:$B$108264)),IF(ISNUMBER(Data!$K2:$AT108264),Data!$K2:$AT108264)))),"")"
    Next r
 End Sub



Sub Option2()

    Sheet1.Range("C4").FormulaArray = _
        "=IFERROR((MODE(IF(ISNUMBER(SEARCH(C4, Data!$B$2:$B$108264)),IF(ISNUMBER(Data!$K2:$AT108264),Data!$K2:$AT108264)))),"")"

    Sheet1.Range("D4:D214").FillDown

End Sub

【问题讨论】:

    标签: arrays vba excel


    【解决方案1】:

    第一个提示:

    在您的两个 VBA 公式的最后部分,您有 "":

    ...Data!$K2:$AT108264)))),"")"
    

    在 VBA 中,如果要在公式中包含引号,则应使用双引号:"""" 而不是 ""

    第二个提示:

    无需使用循环将公式应用于范围内的每个单元格:

    For r = 4 To 214
        Sheet2.Cells(r, 210).FormulaArray = "=IFERROR(...C4,...)"
    Next r
    

    如果你愿意,你的代码会快得多(列№210HB):

     Sheet2.Range("HB4:HB214").FormulaArray = "=IFERROR(...C4,...)"
    

    这种方法会自动调整公式中的所有相对/混合引用:

    • HB4 中你会得到=IFERROR(...C4,...)
    • HB5 中你将拥有=IFERROR(...C5,...)
    • ...
    • HB214 中你会得到=IFERROR(...C214,...)

    所以,工作代码是:

    Sheet2.Range("HB4:HB214").FormulaArray = "=IFERROR((MODE(IF(ISNUMBER(SEARCH(C4, Data!$B$2:$B$108264)),IF(ISNUMBER(Data!$K2:$AT108264),Data!$K2:$AT108264)))),"""")"
    

    【讨论】:

    • 谢谢。这非常有用。
    • 可读性提示:四引号太可怕了——当你指定一个复杂的公式时,你弄错它们,而且调试它需要很长时间。所以试试这个:Public Const QQ As String * 2 = """" 将双引号放入引用的字符串中,并将其用作strFormula = QQ & "Today= " & QQ & " & DATE()" ...就是这样,或者 Chr(34)
    • @Dimitry 这种方法对我不起作用......我正在尝试将我的整个范围设置为数组公式,但它没有调整行引用......任何想法为什么会这样?
    • 这是数组公式:"=IF(H2="""",INDEX($H:$H,MATCH(1,($R$34=$A:$A)*($R$35=$B:$B)*(C2=$C:$C)*(D2=$D:$D),0)),H2)"
    猜你喜欢
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多