数组公式到VBA

我有一个名为“城市”和“数据”的Excel工作表。 “数据”页面包含108264行数据,列一直向上到列AT。

在“城市工作表”下,我列出了从B4到B214行的210个城市。 在它旁边(C列)列出了每个城市使用的代码数(即该城市使用了多less代码)。 接下来的20列(D列到W列)应显示每个城市最常用的代码序列(即最不常用的最常用代码)。 我用样本伪数据集附上图像,以提供我所指的内容的graphics表示。

城市工作表

数据工作表

如果你看城市“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开始拖动公式,并根据前一列的数据自动计算常用代码的频率。

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

我有两个数组公式,我用这个(即计数最常用的代码,比取决于前一列的值,返回下一个最常用的代码)。 问题是,由于如此庞大的数据集,为每个单元格创build一个数组公式会耗费大量时间,并会显着降低Excel电子表格的速度。

所以,这是我迄今为止所尝试的:

  1. 数组公式(请参阅附表)
  2. 在VBAs之下。 第一个返回运行时错误“1004”无法设置范围类的FormulaArray属性 ,而第二个什么都不做。

任何build议或帮助加快arrays公式,或相应地修改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 

第一个提示:

在你的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)))),"""")"