Excel Interop - Create visible workbook while keeping main hidden - c#

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.

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();

ExcelDnaUtility.Application creating a new book (Book1), so first new book in excel is Book2

I have a C# ExcelDna project that, in general, has no issues. However, I use ExcelDna.Application to open a spreadsheet during AutoOpen() (an xlam). I noticed that the first "USER CREATED" workbook, using Excel Menus is Book2. To isolate this, I did the code below. Even when not opening any workbooks, just referring to ExcelDna.Application seems to create a shadow workbook that moves the workbook counter to Book2. Is this a known thing, a bug? or something I'm doing wrong! Thanks/Cheers
public class ExcelDNAXllEntry : IExcelAddIn
{
public void AutoOpen()
{
// EXCEL DNA STUFF ---------------------------------------------------------------------------
ComServer.DllRegisterServer();
//-----------------------------------------------------------------------------------------------
Application x = (Application)ExcelDnaUtil.Application;
I'd expect the first user opened book to be book1. There are no hard errors or error messages, just the odd behavior that I'd like to avoid. We have many users and if they start seeing Book2 I'll be answering lots of questions :)
When Excel loads your add-in, the COM object model is (typically) not yet initialised. I know of no other way to get Excel into a state where we can get to the Application COM object, other than by creating a new 'macro' type workbook behind the scenes. A consequence is the behaviour you report.
I'd be very happy to incorporate an alternative approach in Excel-DNA.
I resolved this issue by
Adding first line in AutoOpen()
bool create = (bool)XlCall.Excel(XlCall.xlcNew, 1);
In ribbon OnLoad(IRibbonUI ribbon)
excel = (Excel.Application)ExcelDnaUtil.Application;
XlCall.Excel(XlCall.xlcFileClose, false);
First step ensure that ExcelDna.Integration/Excel.cs will not use GetApplicationFromNewWorkbook. Second argument 1 in XlCall.Excel means that "Sheet1" is internally created, not "Book1"
The second step closes its own in order to not show empty "Sheet1" window.
Now counting starts from Book1,Book2...
I tested it on Office365, Excel 2106 and Excel 2013, all x64 and it works.

Excel Application Get Active Sheet

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!

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;

Categories

Resources