如何编写 Excel VBA 等效的 INDIRECT 函数?
How to code Excel VBA equivalent of INDIRECT function?
我在我的工作簿中多次使用了 INDIRECT 函数,它导致了性能问题。我需要用能给我相同结果的东西替换它们。所有 INDIRECT 都会在任何更改时重新计算,从而导致工作簿滞后。
我想知道是否有一种方法可以在 VBA 中编写 INDIRECT 而无需实际使用 INDIRECT 函数,并消除代码中函数的波动性。
=INDIRECT("'" & $AC & "'!" & AC26)
这是一个例子。我需要删除 INDIRECT 但此单元格的结果相同。在 VBA 中有没有办法做到这一点?
你可以试试这个。
将以下例程放入标准代码模块中:
Public Function INDIRECTVBA(ref_text As String)
INDIRECTVBA = Range(ref_text)
End Function
Public Sub FullCalc()
Application.CalculateFull
End Sub
将公式中的 INDIRECT
函数替换为 INDIRECTVBA
。
这些将是静态的。如果您的工作簿运行缓慢是因为您的 INDIRECT 不断评估,那么这将结束这种情况。
重要提示: 所有包含使用 INDIRECTVBA
的公式的单元格都将是静态的。每个公式在您确认时都会计算,但当先例发生变化时不会重新计算。
然后您将需要一种方法来强制它们在方便的时候重新计算。您可以从功能区执行此操作。或者,您可以 运行 FullCalc
.
本来打算将其添加为评论,但我的思考过程太长了。
您要解决的问题的背景是什么?
我猜你正在使用 $AC$9 中的某种数据验证下拉菜单到 select 一个 sheet 名称,然后你所有的间接公式都提供了一个镜像用户指定作品的特定部分sheet。
如果是这种情况,那么您可以考虑使用 INDEX
作为替代方案。它写成 =INDEX(Range, RowNum, ColNum)
例如如果你把它放在 H20: =INDEX(Sheet1!A:Z,ROW()+10,COLUMN()-5)
那么它会反映 sheet 1 单元格 C30 中的任何内容(H - 5 列,20 + 10 行)。当然,如果你不想,你不必抵消任何东西,我只是想证明这是一个选项。
现在,棘手的部分仍然存在 - assigning/updating SheetName 变量。这可以通过用户窗体而不是在特定输入单元格中键入值来完成。例如,您可以 VBA 为用户提供 select 可用 sheet 名称之一的输入 box/dropdown 菜单,然后获取该输入并快速使用它查找和替换指令 - 搜索 "=INDEX(*!"
并替换为 "=INDEX(" & InputVariable & "!"
我对您的数据集和您想要实现的目标做出了一些假设,因此它可能不是理想的解决方案,但也许值得考虑。
我在我的工作簿中多次使用了 INDIRECT 函数,它导致了性能问题。我需要用能给我相同结果的东西替换它们。所有 INDIRECT 都会在任何更改时重新计算,从而导致工作簿滞后。
我想知道是否有一种方法可以在 VBA 中编写 INDIRECT 而无需实际使用 INDIRECT 函数,并消除代码中函数的波动性。
=INDIRECT("'" & $AC & "'!" & AC26)
这是一个例子。我需要删除 INDIRECT 但此单元格的结果相同。在 VBA 中有没有办法做到这一点?
你可以试试这个。
将以下例程放入标准代码模块中:
Public Function INDIRECTVBA(ref_text As String)
INDIRECTVBA = Range(ref_text)
End Function
Public Sub FullCalc()
Application.CalculateFull
End Sub
将公式中的 INDIRECT
函数替换为 INDIRECTVBA
。
这些将是静态的。如果您的工作簿运行缓慢是因为您的 INDIRECT 不断评估,那么这将结束这种情况。
重要提示: 所有包含使用 INDIRECTVBA
的公式的单元格都将是静态的。每个公式在您确认时都会计算,但当先例发生变化时不会重新计算。
然后您将需要一种方法来强制它们在方便的时候重新计算。您可以从功能区执行此操作。或者,您可以 运行 FullCalc
.
本来打算将其添加为评论,但我的思考过程太长了。
您要解决的问题的背景是什么?
我猜你正在使用 $AC$9 中的某种数据验证下拉菜单到 select 一个 sheet 名称,然后你所有的间接公式都提供了一个镜像用户指定作品的特定部分sheet。
如果是这种情况,那么您可以考虑使用 INDEX
作为替代方案。它写成 =INDEX(Range, RowNum, ColNum)
例如如果你把它放在 H20: =INDEX(Sheet1!A:Z,ROW()+10,COLUMN()-5)
那么它会反映 sheet 1 单元格 C30 中的任何内容(H - 5 列,20 + 10 行)。当然,如果你不想,你不必抵消任何东西,我只是想证明这是一个选项。
现在,棘手的部分仍然存在 - assigning/updating SheetName 变量。这可以通过用户窗体而不是在特定输入单元格中键入值来完成。例如,您可以 VBA 为用户提供 select 可用 sheet 名称之一的输入 box/dropdown 菜单,然后获取该输入并快速使用它查找和替换指令 - 搜索 "=INDEX(*!"
并替换为 "=INDEX(" & InputVariable & "!"
我对您的数据集和您想要实现的目标做出了一些假设,因此它可能不是理想的解决方案,但也许值得考虑。