我有一个Excel工作表,在近50列上传播最多150000行数据。这都是价值观。
我正在使用VBA向工作表添加新行(通常一次不超过20000行),实际上有一列需要计算结果。因此,可以评估20 000个公式(最大值)。如果我尝试Worksheet.Calculate
,我会收到此页面上描述的错误:http://support2.microsoft.com/kb/2655178
另一种方法是使用带有Range.Calculate
循环的For
方法,使用VBA逐个评估单元格。它确实可以工作并完成工作,但是需要花费大量时间来遍历单元格。
我可以做任何替代或优化吗?复制新行后,这是我添加的公式,并尝试评估最多20k个单元格(在同一列中):
With ActiveSheet
.Cells(lastRow, lastCol - 1).FormulaArray = "=IFERROR(LEFT($AK" & lastRow & ",LEN($AK" & lastRow & ")-2-LEN(INDEX($AK:$AK,MATCH(1,($A:$A=$A" & lastRow & ")*($AQ:$AQ=INDEX(Month,1,MATCH($AQ" & lastRow & ",Month,0)-1)),0)))),$AK" & lastRow & ")"
.Range("AP" & lastRow).AutoFill .Range("AP" & lastRow & ":AP" & .Range("A" & .Rows.Count).End(xlUp).row)
.Range(.Cells(lastRow, lastCol - 1), .Cells(.Range("A" & .Rows.Count).End(xlUp).row, lastCol - 1)).Value = .Range(.Cells(lastRow, lastCol - 1), .Cells(.Range("A" & .Rows.Count).End(xlUp).row, lastCol - 1)).Value
End With
LastCol - 1
是包含计算的列(始终对应于列AP),在导入新行之前评估LastRow
(因此它基本上是上面示例中新数据的第一行) )。 Application.ScreenUpdating
设置为false,Application.Calculation
设置为xlCalculationManual
。
如果我在工作表中总共有超过一定数量的行,那么Excel会返回一个错误(带公式的单元格数总是少于感谢20k)如果我尝试这样做:
ActiveSheet.Calculate
然而这可行,但需要数小时:
For i = lastRow To .Range("A" & .Rows.Count).End(xlUp).row
ActiveWorksheet.Range("AP" & i).Calculate
Next i
具有公式的单元格始终位于列AP中,仅适用于新的数据行,因为如前所述,结果将在计算后转换为值。
为了更好地解释为什么我需要Excel公式,这里有一个我拥有的数据的例子:
ID|Users |Month
-----------------------------------------
1|AA1234 |September
2|BB1234 AA1234 |September
1|BB1234 AA1234 |October
2|AA1234 CC1234 BB1234 AA1234|October
我想为每个ID的当月用户创建一个新列,例如在10月份为ID 2,我想要用户AA1234 CC1234
,因为我们知道其他2个用户实际上已经工作过该身份证不是10月份,而是9月份。我的工作簿中有一个命名范围Month = {"January", ..., {"December"}
。
答案 0 :(得分:0)
答案是@Jeeped对原始问题的评论,但由于他仍然没有将其作为答案发布,因此这里是为了清晰起见:
这不是公式数量的问题;是什么杀了你的 计算资源是使用完整列的数组公式 引用。将完整列引用减少到150K行 您拥有的实际数据会有所帮助,但阵列处理会消耗掉 资源以不变的对数率增长。我试图破译 你的公式,看看2010年的功能是否更新(更有效) 应用但没有样本数据,后一部分似乎是圆形的 逻辑。也许你可以编辑一些数据并将其发布到某个地方。如果你 do,将其中一个数组公式保留在AP列中。