简体   繁体   中英

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. 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.

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("'" & $AC$9 & "'!" & AC26)

This is an example. I need to remove INDIRECT but get the same results for this cell. Is there a way to accomplish this in 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 .

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.

IMPORTANT: all cells that contain a formula using INDIRECTVBA will be static. 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 .

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.

If that is the case then you might consider using INDEX as an alternative. 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). 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. This could be done with a UserForm instead of typing in a value in a particular input cell. 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 & "!"

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":

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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