edited for clarity now that solution has been identified
I am a VBA newbie building a UDF. This UDF involves a number of vlookup functions that reference excel tables on other worksheets in the workbook, such as:
Twirecol = Application.WorksheetFunction.VLookup(i, Range("iterationtable"), 2, False)
The trouble is, if another workbook is active, when excel recalculates the formula returns a #VALUE error.
I see many solutions for how to reference OTHER workbooks and worksheets in VBA and UDFs, but I do not know how to scope these table objects appropriately, so that they stay focused on the workbook in which the UDF exists. Note that I am looking for a solution that does not depend on worksheet name or workbook file name or path, as all of these may change over time.
Here's my name manager for this workbook:Names Manager
Here is the entire UDF code:
Public Function voltagedrop(trenchlength As Integer, intlength As Integer) As String
Application.Volatile
Dim TLX As Integer
Dim ILX As Integer
Dim TVD As Single
Dim IVD As Single
Dim VD As Single
Dim Twirecol As Integer
Dim Iwirecol As Integer
Dim i As Integer
' Extended length variables account for extra length at end of strings
TLX = trenchlength + 10
ILX = intlength + 10
i = 0
Do
i = i + 1
Twirecol = Application.WorksheetFunction.VLookup(i, Range("iterationtable"), 2, False)
Iwirecol = Application.WorksheetFunction.VLookup(i, Range("iterationtable"), 3, False)
' Calculate voltage drops
TVD = Application.WorksheetFunction.VLookup(TLX, Range("trenchtable"), Twirecol, False)
IVD = Application.WorksheetFunction.VLookup(ILX, Range("inttable"), Iwirecol, False)
VD = TVD + IVD
Loop Until VD < 0.025
VD = 100 * Round(VD, 4)
voltagedrop = Application.WorksheetFunction.VLookup(i, Range("iterationtable"), 4, False) & ": " & VD & "%"
End Function
Solution (thanks @DavidZemens)
(*David's complete answer is below, this is my summary)
If this had been a traditional named range, rather than a table, I could have called the range like so:
Twirecol = Application.WorksheetFunction.VLookup(i, ThisWorkbook.Names("iterationtable").RefersToRange, 2, False)
But, because tables act differently than named ranges (despite showing up similarly in the Names Manager), I need to call the range like this:
Twirecol = Application.WorksheetFunction.VLookup(i, ThisWorkbook.Worksheets("Background Tables").ListObjects("iterationtable").Range, 2, False)
However, my ideal solution avoids naming the sheet at all, in case the sheet name changes in the future, so it was demonstrated that I could use the sheet CodeName
instead (in my case sheet1
):
Twirecol = Application.WorksheetFunction.VLookup(i, Sheet1.ListObjects("iterationtable").Range, 2, False)
I have identified the range directly in this sample code for simplicity, but per David's recommendation my final code did use a set a variable for the range.