I'm using the UDF which relies on the ListObject name passed to it. A user doesn't have to know where a referenced table (ListObject) is placed in the workbook, since it is rather big and complex workbook. For this reason, the UDF refers to the table by its name, omitting the worksheet's name, as follows:
Set Obj = Application.Range(TableName).ListObject
This works perfectly as long as the code is in the active workbook. It doesn't work, if another workbook is activated. For some reason, when another workbook is being opened, the UDF's VBA code is being fired, and it fails resulting in #VALUE outputs all the way across my workbook. I have tried multiple ways to reference a list object explicitly, and the only working one seems to be like
WorkbookObject.WorksheetObject.ListObject(TableName)
However, as I've mentioned above, I'm trying to avoid using a Worksheet reference.
Is it ever possible to reference a list object in non-active workbook through an explicit reference, without a need to use a Worksheet reference?
If not, what is the best way to prevent a UDF from unnecessary runs when another workbooks are being opened? I've tried to force re-calculating the UDF using Application.Volatile method, but due to the size of the workbook, it slows it down dramatically.
Any help are highly appreciated.
Clarification based on the @BigBen comment Because most part of the workbook acts behind the scene, the table's name isn't passed on as an explicit value, instead the UDF takes user inputs (strings) and decides on the name of the table to call based on these inputs.
Edit
Thanks all. I've now resolved the issue, based on the Tim Williams's suggestion as follows:
Dim ws As Worksheet, LObj As ListObject
If ActiveWorkbook Is ThisWorkbook Then
Set Obj = Application.Range(Tabl).ListObject
Else
For Each ws In ThisWorkbook.Worksheets
For Each LObj In ws.ListObjects
If LObj.Name = Tabl Then Set Obj = LObj: Exit For
Next
Next
End If
Excuse me for being so stupid before.
ListObjectparameter and pass the actual table, not the table name?Application.Rangealways refers to the Active Workbook/Sheet). If the table is always in the WB containing the code, then it'sThisWorkbook. If not, and the UDF call is always in the same WB as the Table, then it'sThisCell.Workbook.ParentThisCell.Worksheet.Parent