I'm new to C# and trying to accomplish some simple excel manipulation through the interop library.
I'd like to delete a text value which always appears as a separate line below the actual data table (with a blank row between the table and the text). It's a 'rows selected.' count which prints out in an automated report. It always appears in the first column.
The error "COMexception unhandled - Cannot access read-only document - test1.xlsx" appears after the row is deleted and I try to Close() the workbook.
I cannot seem to release the workbook, I've tried a lot of random garbage collection methods found on other forums, but has anyone seen this before?
Appreciate the help!
EDIT - So the file isn't read-only until I start running the program. Once I run the program it becomes locked and read-only. It isn't closing/releasing the workbook...
EDIT - I ended up adding a Workbook.Save() function and using the Application object's Quit() function. This question was also very informative (similar question).
public void ExcelManip(string thisFileName)
{
Workbook workBook = _excelApp.Workbooks.Open(thisFileName,
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);
DeleteRowCount(ref workBook);
workBook.Save();
workBook.Close(false, Type.Missing, Type.Missing);
_excelApp.Application.Quit();
_excelApp.Quit();
//workBook.Close(true, thisFileName);//ERROR;Cannot access read-only document
//Marshal.ReleaseComObject(workBook);
//GC.Collect();
//GC.WaitForPendingFinalizers();
}
I ended up adding a Workbook.Save() function and using the Application object's Quit() function. This question was also very informative (similar question).
Related
I have some code that copies all sheets from one excel file into another. This code is as follows:
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook source = ExcelApp.Workbooks.Add(missing);
Microsoft.Office.Interop.Excel.Workbook destination = ExcelApp.Workbooks.Add(missing);
string file = #"C:\SomeExcelFile.xlsx";
source = ExcelApp.Workbooks._Open
(file, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing
, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
foreach (Microsoft.Office.Interop.Excel.Worksheet s in source.Worksheets)
{
s.Copy(Type.Missing, destination.Worksheets[destination.Worksheets.Count]);
}
In most cases this works as expected but there are two issues that I want to resolve. The first is that in one of the excel workbooks I am copying there is a column that is formatted like this:
$#,##0.00;[Red]-$#,##0.00
When running this through my code this column gets reformatted to this:
$#,##0.00_);[Red]($#,##0.00)
Is there a way I can retain the formatting of the original file?
Secondly, I'd like the widths of the columns to remain the same as the original file. Is this possible too?
This code is being used to merge multiple excel workbooks into a single file.
Thanks
The company I work for has the option to create plugins for our main product. I am currently working on a plugin. The plugin needs to read in from an Excel file.
Part of my plugin tries to get a worksheet by name:
Excel.Application excelApp = new Excel.Application();
Excel.Workbook wb = excelApp.Workbooks.Open(fileName, Type.Missing, Type.Missing,
Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Excel.Worksheet ws = wb.Sheets[SheetName] as Excel.Worksheet;
When I run as a standalone application (outside of our main application) the above code works fine.
However when I run the above code as a plugin from our main application I get the following execption:
dynamic operations can only be performed in homogenous appdomain
I have done some research and found that the legacy security policy is related. For other reasons that I am unaware of and cannot change our main product must run with legacy security policy turned on.
<NetFx40_LegacySecurityPolicy enabled="true"/>
Regardless of this condition our client still wants this feature added. There must be some way of getting the Excel functionality to work.
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 create a csv file from an excel file using MS Excel Interop in my C#/Winforms app.
Am getting this error on SaveAs method in the code below.
'The file could not be accessed. Try one of the following:
• Make sure the specified folder exists. • Make sure the folder that
contains the file is not read-only. • Make sure the file name does
not contain any of the following characters: < > ? [ ] : | or
* • Make sure the file/path name doesn't contain more than 218
characters.'z
I tried setting readonly to false in Workbook's Open(...) method as per:
Problem saving excel file after inserting data , but still getting the same error.
In my code, the csv file path was:C:\
If I change the csv file path to C:\SomeFolder or some shared UNC path, then I dont get this error.
Please advise.COuld there be some permissions issues with C drive?
Heres the code:
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlApp.DisplayAlerts = false;
xlApp.Visible = false;
wbkSrc = xlApp.Workbooks.Open(m_sSrcFil,
Type.Missing, false, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
wstSrc = (Worksheet)wbkSrc.Worksheets[sSrcSht];
//wstSrc.Activate();
rngWork = wstSrc.Cells.get_Range("H:H", System.Reflection.Missing.Value);
rngWork.NumberFormat = "General";
dteTmpDate = Convert.ToDateTime(m_sBusDate);
sTmpFileName = m_sSrcFil.Substring(0, m_sSrcFil.IndexOf(".")) + "_" +
m_sUserName + "_" + dteTmpDate.ToString("yyyy_MM_dd") + ".Csv";
wstSrc.SaveAs(sTmpFileName, XlFileFormat.xlCSV, Type.Missing,
Type.Missing, true, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Clearly sTmpFileName is an invalid path. The error message tells you that. Perhaps m_sUserName contains characters that are not allowed. Perhaps it is a DOMAIN\USER format user name. Perhaps the file name really is too long. Or perhaps something else is up. Take a look at the actual value of sTmpFileName and you will have your explanation.
As an aside, your code is mistaken in using SubString and IndexOf(".") to get the filename without the extension. Filenames can have multiple periods in them. The extension is simply that text after the final period. Consider these file names and how your code will deal with them:
C:\My.Folder.Name\TheFile.xls
C:\MyFolder\TheFile.Name.xls
Instead you should use Path.GetFileNameWithoutExtension.
Excel SaveAs is quite picky. Things like c:\folder\\file.csv (note the double backslash) are accepted by File.Exists or when you open a workbook, but not when saving
Check your FilePath where you are saving if it is more than 218 characters then also you will get this error.
Does anyone know how to simply open and close an Excel workbook?
I don't need to read any data from the file, I just need to open and close it. (*)
I'm guessing that I'll need to reference the Microsoft.Office.Interop.Excel assembly.
*Reason: I've already configured pivot table information with a 3rd party library (Aspose). Now I need to read the generated pivot table.
Unfortunately, the Aspose library can't generate the pivot table at runtime. It needs someone to open the file with Excel so that Excel can generate the pivot table values.
after referencing Microsoft.Office.Interop.Excel also Make sure to clean up in the finally.
using Excel = Microsoft.Office.Interop.Excel;
Excel.ApplicationClass _Excel;
Excel.Workbook WB;
Excel.Worksheet WS;
try
{
_Excel = new Microsoft.Office.Interop.Excel.ApplicationClass();
WB = _Excel.Workbooks.Open("FILENAME",
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);
//do something
}
catch (Exception ex)
{
WB.Close(false, Type.Missing, Type.Missing);
throw;
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(WB);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(_Excel);
}
A quick Google gives me this on code project:
http://www.codeproject.com/KB/office/csharp_excel.aspx
Consider using System.Diagnostics.Process to start, monitor, and close Excel. This site gives a good intro: http://www.thescarms.com/dotnet/Process.aspx, including running with an invisible window and sending input to it.