I have a spreadsheet which is probably calling BDDE.EXE. When I open this spreadsheet in Excel, everything works fine. I can see values in cells whose formula starts with "=BDDE". However, when I open the same file using C#, Excel first displayed an Alert
Remote data not accesible.
To access this data Excel needs to start another application. ...
Start application 'BDDE.EXE'?
Then no matter what I click - Yes or No, the formulas are updated, all the values from a previous recalculation are lost.
I then tried forcing Excel not to recalculate by setting XlCalculation to Manual. Open stops working after this change, and threw an COMException (with no other information).
System.Runtime.InteropServices.COMException (0x800A03EC): Exception from HRESULT
: 0x800A03EC
at Microsoft.Office.Interop.Excel.ApplicationClass.set_Calculation(
XlCalculation RHS)
I got completely stuck. I can't recalculate because that would mess up all the numbers. I can't set XlCalcualtion to Manual as it throws Exception.
Any help is appreciated.
You can't set the Calculation property without first opening the workbook. This sounds like Catch 22, but it's not actually the 'calculation' you're trying to prevent here - you just don't want it to update the cells linked to an external source.
The Open method takes an optional UpdateLinks parameter. Set this to false, and you should be fine.
There is a limitation in Excel engine which requires an opened workbook prior to setting XlCalculation property. So easiest solution would be to create a new workbook, and then set XlCalculation to desired mode, prior to opening file with actual data.
Related
I have been working up an Add-In to process data out of Excel files sitting in a directory. My program has run successfully in production under a number of scenarios, so I know my code is generally solid. Until now, I have been reading just the first 'sheet' of the Excel file.
I have been working on a feature that will 'crawl' through the entire Workbook by doing a foreach loop through the Worksheets object. The process works fine for the most part, but on occasion when I change sheets I get the message popup: Compile Error in Hidden Module: Clipboard. I do not at any point call or write anything to the clipboard. I have restarted my machine to clear memory and still get the message.
On breakpoint checks, I get the message after calling Excel.Range oRng = thisExcel.xlWorksheet.get_Range("A1").SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell); - at which point it throws that Complile Error message twice (on the same line), and then continues on. It does not cause the program to fail - and if I keep clicking 'Okay' it will proceed to the end and give me my output.
In my code, oRng is a local variable in a function different from the process that sets a new ActiveSheet, so it is null until get_Range is called.
This doesn't happen ever when I read only 1 sheet per Workbook, and it will still run to the end - just throws this message and will not proceed until it is dismissed. I'm using VSTO 2010.
Is there a problem with my use of get_Range? I can share more code on request if that will help shed more light.
UPDATE:
Tried a suggestion that I clear Clipboard. When I try Clipboard.Clear(), I get the same result.
So as it turns out Compile Error in Hidden Module: Clipboard was a message for some specific macros in a few of the workbooks provided to me. It ran all kinds of problems in Excel 2010. But when tested against Excel 2013, there was no problem.
Is there any way I can know if Excel is in dirty state or not.
By dirty state I mean:-
When you do anything on Excel and close save button - Excel asks you to save the file.
So there must be some flag which is set when the file is edited.
Can I know the status of an Excel file through C# code?
Searched a lot, but not much help is available. One option is there which allows you to know if Excel is in edit state or not by looking at GetRibbonControlEnabled("FileNewDefault")
In this case you can see if Excel is in edit state only at the time when you execute this method.
What if I want to know if Excel was edited/made dirty since the time it was open.
Please don't advice to start to background thread which keeps looking if Excel was in edit mode by using the above function.
An help will be extremely appreciated.
Take a look at the Workbook.Saved property. It will tell you if the user has modified the document since it was last opened.
bool isDirty = !Globals.Application.ActiveWorkbook.Saved;
In an Excel VBA module one can test the ActiveWorkbook.Saved property, and if it is False then the workbook has unsaved changes (is "dirty"). Details here. See if you can check that property from your C# code.
I'm using Microsoft.Office.Interop.Excel to create Excel reports with C#. Those reports have a large amount of graphics and take long time to prepare. During the preparation, The instance of the Excel application that my program uses is hidden from the user.
MY problem is that Microsoft Office tends to share application instances automatically. If the user opens an Excel workbook, Excel will try to find a running instance of Excel and open the document from there. When the user tries to open an Excel workbook while my program is running, it is attached to the instance my program uses.
This generates two problem. First, it forces my reports into visibility before they are supposed to become visible. And second, my program now needs to fight with user over the attention of the Excel instance - and my program usually loses.
So, is there any way to make the Excel instance reject requests(from the user. it should still obey to my program) to open documents, and make Office ignore my instance when it has to decide how to open an Excel document?
You could handle the Application.WorkbookOpen event. In here, either start a second instance of Excel and have it open the workbook, or close the workbook with an error message.
I also saw the Application.Interactive property. I haven't played with this, but it may be of use to you.
You can use NPOI, I suggest you visit the following link
http://npoi.codeplex.com/discussions/36157?ProjectName=npoi
I have done a little experimenting, and I think this will work:
Whenever you begin working with Excel, create two instances, and work with the second. When you're done with your work, delete the second instance and its object, then check the "UserControl" property of the first. If it returns "true", then delete only the object, but leave the process for that instance behind. If it returns "false", then delete the instance as well.
As far as I can tell, the user can open and close any number of workbooks, and it will use the first instance you created, as long as you don't delete it, and the second instance will be unmolested.
here is my question:
I have developed a program that uses Microsoft.Excel COM components in order to read/write over Excel files. Well, my app is doing good but when I open, for instance, another file directly with Excel while my program is running, the file(s) that my app uses appear within Excel. I do not want this. I tried also the Visibility property of Excel Application class, but that was not the solution, it just does not work.
NOTE : I have checked this question out.
Restrict access to excel file opened by C# program
Yet, it says no proper solution actually.
You can use Application.IgnoreRemoteRequests = true. This will avoid users opening excel files in the same Excel process as the one you are using.
There is one caveat though: you have to make sure that all execution paths of your application reset this property to false. This property WILL NOT reset itself when you quit and release your Excel application which means that Excel will not respond correctly to a subsequent user who double clicks on a *.xls file for example.
EDIT: Possible issues with IgnoreRemoteRequest
Ok, to make this clearer I'll detail a little bit more what issues you can run into using this feature (at least these are the only ones I've run into when I had to use this feature).
When setting IgnoreRemoteRequests = true you have to make sure you reset this property BEFORE quiting and/or releasing the COM Excel application. If you don't, Excel will not respond to DDE requests which means if someone double clicks on a *.xls file, the file will not open (Excel will start up, but it wont open the file automatically).
This however is only true if you quit the application and/or release it without reseting the property. You just have to make sure that wherever it is in your code that you are quitting/resetting you set the IgnoreRemoteRquests back to false before.
If you'r application crashes and it hasn't been able to clean up (unhandled exception) then the EXCEL process will keep running (if invisible, you will only see it in the Task Manager). That is normal as your app didnt have a chance to quit and release the internal Excel it is using. This however is not an issue. If a user ignores this "leaked" Excel process until it's eventually killed in next reboot or whatever, or manually kills it from the task bar, Excel will work perfectly fine.
Note: MS Excel 2007. Don't know about behavior of previous versions.
Have you tried running your program under a service account? This should avoid the excel com object interfering with the instance used by the logged in console user, so they will not see the effects of your com objects. It's probably also better security practice to run COM type applications under a service account instead of a user account as well, but that's for another question.
I refresh Excel 2007 data connections via a C# program and OLE. Most of the work is done by a single Workbooks.RefreshAll() statement.
As is the nature of refreshing spreadsheets, various things can go wrong. During the refresh process, the program can give dialog box error messages about "Data cannot be read from file '|'", and a message about "Overlapping pivottable reports". Both of these are fatal, and I should be able to catch these errors, and exit my program with an error.
Unfortunately, I don't seem to be able to catch these problems, and instead my automated program sits until I come along and hit enter on the dialog.
Does anyone know if it's possible to programmatically catch the errors shown in excel dialog boxes, instead of having them displayed to the user?
Your best bet is to set the Application.DisplayAlerts property to False. That is, assuming that your Excel.Application object variable is named "xlApp", all you'd have to do is the following:
xlApp.DisplayAlerts = false;
Note that this will cause the default response to be taken for each dialog box, which is normally what you would want. (There's no good way around this. Leaving DisplayAlerts = True and using SendKeys might be your only other option, but would be ugly and very error prone.)
Since you are making this call via OLE Automation, this call is cross-process, and, therefore, the DisplayAlerts setting will persist until you change it. (If called in-process, via VBA, it is switches back to to true automatically when the routine completes. The same behavior probably applies for a VB.NET or C# add-in called via a CommandBar or Ribbon control, but one would need to test to be certain.)