【问题标题】:Excel: list ranges targeted by INDIRECT formulasExcel:列出间接公式所针对的范围
【发布时间】:2008-08-29 15:49:25
【问题描述】:

我们有一些非常大的 Excel 工作簿(数十个选项卡,每个选项卡超过 1 MB,非常复杂的计算),其中包含数十个甚至数百个使用可怕的 INDIRECT 函数的公式。这些公式分布在整个工作簿中,并针对多个数据表来查找值。

现在我需要将这些公式所针对的数据范围移动到同一工作簿中的不同位置。

(原因不是特别相关,但本身就很有趣。我们需要在 Excel Calculation Services 中运行这些东西,并且一次加载每个相当大的表的延迟时间被证明是不可接受的高。我们正在连续范围内移动表格,因此我们可以一次性加载它们。)

有什么方法可以找到当前引用我们要移动的表的所有 INDIRECT 公式?

我不需要在线执行此操作。只要它可靠,我会很乐意运行需要 4 个小时才能运行的东西。

请注意,.Precedent、.Dependent 等方法仅跟踪直接公式。

(另外,用 whatever 重写电子表格对我们来说不是一种选择)。

谢谢!

【问题讨论】:

  • 出于好奇,该项目已完成(成功)。手动分析、修改和重新测试所有电子表格需要 100 多个工时(我确实说过它们很大!)。好吧,它并没有我刚才说的那么糟糕:无论如何,我们都会进行广泛的重新测试。

标签: excel vba


【解决方案1】:

您可以使用 vba 遍历整个 Workbook(我已包含来自 @PabloG 和 @euro-micelli 的代码):

Sub iterateOverWorkbook()
For Each i In ThisWorkbook.Worksheets
    Set rRng = i.UsedRange
    For Each j In rRng
        If (Not IsEmpty(j)) Then
            If (j.HasFormula) Then
                If InStr(oCell.Formula, "INDIRECT") Then
                    j.Value = Replace(j.Formula, "INDIRECT(D4)", "INDIRECT(C4)")
                End If
            End If
        End If
    Next j
Next i
End Sub

此示例将每次出现的“indirect(D4)”替换为“indirect(C4)”。如果您有更复杂的间接函数,您可以轻松地将替换函数替换为更复杂的函数。性能还不错,即使对于更大的工作簿也是如此。

【讨论】:

  • 我接受这个答案,因为它是唯一获得投票的答案,它确实提供了我们发现的唯一已知方法。完整的答案是“不,Excel 不支持为您定位间接公式,您必须使用 VBA 来扫描自己。”。对不起,我花了两年多的时间......
  • 您可以在上面的代码中节省 4 行(和一些时间),将第 4、5、6 行(加上 2 个匹配的 End If)替换为: For Each j In rRng.SpecialCells(xlCellTypeFormulas)
【解决方案2】:

问:“有什么方法可以找到当前引用我们要移动的表的所有 INDIRECT 公式?”

当我阅读它时,您想查看 INDIRECT 的参数内部以获取对感兴趣领域的引用。 OTTOMH 我会编写 VBA 来使用正则表达式解析器,甚至是一个简单的 INSTR 来查找 INDIRECT(向前读取匹配),然后 EVALUATE() 里面的字符串将其转换为实际地址,根据需要重复多个 INDIRECT (...) 调用并将公式及其翻译转储到工作表中的两列。

【讨论】:

    【解决方案3】:

    你可以在 VBA 中使用这样的东西:

    Sub ListIndirectRef()
    
    Dim rRng As Range
    Dim oSh As Worksheet
    Dim oCell As Range
    
    For Each oSh In ThisWorkbook.Worksheets
        Set rRng = oSh.UsedRange
        For Each oCell In rRng
            If InStr(oCell.Formula, "INDIRECT") Then
                Debug.Print oCell.Address, oCell.Formula
            End If
        Next
    Next
    
    End Sub
    

    您可以添加代码来满足您的口味,而不是 Debug.Print

    【讨论】:

      【解决方案4】:

      不幸的是, INDIRECT 通常比 那。这是一个实际的公式 其中一张,不是最 我们有复杂的公式:

      =IF(INDIRECT("'"&$B$5&"'!"&$O5&"1")="","",INDIRECT("'"&$B$5&"'!"&$O5&"1"))

      hm,您可以通过忽略大部分字符并仅查找相关部分来编写一个简单的解析器(在此示例中:“A..Z”、“0..9”和“!:”等)但是如果“indirect”中的参数是函数,你会遇到麻烦。

      也许更安全的方法是在第三张纸中打印每次出现的“间接”。然后,您可以添加所需的输出并编写一个小型搜索和替换程序来写回您的更改。

      如果你“得到”一个巨大的 您可能最终需要的电子表格 巨大的内存量。我是 仍然愿意尝试并接受 风险。

      PabloG 选择使用范围的方法是可行的方法(将其添加到我的原始代码中)。速度相当不错,尤其是在检查当前单元格是否包含公式时。显然,这一切都取决于您的工作簿的大小。

      【讨论】:

        【解决方案5】:

        我不确定 SO 的礼仪是关于提及作者所连接的产品的,但是 OAK,Operis 分析工具包,一个 Excel 插件,可以通过它们解析的单元格引用替换 INDIRECT 函数到。然后,您可以使用 Excel 的审计工具来确定每个范围有哪些依赖项。

        当然,您可以对工作簿的临时副本执行此操作。

        更多在

        • http://www.operisanalysiskit.com/oakpruning.htm
        • http://www.operisanalysiskit.com/help/2007/index.html?oakconceptpruning.htm

        考虑到这个问题的年龄,您很可能已经找到了替代解决方案或解决方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-03-11
          • 1970-01-01
          • 2017-05-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多