An Excel file contains VBA-encoded user-defined functions (UDFs) that are deployed in tables (VBA listobjects). Now, for reasons that avoid me, if the UDF module contains range variables that are declared outside the scope of any subfunction or function, I get a very sharp warning when I open the file: "Automatic error - catastrophic failure."
"Catastrophic" seems like an exaggeration, because after the warning is rejected, the file seems to be working correctly. But I still would like to understand what the problem is. I was able to reproduce the problem with the MVC example as follows. I am running Excel 2016 (updated) on Windows 10.
There are two tables (for example, VBA listobjects): Table 1 contains lists of “elements” and Table 2 lists of “element functions” (both tables were generated by selecting data and click Table on the Insert tab). Table 2 has a UDF called ITEM_NAME() in the Item_Name field, which returns the item name as a function of the item identifier, see screenshot:

The ITEM_NAME() function is essentially a wrapper around the usual INDEX and MATCH sheet functions, as in the following code:
Option Explicit Dim mrngItemNumber As Range Dim mrngItemName As Range Public Function ITEM_NAME(varItemNumber As Variant) As String ' Returns Item Name as a function of Item Number. Set mrngItemNumber = Sheets(1).Range("A4:A6") Set mrngItemName = Sheets(1).Range("B4:B6") ITEM_NAME = Application.WorksheetFunction.Index(mrngItemName, _ Application.WorksheetFunction.Match(varItemNumber, mrngItemNumber)) End Function
So, to repeat, with this setting, I get an Automation error when opening a file. But the error disappears when I do one of the following:
Move the ads to the scope of the function. This solution is not attractive, since it requires much more lines of code, one for each UDF, and there are many.
Change the type of the variable from the range to something else, for example Integer (so the function will obviously not work).
Convert table 2 to the normal range (i.e. delete the table). This is also an inconvenient solution, since I really want to use the Table functions for other purposes in my code.
Remove the ITEM_NAME() function from table 2. (Obviously, there is no attractive option.)
What's happening? Why am I getting an error message? And why is the file still working fine despite the warning? Is there a workaround that I missed?
I suspect this may have something to do with how sheet objects and object lists interact, but are not sure. A possible hint is given in this answer to another question:
If you want to reference a table without using a sheet, you can use hack Application.Range(ListObjectName).ListObject .
NOTE. This hack builds on the fact that Excel always creates a named range for table DataBodyRange with the same name as the table.
Similar issues have been reported elsewhere (at https://stackoverflow.com/a/26825 / ... and Microsoft Technet ), but not with this particular taste. Suggested solutions include checking for broken links or other processes running in the background, and I did it to no avail. I can also add that it doesn't matter if the Item_Name function is Item_Name after creating table 2, than before; the only difference is that in this case it uses structured links (as in the screenshot above).
UPDATE: Inspired by @SJR's comments below, I tried the following code variant, which declared a ListObject variable to store the Elements table. Note that range declarations now fall within the scope of the function and that only the ListObject declaration is outside. It also generates the same automation error!
Option Explicit Dim mloItems As ListObject Public Function ITEM_NAME(varItemNumber As Variant) As String ' Returns Item Name as a function of Item Number. Dim rngItemNumber As Range Dim rngItemName As Range Set mloItems = Sheet1.ListObjects("Items") Set rngItemNumber = mloItems.ListColumns(1).DataBodyRange Set rngItemName = mloItems.ListColumns(2).DataBodyRange ITEM_NAME = Application.WorksheetFunction.Index(rngItemName, _ Application.WorksheetFunction.Match(varItemNumber, rngItemNumber)) End Function
UPDATE 2: Now the problem is resolved, but I'm not much wiser about what actually caused it. Since no one could replicate (even my friends who opened the same file on different systems), I began to think that this was a local question. I tried to restore Excel, and then even reinstalled the full Office suite from scratch. But the problem still persisted, both with my MCV files used to create the example above, and with the source file where I found the problem.
I decided to try creating a new version of the MCV example, where, inspired by AndrewD below , I used .ListObjects() to set the range instead of using .Range() . It really worked. I can probably adapt this solution for my work (but see my comments in the AndrewD question explaining why I prefer .Range() .)
To check if this solution works, I decided to create two new files, one of which will replicate my own example, as described above, and one where the only difference will be the transition to ListObjects() . In this process, I noticed that I was actually backing away from Range declarations at the beginning of the code in my source file, for example:
Option Explicit Dim mrngItemNumber As Range Dim mrngItemName As Range Public Function ITEM_NAME(...
Without thinking about it, I created a new file, but without indentation. Thus, it will be an exact copy of the previous file (and the above example), but without indentation. But now, with this file, I could not replicate the Automation error! After checking both files, I noticed that the only difference was really indentation, so I again indent the new file, expecting it to generate an Automation error again. But the problem did not appear again. So, then I removed the indent from the first file (used to create the example above), and now the auto-disappear error also disappeared from this file. Armed with this observation, I returned to my real file, where I first discovered the problem and simply deleted the indentation there. And it worked.
So, to summarize, after removing the indent of the Range declaration, I cannot recreate the Automation error in any of the three files generated earlier. And besides, the problem does not appear again, even if I reinsert the indent. But I still don’t understand why.
Thanks to everyone who took the time to look at this and share valuable ideas.