Excel Application Get Active Sheet - c#

I'm trying to return the active sheet from the workbook.SheetActivate event as a Microsoft.Office.Tools.Excel.Worksheet object but I'm having some real issues!
I'm creating worksheets at runtime by copying one worksheet, and then renaming it. The worksheet I'm copying is a template which houses the look and feel for each generated excel sheet.
I need to get the Microsoft.Office.Tools.Excel.Worksheet object because I then need to add a button control to the stated excel sheet.
This is how I've tried to accomplish this:
void Application_SheetActivate(object Sh)
{
Excel._Worksheet test = Sh as Excel._Worksheet;
Worksheet worksheet = Globals.Factory.GetVstoObject(test);
MessageBox.Show(worksheet.Name.ToString());
}
This works for the Sheet1, but the template sheet and anything else that gets started up gets this error:
System.NullReferenceException. Object not sent to an instance of an object. After running the debugger I can see that the first excel sheet is assigned correctly, but any other ones aren't... I know what the error states and what it means.
What am I doing incorrectly here? When a sheet tab gets clicked, all I want to be able to do is return a Microsoft.Office.Tools.Excel.Worksheet type, but boy I've never had so many issues!

Related

EPPlus set default worksheet

I am using EPPlus v4.1 to generate an excel file in C#.
Is there a way to set a specific worksheet as the default worksheet? (when the user is opening the exported file, that sheet should be shown)
I could not find a method or property on ExcelWorkbook or ExcelWorksheets classes.
I found the answer meanwhile. I don't want to delete the question because it might be useful to someone else.
//this line sets the first tab in the excel file as default/active
Workbook.Worksheets.First().Select();
For EPPlus 5 the answer is:
sheet.View.SetTabSelected();

How can you set the scope for a defined name programmatically using SpreadsheetGear?

The support for working with defined names in SpreadsheetGear isn't as good as for other components of Excel.
Can this be done? If so, how?
When I copy in a sheet from another workbook, the scope is limited to that worksheet, and I'd like to be able to apply it to the whole workbook.
This is how you define a name with workbook scope
SpreadsheetGear.IWorkbook workbook = workbookView.ActiveWorkbook;
SpreadsheetGear.INames definedNames = workbook.Names;
definedNames.Add(name, refTo, SpreadsheetGear.ReferenceStyle.A1);
definedNames[name].Comment = "SomeComment";
definedNames[name].Visible = true;
"When I copy in a sheet from another workbook, the scope is limited to that worksheet"
If I understand you correclty, you cannot do what you want and it is logically impossible. The defined names always should have 'workbook scope', that is, it is workbook.Names that holds the defined names information. Now based on this fact, if you copy a sheet from workbookA to workbookB, the sheet holds nothing about the defined names of that workbook (workbookA.Names), thus it can never hold their references.
I hope this helps.

using Excel Workbooks.OpenXML and getting a warning that stops the automation

Excel 2010.
I have a C# app that has a dataset with multiple tables. I want to export this to a workbook where each table is a separate sheet it is important to keep the order of the datasets, and the name of the data tables)
One possible solution is to loop through each table, put it on its own dataset, save this dataset as XML, then use the Application.Workbooks.OpenXML method
MSDN OpenXML Documentation
But here is the problem, if I pass the third parameter (which gives a very nice import with filters and everything), excel succeed, but it warns me that some columns were imported as text, which is ok with me (one of the columns is UPC, which should be a text, not a number).
By displaying this message it stops the process until the user clicks that this is acceptable. Then I question my self about how the mother of all excels is doing these days.
How to prevent this message from popping up?
Or another way to do this import with such nice results? (Copy and paste works but not so nicely, writing in every cell using automation is way to slow, maybe using some excel library...)
You turn
Try
var excelApplication = new Application { DisplayAlerts = false };
or
Workbook excelWorkBoook = excelApplication.Workbooks.Open(...);
excelWorkBoook.CheckCompatibility = false;

