简体   繁体   English

如何编写等效于 INDIRECT 函数的 Excel VBA?

[英]How to code Excel VBA equivalent of INDIRECT function?

I have many uses of the INDIRECT function in my workbook, and it is causing performance issues.我的工作簿中有很多 INDIRECT 函数的用法,它会导致性能问题。 I need to replace them with something that will give me the same results.我需要用能给我相同结果的东西替换它们。 All the INDIRECTS recalculate anytime anything is changed, causing the workbook to lag.任何时间发生任何更改时,所有 INDIRECTS 都会重新计算,从而导致工作簿滞后。

I was wondering if there is a way to code INDIRECT in VBA without actually using the INDIRECT function, and take away the volatility of the function in the code.我想知道是否有一种方法可以在不实际使用 INDIRECT 函数的情况下在 VBA 中编写 INDIRECT 代码,并消除代码中函数的波动性。

 =INDIRECT("'" & $AC$9 & "'!" & AC26)

This is an example.这是一个例子。 I need to remove INDIRECT but get the same results for this cell.我需要删除 INDIRECT,但要为这个单元格获得相同的结果。 Is there a way to accomplish this in VBA?有没有办法在 VBA 中实现这一点?

You can try this. 你可以试试这个。

Place the following routines in a standard code module: 将以下例程放在标准代码模块中:

Public Function INDIRECTVBA(ref_text As String)
    INDIRECTVBA = Range(ref_text)
End Function

Public Sub FullCalc()
    Application.CalculateFull
End Sub

Replace the INDIRECT functions in your formulas with INDIRECTVBA . 更换INDIRECT在公式与函数INDIRECTVBA

These will be static. 这些将是静态的。 If the slowness of your workbook is because your INDIRECTs are constantly evaluating, then this will put an end to that. 如果您的工作簿缓慢是因为您的INDIRECT正在不断评估,那么这将结束这一点。

IMPORTANT: all cells that contain a formula using INDIRECTVBA will be static. 重要信息:包含使用INDIRECTVBA的公式的所有单元格都将是静态的。 Each formula will calculate when you confirm it, but it will not recalculate when precedents change. 每个公式将在您确认时计算,但在先例更改时不会重新计算。

You will then need a way to force them to recalculate at a convenient time. 然后,您需要一种方法强制他们在方便的时候重新计算。 You can do that from the Ribbon. 您可以从功能区执行此操作。 Or, you can run FullCalc . 或者,您可以运行FullCalc

Was going to add this as a comment, but my thought process got too long. 我想把它添加为评论,但我的思考过程太长了。

What is the context of the problem you are trying to solve? 您要解决的问题的背景是什么?

I am guessing you are using some kind of data validation drop-down menu in $AC$9 to select a sheet name and then all your INDIRECT formulas are providing a mirror image of a particular section of the user-specified worksheet. 我猜您在$ AC $ 9中使用某种数据验证下拉菜单来选择工作表名称,然后所有的INDIRECT公式都提供了用户指定工作表的特定部分的镜像。

If that is the case then you might consider using INDEX as an alternative. 如果是这种情况,那么您可以考虑使用INDEX作为替代方案。 It is written as =INDEX(Range, RowNum, ColNum) Eg if you put this in H20: =INDEX(Sheet1!A:Z,ROW()+10,COLUMN()-5) then it would reflect whatever is in sheet 1, cell C30 (H - 5 columns, 20 + 10 rows). 它被写为=INDEX(Range, RowNum, ColNum)例如,如果你把它放在H20: =INDEX(Sheet1!A:Z,ROW()+10,COLUMN()-5)那么它会反映在表格中的任何内容1,单元格C30(H-5列,20 + 10行)。 Of course, you don't have to offset anything if you don't want to, I just wanted to demonstrate that as an option. 当然,如果你不想,你不必抵消任何东西,我只想证明这是一个选择。

Now, the trickier part would still remain - assigning/updating the SheetName variable. 现在,更棘手的部分仍然存在 - 分配/更新SheetName变量。 This could be done with a UserForm instead of typing in a value in a particular input cell. 这可以使用UserForm完成,而不是在特定输入单元格中键入值。 For example, you could have VBA provide an input box/dropdown menu for the user to select one of the available sheet names, then take that input and use it in a quick find and replace instruction - searching for "=INDEX(*!" and replacing with "=INDEX(" & InputVariable & "!" 例如,您可以让VBA提供一个输入框/下拉菜单供用户选择一个可用的工作表名称,然后获取该输入并在快速查找和替换指令中使用它 - 搜索"=INDEX(*!"并替换为"=INDEX(" & InputVariable & "!"

I've made a few assumptions about your dataset and what you're trying to achieve, so it might not be the ideal solution, but perhaps something to think about. 我对你的数据集和你想要实现的目标做了一些假设,所以它可能不是理想的解决方案,但也许是需要考虑的事情。

The solution to volatility with the Indirect function (typical in multi-version cross platform use and partitioning to run Windows on Mac) can be absorbed by splitting its various functions with a pseudonym for Indirect I have named "Implied":使用 Indirect 函数(通常在多版本跨平台使用和分区以在 Mac 上运行 Windows)解决波动性的方法可以通过使用 Indirect 的化名拆分其各种函数来吸收,我将其命名为“Impied”:

Public Function Implied(Varient)
' CREDIT: Stephen L. Rush

    On Error Resume Next

    If IsError(Range(Varient)) Then
        If IsError(Find(Varient, "&")) Then
           'Not Range, is Indirect.  "A" & Match() Style (where Match() = row).
            Implied = WorksheetFunction.Indirect(Varient)
        Else
           'Not a Range, not Indirect. "A" & B99 Reference (where B99 = row).
            Implied = Range(Left(Varient, Find(Varient, "&") - 1) & Range(Right(Varient, Len(Varient) - Find(Varient, "&"))))
        End If
    Else
       'Is pure Range
        Implied = Range(Varient)
    End If

   '[On Error GoTo 0] Conflicts with use as formula

End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM