【问题标题】:Excel ran out of resources while attempting to calculate one or more formulasExcel 在尝试计算一个或多个公式时用尽了资源
【发布时间】:2013-02-26 01:48:43
【问题描述】:

我有一本工作簿可以对我的开支做“智能”图表。它已经运行了一年,现在有很多图表和费用。现在,每当我更改任何内容或打开工作簿时,Excel 都会引发资源不足错误。问题是,我有 很多 资源,而且几乎没有使用任何资源。

Win8 64bit w/ 8 core CPU and 32GB of ram
Office 2013 64bit

我有 2 张工作表,第一个名为 Expenses 的工作表有 3 列 [Date,Description,Amount] 和大约 1500 行数据。第二张表有很多(大约 500 个)公式,它们都是相同的,旨在“总结日期 X 和 Y 之间的所有费用,其中描述匹配-一些针-”。我的公式是这样的:

=
ABS(
    SUMPRODUCT(
        --(Expenses!A:A >= DATE(2011,12,1)), 
        --(Expenses!A:A < DATE(2012,1,1)), 
        --(ISNUMBER(FIND(C50,Expenses!B:B))),
        Expenses!C:C
    )
)

我可以给 Excel 更多资源吗? (我很高兴它使用了我所有的内存,并占用了我的 CPU 几分钟)。

有没有更有效的方法可以做这个公式?

我知道这个公式正在创建一个大网格并用它来掩盖我的费用清单,并且必须为每个公式创建这个网格。我应该创建一个宏来更有效地执行此操作吗?如果我有一个宏,我想以某种方式从单元格中调用它,例如

=sumExpenses(<startDate>, <endDate>, <needle>)

这可能吗?

谢谢。

【问题讨论】:

  • 单个对象可能变得太大。语言(例如 .NET)对单个对象的大小有大小限制。
  • 我想。我希望其他用户的工作簿比我大得多、复杂得多。我很惊讶我已经遇到了这么小的数据集的问题。
  • 这是一个漂亮的漂亮的 excel 弹出错误还是一个愤怒的 Windows 错误?
  • --sumproduct 中的数组之前做了什么?从未真正使用过它,也无法弄清楚它的用途。
  • (1) SUMIFSSUMPRODUCT 更有效 (2)如果工作簿损坏,我会尝试“重生”文件,方法是右键单击工作表选项卡,“移动或复制”,然后选择新书(3)尝试将公式的范围缩小到实际使用的行

标签: excel excel-2013 vba


【解决方案1】:

这可能有很多原因。我只是希望 Excel 能告诉我们哪个(或更多)“通常的嫌疑人”此时正在犯下占用 RAM 的罪行。

