I have some existing custom Excel workbooks/applications with code-behind C#, which work fine. They do things like referencing Tables defined in the active worksheet, setting their datasources to IEnumerables, etc.
However, now I need to reference a Table which is not in the active sheet. Basically, the active sheet has a button that triggers some C# code-behind, and I need to figure out how to get a reference to a Table on the fourth tab/worksheet in my workbook while inside the code-behind for the first tab/worksheet (the active one).
In my existing code (which works), I can do this on the active sheet:
this.Table1.DataSource = results;
this.Table1.RefreshDataRows();
… so the “Table1” reference is right there and I can access it easily.
However, trying to get a reference to a Table in the other sheet, I run into ComObject errors. For example, I was hoping that this (or something like it) would work:
((Sheet4)Application.Worksheets[3]).Table2.DataSource = results;
((Sheet4)Application.Worksheets[3]).Table2.RefreshDataRows();
… but that throws the error: “Cannot convert type ‘System.__ComObject’ to ContractStatementClient.Sheet4′”. Writing those lines allows Visual Studio to find the Table (Table2) using IntelliSense, but at execution time it fails with the ComObject error I mentioned. “Sheet4” is the name of the class that Visual Studio created for me when I made the new tab.
I can get references to Worksheets that seem to work by doing:
Application.ActiveWorkbook.Worksheets[3]
… but I can’t seem to figure out how to get from there to having a handle to a Table (or ListObject), that I can set the DataSource property on, as I’ve done in the past.
I tried this, but it throws a “NOINTERFACE” COM error during the cast:
Worksheet worksheet = Application.ActiveWorkbook.Worksheets[3];
((Microsoft.Office.Tools.Excel.ListObject) (worksheet.ListObjects[1])).DataSource = results;
Am I missing something obvious? I know next to nothing about COM, so it’s tough for me to diagnose what’s going on. In the end, I just need to figure out how to set the datasource for the Table/ListObject in the other tab/worksheet (and presumably tell it to refresh itself).
Thanks! Any help is greatly appreciated.
I ended up using the following approach, which worked quite well.
At the workbook level, I added a static array of type “WorksheetBase”, and instantiated it in the “startup method for the Workbook, like this:
Then, in each individual worksheet, I added this to the “startup” method:
Each worksheet knows which zero-based index it falls in, so this particular sheet uses index == 0, whereas the second sheet would use index == 1.
Now, when I want to access a specific member of another worksheet anywhere in my client, I reference the appropriate index, cast to the appropriate type for the sheet I want, and go to town:
I’m sure there is a more straightforward way to do this using the COM back-end, but darned if I could figure it out. Hopefully this helps somebody else save some time!