I'm trying to open an excel workbook and trying to get a worksheet in it. Excelapp.workbooks.Open line is throwing an Exception as
System.Runtime.InteropServices.COMException from HRESULT: 0x800A03EC at Microsoft.Office.Interop.Excel.Workbooks.Open
Here is my code:
Excel.Application excelApp = new Excel.ApplicationClass();
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(strWBPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, true);
StrWbPath is my Excel location. I'm refering to 2007 excel and added Microsoft.office.interop.excel of version 12.0.0.0.
(Sorry for answering this old question, but it's google result #1 for this problem and the correct answer is missing).
The error occurs because excel thinks the Workbook has been corrupted. When opening the Excel file, the last parameter tells excel how to handle this situation. Pass Microsoft.Office.Interop.Excel.XlCorruptLoad.xlExtractData to instruct it to retrieve the data (This will open a popup telling the user excel tried to extract the data if the file is corrupted).
However, I noticed this problem can also be caused if the workbook you are trying to open has a different locale than your excel (was saved on a machine using another language setting) OR your system not having the en-us locale set.
While this is extremely stupid, it's easy to overcome. For me the solution was to just set the current locale to en-us before opening the file:
static System.Globalization.CultureInfo oldCI;
oldCI = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
xlWorkBook = xlApp.Workbooks.Open(filePath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, Microsoft.Office.Interop.Excel.XlCorruptLoad.xlExtractData);
System.Threading.Thread.CurrentThread.CurrentCulture = oldCI;
credit goes to this page
What if you try System.Reflection.Missing.Value instead of Type.Missing?
Regards,
M.
Which class are you using?
Microsoft.Office.Interop.Excel.ApplicationClass
if this then try changing it to
Microsoft.Office.Interop.Excel.Application
In case it helps someone else, I lost tons of time on this one. I was passing Microsoft.Office.Interop.Excel.XlCorruptLoad.xlRepairFile for the CorruptedLoad parameter for all files, thinking it meant "open the file, and if it's corrupt, attempt a repair". This worked for most files.
However, for some files, I was still getting the exception (Exception from HRESULT: 0x800A03EC). Yet if you open the file in Excel manually, it is not corrupt.
It turned out that for those files, you must not supply the CorruptedLoad parameter. Then it opens successfully. So in the end I adjusted my code to first try without any CorruptedLoad parameter, and only if that returns the exception, then try passing xlRepairFile for that parameter. I also adjusted my understanding of that parameter to mean "open and repair this file regardless of whether it's corrupt".
Related
I am using C# to create a spreadsheet, here is the code:
try
{
_excel = new Excel.Application();
_excel.Visible = false;
_workbook = _excel.Workbooks.Add( Type.Missing );
_worksheet = (Excel.Worksheet)_workbook.Sheets[1];
createColumnHeaders();
_workbook.SaveCopyAs( savePath );
}
catch (Exception ex)
{
Logger.Error( "Error creating spreadsheet: {0}", ex.Message );
}
finally
{
// Cleanup
}
This runs nicely, saves the sheet into the savePath. However, if I change SaveCopyAs() to
SaveAs( savePath,
Excel.XlFileFormat.xlWorkbookNormal,
Type.Missing,
Type.Missing,
false,
false,
XlSaveAsAccessMode.xlNoChange,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing );
then the application gets a COMException saying
'C:\//temp/00-04.20.18-24-07-2014/' cannot be accessed. The file may be corrupted,
located on a server that is not responding, or read-only.
This is a pain since I really need to be saving in .xls format, not .xlsx. Any ideas why this exception occurs for SaveAs()?
It's kinda obvious what went wrong here. That's not a valid path of course, // should only ever appear as the lead characters for a path to name the machine that contains the file system.
You'll have to de-tune the "Windows works like Unix" expectation when you work with Microsoft application software. Forward slashes in a path are not a problem when you make direct operating system calls. Windows supports them well, not in the least because Windows NT once supported Posix out of the box. The same is not true for other apps, particularly the kind whose source-code base is 25 years old. But is not limited to just old code, VS has problems too. Microsoft treats these kind of bugs reports a bit like Jeff Atwood treats pluralization bugs.
The proper path separator character without any surprises is a backslash.
I'm working with a legacy system that has components made several years ago (Excel macros) which I'm now trying to integrate into a more user friendly .net application. The files I am accessing are tab-delimited datasheets saved as __.xls so they're opened automatically by Excel when double-clicked.
Inside the sheet there are various dates in the format "dd/MM/yyyy", and when the file is opened normally (double clicked, right-click open, etc) via Excel 2003 (required version), the dates are interpreted as such. When I attempt to open the file using the Microsoft.Office.Interop.Excel (14.0.4756.1000) library however, (i.e. invoke via c#) using the following syntax:
eit_book = eit_books.Open(targetFile.FullName, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
the dates have their day and month switched, and all date math done in the aforementioned macros is done incorrectly. (As well as any dates where the day is greater than 12 are not even recognized as dates)
I.E. 04/01/2012 becomes 01/04/2012, this is presumably because the system has its regional settings set to "English (United States)", but I've made sure that the system's Regional Settings Short Date format is set to a custom value that matches the data in the spreadsheet ("dd/MM/yyyy"), and the problem only seems to occurs when the sheet is opened using the code above.
Any help would be very much appreciated. Thanks.
edit: The Operating System of the computer opening the files is Windows XP.
You need to use the OpenText method to open the file to be able to specify the date formats. Additionally, Excel remembers your previous preferences (when opening a text file, or converting text to columns), so you must explicitly specify most of the parameters for reliable outcomes.
My sample file is tab delimited with 3 columns, but I'm only specifying the date format for the first column.
The first line of text in my file is:
11/01/2001 12/01/2001 13/01/2001
The OpenText method doesn't return a Workbook, so I have to retrieve it by name afterwards:
int[] dateColInfo = new int[] {1, (int)XlColumnDataType.xlDMYFormat};
object[] fieldInfo = new object[] {dateColInfo};
eit_books.OpenText(path, Type.Missing, 1, XlTextParsingType.xlDelimited, XlTextQualifier.xlTextQualifierDoubleQuote, false, true, false, false, false, false, Type.Missing, fieldInfo, Type.Missing, Type.Missing, Type.Missing, Type.Missing, false);
eit_book = eit_books.get_Item(name);
Range rng = eit_book.Worksheets.get_Item(1).range("A1");
Console.WriteLine("{0} ISO Date: {1}", rng.Value, ((DateTime)rng.Value).ToString("yyyyMMdd"));
The output when dateColInfo[1] = XlColumnDataType.xlDMYFormat is:
11/01/2001 12:00:00 AM ISO Date: 20010111
The output when dateColInfo[1] = XlColumnDataType.xlMDYFormat is:
1/11/2001 12:00:00 AM - ISO Date: 20011101
When trying to run these lines:
var app = new Excel.Application();
Excel.Workbook workbook = app.Workbooks.Open(pathToFile, Type.Missing, true, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
I've got these problems:
1) I'm getting a message of "file conversion is in progress". Why do I need to convert something if all I want to do is just read a column from one of the work sheets.
2) I'm getting this error message:
why do I need to care which version created the excel?
3) In the very end I get an exception: "Too many different cell formats".
So is there something wrong with the way I'm using the open workbook method or is there another way to read a specific column from an excel file which contains several sheets and I only need to read data from a single specific sheet?
It might not be obvious to you but calling
new Excel.Application()
opens an instance of Excel (you may check it on the Task Manager). So if your version of Excel is not compatible with the file you are opening you get this error.
Since you are trying to open the Excel document with your Excel application, you DO care of what versions they are.
I think OpenXML SDK could help you with it.
I'm trying to write a C# application that will find a document open in MS Word and write some text to the end of the document using word interop. Is this possible?
I know it's possible to kind of solve this problem using Process and Sendkeys built into the .NET Framework, but I'd like to solve the problem using Word Interop so I can add more functionality down the road (also sendkeys would really only solve the problem in certain special cases.)
Thanks!
Update:
I got the following partial solution working:
Application wordApp = new Application();
wordApp.Visible = true;
wordApp.Documents.Add();
Range rng = wordApp.ActiveDocument.Range(0, 0);
rng.Text = "New Text";
But I'd like to use an already open instance of word instead of creating a new one. Thanks!
Update 2:
I'm close! The following code works with UAC turned off
Application wordApp = (Word.Application)Marshal.GetActiveObject("Word.Application");
Range rng = wordApp.ActiveDocument.Range(0, 0);
rng.Text = "New Text";
But I'm not sure how to get it working with UAC enabled. UAC isn't causing any errors or exceptions, it just doesn't write the text to the open document.
Thanks for everyones help so far, the end is now in sight :)!
Update 3:
Just tried it again with UAC turned on and it worked... strange. Still if you know of any good resources about interop and UAC in general, please post a link here!
Have you looked at using Marshal.GetActiveObject("Word.Application") to get the running application, rather than creating a new one?
Definitely Evan. The Microsoft Office Interop Assemblies let you do just about anything from C#! SendKeys() is an issue.
http://msdn.microsoft.com/en-us/library/15s06t57(v=vs.80).aspx
I guess I should elaborate about SendKeys(): it doesn't even work reliably anymore as it was a primary hacker tool. The MS Office Interop Assemblies allow you to do an enormous array of things with each of the Office components. I have used them extensively with MS Excel, and some with Word, and you can do just about anything a user can do programatically.
You can try below .Here i am giving example with image insert.
WordC.Application wordApp = new WordC.Application();
// create Word document object
WordC.Document aDoc = null;
object readOnly = false;
object isVisible = false;
wordApp.Visible = false;
// wordApp.DisplayAlerts = false;
//docFileName is the filename with complete path. ex c://test.doc
aDoc = wordApp.Documents.Open(docFileName, Type.Missing, ref readOnly, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, ref isVisible, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
aDoc.Activate();
aDoc.InlineShapes.AddPicture(imgFilename, Type.Missing, Type.Missing, Type.Missing);
aDoc.Save();
aDoc.Close(Type.Missing, Type.Missing, Type.Missing);
wordApp.Quit(Type.Missing, Type.Missing, Type.Missing);
The problem: Loading an excel spreadsheet template. Using the Save command with a different filename and then quitting the interop object. This ends up saving the original template file. Not the result that is liked.
public void saveAndExit(string filename)
{
excelApplication.Save(filename);
excelApplication.Quit();
}
Original file opened is c:\testing\template.xls
The file name that is passed in is c:\testing\7777 (date).xls
Does anyone have an answer?
(The answer I chose was the most correct and thorough though the wbk.Close() requires parameters passed to it. Thanks.)
Excel interop is pretty painful. I dug up an old project I had, did a little fiddling, and I think this is what you're looking for. The other commenters are right, but, at least in my experience, there's a lot more to calling SaveAs() than you'd expect if you've used the same objects (without the interop wrapper) in VBA.
Microsoft.Office.Interop.Excel.Workbook wbk = excelApplication.Workbooks[0]; //or some other way of obtaining this workbook reference, as Jason Z mentioned
wbk.SaveAs(filename, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing);
wbk.Close();
excelApplication.Quit();
Gotta love all those Type.Missings. But I think they're necessary.
Rather than using an ExcelApplication, you can use the Workbook object and call the SaveAs() method. You can pass the updated file name in there.
Have you tried the SaveAs from the Worksheet?
Ditto on the SaveAs
Whenever I have to do Interop I create a separate VB.NET class library and write the logic in VB. It is just not worth the hassle doing it in C#