Excel Interop - Create visible workbook while keeping main hidden

Suppose I have the following set up in a WinForms application:
Dim ExcelApp As Microsoft.Office.Interop.Excel.Application
Dim ExcelWorkbook As Microsoft.Office.Interop.Excel.Workbook
Dim wksDataVals As Microsoft.Office.Interop.Excel.Worksheet
ExcelApp.Visible = False
Basically, I have an invisible instance of Excel running in the background with a workbook open in it called ExcelWorkbook and a sheet the app is manipulating called wksDataVals. And the user is manipulating this sheet (and others) via the userform and seeing some outputs based upon those manipulations.
Now, on my form I have a button Show Excel Sheet where, once the user clicks it, I want to show them a copy of wksDataVals in a new, standalone, workbook while keeping the original hidden in the background for further data manipulation. I believe that I need to do this by creating a new instance of Excel since I want to keep this one hidden.
Is there a better way to do this than:
Saving the worksheet
Creating a new (visible) instance of Excel
Re-opening the worksheet in that instance
(Which can create an issue with the worksheet now only being read-only since I want it to stay open in the other Excel instance) - I know I can overcome this by re-saving the worksheet as a new name AGAIN, but this all seems like overkill.
Any ideas about how I can accomplish this in the easiest way?? - Maybe there's a way to save the workbook / sheet internally and feed it to a new Excel instance rather than making Excel try and open a saved sheet??
Thanks!
As an answer to my own question in case anyone out there happens to have the same question come up for them (please, experts, if you have a better way, let me know), what I ended up doing was:
Create a new instance of Excel
Create a blank new workbook in that instance
Copy the Range I cared about from the hidden sheet
Pasted it (Values and formatting in my case was all I wanted) onto the new workbook
Made the new instance of Excel visible
Set the reference to the new app instance, workbook, sheet, etc = nothing, so now it was no longer connected to my program.
Seemed to do the trick wonderfully.

How to programmatically group (shift select) sheets in Excel

This topic is related to: What object type are multiple selected sheets in Excel?
To give an overview of the problem, I run some code that changes my selection in Excel, and I want to return the selection to what it originally was (I call this "originalSelection"). In most instances, you can just invoke the Select() method on the originalSelection.
var originalSelection = ExcelApp.Selection;
originalSelection.GetType().InvokeMember("Select", System.Reflection.BindingFlags.InvokeMethod, null, originalSelection , null);
With multiple sheets selected, the selection type is always of a range (it's what Excel defaults to). However, if you have multiple sheets selected, you can run into errors when trying to invoke Select again. You need to do some dancing around to get things to work.
If multiple sheets are selected, but not all the sheets, you can do the follow:
selectedSheets.Select();
activeSheet.Activate();
originalSelection.Select(); //this was casted to an Excel.Range
However, if all the sheets are selected, the activeSheet.Activate() line deselects all the other selected sheets. This also happens if you try it natively using the UI.
I was wondering if there is a way to pragmatically mimic shift-selecting sheets one by one through the code? Closest stuff I've found is stuff with range groupings, but nothing for sheets.
I tried to keep my overview brief, but if you need more clarification on what I'm doing, just ask.
So I figured out a way programatically select sheets.
You can create a string array of names, and use the ordering of the array to get a collection of the sheets. Select this collection, and you should have all the specified sheets selected.
String[] sheetsToBeSelected = {"Sheet3","Sheet1","Sheet2"}; //Note, Sheet3 is the first item in this array
excel.Workbook workbook = ExcelApp.ActiveWorkbook; //get your Excel application however you want
excel.Sheets worksheets = workbook.Worksheets; //get all the sheets in this workbook
//This gets a collection of the sheets specified and ordered by the array of names passed in.
//Just call select on this collection, and the first sheet in the collection becomes the active sheet!
((excel.Sheets)worksheets.get_Item(sheetsToBeSelected)).Select();

Categories

Resources