【问题标题】:Calculate Excel formulas in VBA but display only the value in Excel在 VBA 中计算 Excel 公式,但仅在 Excel 中显示值
【发布时间】:2017-09-15 08:37:35
【问题描述】:

这是我的第一篇文章,我无法在任何地方找到确切的答案。我的 Excel 电子表格变得太大而无法操作,因为我在数百万个单元格中有很长的公式。我需要知道如何使用 VBA 计算公式,但只有值出现在 Excel 中。一个例子是我想将 B 列乘以 C 列:

我试过这段代码:

Range("D3:D6").Formula = Evaluate("=B3*C3")

它正确计算了第一个单元格,但对于其他单元格,它仍然尝试将 B3*C3 计算为固定参考,而不是作为随单元格位置变化而变化的动态参考。

我该如何解决这个问题?谢谢。

编辑:

我的实际电子表格如下所示:

这个公式需要向下应用 17520 行和 300 列,但我只希望这些值出现在 Excel 中。这样做的目的是减小文件大小并减少计算时间。

=IF(-SUMIF(AIG$4:AIG4,"<0")>0.9*SUMIF(AIG$4:AIG4,">0"),0,IF(-SUMIF(AIG$4:AIG4,"<0")-IF(WQ5<'Battery Specs'!$B$13,-'Battery Specs'!$B$15,IF(WQ5=ROUNDDOWN('Battery Specs'!$B$13,0)+1,-('Battery Specs'!$B$13-ROUNDDOWN('Battery Specs'!$B$13,0))*'Battery Specs'!$B$15,0))>0.9*SUMIF(AIG$4:AIG4,">0"),-(0.9*SUMIF(AIG$4:AIG4,">0")+SUMIF(AIG$4:AIG4,"<0")),IF(WQ5<'Battery Specs'!$B$13,-'Battery Specs'!$B$15,IF(WQ5=ROUNDDOWN('Battery Specs'!$B$13,0)+1,-('Battery Specs'!$B$13-ROUNDDOWN('Battery Specs'!$B$13,0))*'Battery Specs'!$B$15,IF((0.9*SUMIF(AIG$4:AIG4,">0")+SUMIF(AIG$4:AIG4,"<0"))>'Battery Specs'!$B$10,0,IF(((0.9*SUMIF(AIG$4:AIG4,">0")+SUMIF(AIG$4:AIG4,"<0"))+$AIF5*0.9)>'Battery Specs'!$B$10,'Battery Specs'!$B$10-(0.9*SUMIF(AIG$4:AIG4,">0")+SUMIF(AIG$4:AIG4,"<0")),$AIF5))))))

【问题讨论】:

    标签: excel vba excel-formula


    【解决方案1】:

    试试

    Range("D3:D6").Formula = "=B3*C3"
    Range("D3:D6").Value = Range("D3:D6").Value
    

    或者干脆

    Range("D3:D6").Formula = Evaluate("(B3:B6)*(C3:C6)")
    

    【讨论】:

    • 非常感谢。但是,我不相信这会减少我在 Excel 中处理大型电子表格/公式的时间,因为代码的第一行将公式放在所有单元格中。有没有其他方法可以做到这一点?
    • @Tyce - 尝试回答Range("D3:D6").Formula = Evaluate("(B3:B6)*(C3:C6)")中的第二个选项
    • 为了进一步提高性能,可能值得在运行代码时关闭屏幕更新。 (更好的办法是将结果收集到一个数组中,并在必要时一次性写入,但我认为这一步太远了)。
    • @Mrig - 再次感谢你 - 抱歉我的电脑没有更新你的编辑。第2行很棒。我如何将它应用于许多列而不需要单独列出每一列?我只是不确定如何将它应用到具有许多 IF 语句和偏移量的实际电子表格中。谢谢。
    【解决方案2】:

    使用 Evaluate 计算公式然后将值传输到 Excel 会比让 Excel 直接计算公式要慢。

    您可以尝试以下几点:

    a) 公式 您在 500 万个单元格中只有 500 万个公式 - 这不是一个非常大的数字,但是您的公式很长,并且每个公式都引用了大量的单元格。 您的公式包含许多重复的表达式和计算 - 将它们移到辅助单元格并尝试简化/缩短您的公式。

    b) VBA - 不要使用 Evaluate - 只需将 500 万个单元格的范围抓取到单个变体数组中,然后使用 VBA 循环、算术和逻辑来完成与公式相同的任务,然后将数组放回原处。

    【讨论】:

    • 谢谢查尔斯。创建辅助单元格会减小文件大小/提高计算速度吗?因为每次我创建一组辅助单元格时,都会有另外 500 万个。至于 VBA,不幸的是我的 VBA 技能还不足以在没有很多帮助的情况下创建所需的循环。
    【解决方案3】:

    我认为最好的选择是保留公式,而不是使用 VBA 来生成相同的公式。相反,在电子表格中输入新数据时,请务必将计算设置为手动(转到Formulas tab=>Calculation Options=>Manual。这样您在输入/粘贴新值时不会触发计算,这意味着您的 Excel文件将像没有公式一样快速运行。输入/粘贴所有新值后,将 Calculations 设置为 Automatic

    【讨论】:

    • 嗨克雷西米尔。谢谢你的建议。我已经尝试过了,但电子表格仍然太慢(打开它需要几个小时 - 现在是 560MB),我相信目前减小大小的最佳方法是防止 Excel 必须存储数百万个长公式我在用。如果我错了,请纠正我
    • 你是对的。如果文件那么大,请尝试将其保存为 XLSB 格式,默认为压缩格式。您应该在打开文件/减小大小和更好的计算速度方面得到一些改进(不确定最后一个)。
    • 我会说在 560MB 这样大小的情况下,值得尝试将这些数据拆分为单独的工作簿或将其存储在比 Excel 更快的东西中
    • @B Slater 谢谢。如果我能让它工作足够长的时间,那可能就是我对电子表格所做的事情。您建议以什么方式存储/计算它?我对其他程序没有经验。 Matlab 是个不错的选择吗?
    【解决方案4】:

    你可能想试试这个:

    Dim i as Integer
    
    For i = 3 to 6
        Range("D" & i).Value = Range("B" & i).Value * Range("C" & i).Value
    Next i
    

    【讨论】:

      【解决方案5】:

      另一种选择是给你的公式命名,例如,不要说 =B3*C3,你可以给它一个名字,说 times value,然后说 =timesvalue。接下来,删除公式并仅保留值。例如。 range("D3:D30").value=range("D3:D30").value

      【讨论】:

        猜你喜欢
        • 2017-06-16
        • 1970-01-01
        • 2013-04-24
        • 1970-01-01
        • 2017-07-17
        • 1970-01-01
        • 2016-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多