同时寻找

  1. 循环引用

  2. 分段条件格式(由剪切、粘贴、排序、删除和添加单元格或行引起。

  3. 导致 #N/A、#REF、#DIV/0 的错误!等等,

  4. 过度使用 volatile 函数 TODAY()、NOW() 等

  5. 使用了太多不同的格式

...按这个顺序

当你在那里时,检查

  1. 链接断开。依赖于来自外部数据的新值的公式可能会返回错误。

  2. 任何包含 #REF! 的公式。如果你的公式很乱,这些也可能存在。它们不会导致错误标志,但可能会导致一些未报告的错误。如果您的公式满足较早的条件,则公式部分包含#REF!在其他条件成立之前不会进行评估。

【讨论】:

    【解决方案2】:

    我遇到了一个类似的问题,其中有一些数组公式在大约 150 行之后出现了这个错误,这真的让我感到困惑,因为实际上没有那么多公式要计算。我联系了我们的 IT 人员,他解释了以下内容,其中一些我明白,大部分我不明白:

    通常,当计算机尝试处理大量数据时,它会使用多线程计算,即使用计算机欺骗自己认为自己拥有的所有 8 个处理器。关闭多线程计算时,电脑不会抛出“Excel用尽资源...”错误。

    要关闭多线程计算,请转到 Excel 工作簿中的“文件”选项卡并选择“选项”。在出现的框的右侧,选择“高级”并向下滚动到标题“公式”。在该标题下是一个复选框,显示“启用多线程计算”。取消勾选,然后选择“确定”并重新计算您的公式。

    【讨论】:

    • 帮我解决了,非常有见地!
    【解决方案3】:

    我尝试创建一个函数,希望能够复制您当前在 VBA 中所做的方程式,但有一些不同之处。由于我不知道您的第二张工作表的细节,因此缓存可能根本没有帮助。

    如果您的第二张工作表对sumExpenses 的所有调用都使用相同的日期范围,那么它应该会更快一些,因为它会在第一次通过时预先汇总所有内容,如果您的日期范围在整个过程中发生变化,那么它只是做了很多不劳而获。

    Public Cache As Object
    Public CacheKey As String
    
    Public Function sumExpenses(ByVal dS As Date, ByVal dE As Date, ByVal sN As String) As Variant
    Dim Key As String
    Key = Day(dS) & "-" & Month(dS) & "-" & Year(dS) & "_" & Day(dE) & "-" & Month(dE) & "-" & Year(dE)
    
        If CacheKey = Key Then
            If Not Cache Is Nothing Then
                If Cache.Exists(sN) Then
                    sumExpenses = Cache(sN)
                    Exit Function
                End If
                Set Cache = Nothing
            End If
        End If
        CacheKey = Key
        Set Cache = CreateObject("Scripting.Dictionary")
    
        Dim Expenses As Worksheet
        Dim Row As Integer
        Dim Item As String
    
        Set Expenses = ThisWorkbook.Worksheets("Expenses")
    
        Row = 1
    
        While (Not Expenses.Cells(Row, 1) = "")
            If Expenses.Cells(Row, 1).Value > dS And Expenses.Cells(Row, 1).Value < dE Then
                Item = Expenses.Cells(Row, 2).Value
                If Cache.Exists(Item) Then
                    Cache(Item) = Cache(Item) + Expenses.Cells(Row, 3).Value
                Else
                    Cache.Add Item, Expenses.Cells(Row, 3).Value
                End If
            End If
            Row = Row + 1
        Wend
    
        If Cache.Exists(sN) Then
            sumExpenses = Cache(sN)
        Else
            sumExpenses = CVErr(xlErrNA)
        End If
    
    End Function
    
    Public Sub resetCache()
        Set Cache = Nothing
        CacheKey = ""
    End Sub
    

    【讨论】:

    • 如果您要将它用作 UDF,则必须将 Application.Volatile True 设置为函数的第一行。否则它永远不会重新计算。但是,拥有大量易失性 UDF 可能会减慢工作簿的速度。如果你不让它变得易变,它只会在你编辑调用它的单元格中的公式时重新计算。如果您有 500 个单元格调用该 UDF,那么这将意味着 500 次编辑。见参考here
    • 这真的很有用@NickSlash!缓存是否会保留对象以供下一个函数使用?我正在考虑创建一个 UDF,首先它将所有费用读入保存 [date,desc,amnt] 的 UserDefinedTypes 集合。 UDF会检查缓存是否存在,如果存在,则根据缓存计算,如果不存在,则构建缓存,然后根据它进行计算。
    • @NickSlash,我刚刚测试了持久性,它有效!我将根据您的情况对您的回答进行一些调整,谢谢您的帮助-我不知道 UDF。
    • @barrowc,在我的测试=sumExpenses(D1, E1, F1) 中,如果我更改了D1E1F1,结果会更改为正确的值。虽然它是真的,但结果可能已经过时了,但它仍然发生了变化。 (这没有Application.Volatile 或用公式修改单元格)我想这不是你指的?你能再解释一下吗?
    • 抱歉,我现在明白你的意思了。如果源数据发生变化而不是函数的参数?由于缓存的工作方式,即使当前使用Application.Volatile,该函数也不会返回新结果。
    猜你喜欢
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    相关资源
    最近更新 更多