Exception from HRESULT: 0x800A03EC Error while saving Excel file - c#

I am saving data on button's click event and below is code:
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;
object misValue = System.Reflection.Missing.Value;
String st = System.IO.Directory.GetCurrentDirectory() + "\\A.xlsx";
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open(st, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
int i = 6;
for (i = 6; i < 10; i++)
{
xlWorkBook.SaveAs(st, XlFileFormat.xlExcel9795, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlShared, misValue, misValue, misValue, misValue, misValue);
MessageBox.Show(xlWorkSheet.get_Range("L" + #i, "L" + #i).Value2.ToString());
}
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
When I am saving it, it gives me error:
HRESULT: 0x800A03EC Error while saving Excel file

check for cell indices for sheet , starts from [1,1]
sheet.cells[0,0] will throw com error.

As I understand at Saving an Excel File Exception from HRESULT: 0x800A03EC Exception raised when arguments of method SaveAs are wrong. Please review your arguments at:
xlWorkBook.SaveAs(st1, XlFileFormat.xlExcel9795, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlShared, misValue, misValue, misValue, misValue, misValue);

I know this thread is old, but this may be of help to somebody. I had the same problem, and calling the Activate() function on the workbook fixed it for me:
yourWorkBookObject.Activate()

#Sebastian is correct in that you are calling SaveAs four times, saving to the same location without closing. This isn't going to work, you need to first of all move this out of the loop. But looking at your code more closely, you aren't changing anything in the workbook, so there is no need to save, and if you did change something, you would be better calling Save instead of SaveAs. As well as this, you are specifying ReadOnly as true when you are opening the workbook, so attempting to call save in any capacity isn't going to work.
Finally, if you are using >= C# 4, you can use optional parameters, so all of those misValue's are unnecessary. I tidied up your code below:
using Excel = Microsoft.Office.Interop.Excel;
var st = System.IO.Directory.GetCurrentDirectory() + "\\A.xlsx";
var xlApp = new Excel.Application();
var xlWorkBook = xlApp.Workbooks.Open(st);
var xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.Item[1];
for (var i = 6; i < 10; i++)
{
MessageBox.Show(xlWorkSheet.Range["L" + #i, "L" + #i].Value2.ToString());
}
//make some changes here
xlWorkBook.Save();
xlWorkBook.Close();
xlApp.Quit();

I had the same error while saving the Excel file line.
xlWorkBook.SaveAs(st);
I found out the folder name has been changed by someone cause an issue for me to save the file to the given file location at "st". I hope this helps someone to check first.

In case anyone else makes the same mistake as me, in my case it was due to the filename used to save the excel file. It had an illegal character in the name "/" which was causing this 0x800A03EC Error with no details at all.
So before dealing with permissions make sure that the path exists AND that the filename is legal.

Related

Export Chart to Excel File

I am new in C# Programming. I am creating a winform application in which I am using System.Windows.Forms.DataVisualization Chart. This chart contains multiple series. I want to export that chart data to Excel file.
To Add Data to chart I am using
chart.Series[mSeries].Points.AddXY(dt, avgData);
dt is current DateTime and the data.
So my Excel file look like
First Column is Series Name, second is DateTime and third column contain data.
So, can anyone please tell me how I can do this.
Thanks in Advance
You can refer to the following solution. First you will need to add reference to Microsoft Excel Object Library of COM. See this link on how to add. Then next step is pretty simple. You will need to add the code from the above link and replace the data which you fed in Excel with your custom data.
Here is the code shown in the link.
private void button1_Click(object sender, EventArgs e)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int i = 0; i < chart1.Series.Count; i++)
{
xlWorkSheet.Cells[1, 1] = "";
xlWorkSheet.Cells[1, 2] = "DateTime";//put your column heading here
xlWorkSheet.Cells[1, 3] = "Data";// put your column heading here
for (int j = 0; j < chart1.Series[i].Points.Count; j++)
{
xlWorkSheet.Cells[j + 2 , 2] = chart1.Series[i].Points[j].XValue;
xlWorkSheet.Cells[j + 2 , 3] = chart1.Series[i].Points[j].YValues[0];
}
}
Excel.Range chartRange;
Excel.ChartObjects xlCharts = (Excel.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(10, 80, 300, 250);
Excel.Chart chartPage = myChart.Chart;
chartRange = xlWorkSheet.get_Range("B2", "c5");//update the range here
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = Excel.XlChartType.xlColumnClustered;
xlWorkBook.SaveAs("csharp.net-informations.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
MessageBox.Show("Excel file created , you can find the file c:\\csharp.net-informations.xls");
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
Simply replace the cells and data from the code with your custom data and viola when you click on export button it will export it for you.

How to represent a property value in excel

My code works fine with generating an excel file, thanks to this community here.
But I still have a problem:
I have a ListBox from which I export a data to an excel file.
When I run it and the file will be created, I open it and in the rows I see
"SheduleMenager.Employees"
Employees is the class in my project in which i have two properties:
string Name and bool Experience
Here is a button to create and fill up the excel file :
private void Generateexcelfile_Click(object sender, RoutedEventArgs e)
{
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int i = 0; i < MonBox.Items.Count; i++)
{
xlWorkSheet.Cells[i + 1, 1] = MonBox.Items[i].ToString();
}
xlWorkBook.SaveAs("FILEPATH", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
}
I would be really happy if you can help me to represent a VALUE of Employees.Name
I'm guessing that MonBox contains list of employees, in Items collection.
If that is so, change your line
xlWorkSheet.Cells[i + 1, 1] = MonBox.Items[i].ToString();
into
xlWorkSheet.Cells[i + 1, 1] = (MonBox.Items[i] as SheduleMenager.Employees).Name;

Change the x axis values of graph c#

I am a little new to c# and Visual Studio and I am trying to plot a graph based on the values of a csv file located somewhere else. I have used the ChartObjects and ChartWizard property in c# to create the graph. The graph plotted should be the column range I am providing, in the Y-axis and X-axis should have the current row number(1,2,3,4 etc). However my graph by default takes the X-axis to be the first column in my csv file. It plots properly if I specify a range for X-axis too but how can I get the current row number there?
I went through a lot of articles and questions even on Stack Overflow but none seemed to help.
Here's a snippet of my code:
Microsoft.Office.Interop.Excel.Application xlexcel;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlexcel = new Microsoft.Office.Interop.Excel.Application();
var xlWorkBooks = xlexcel.Workbooks;
xlexcel.Visible = false;
xlWorkBooks.OpenText(#"C:\" + processName + ".csv", misValue, misValue, Microsoft.Office.Interop.Excel.XlTextParsingType.xlDelimited, Microsoft.Office.Interop.Excel.XlTextQualifier.xlTextQualifierNone, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);
// Set Sheet 1 as the sheet you want to work with
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBooks[1].Worksheets.get_Item(1);
xlWorkSheet.Shapes.AddChart(misValue, misValue, misValue, misValue, misValue).Select();
//~~> Make it a Line Chart
xlexcel.ActiveChart.ApplyCustomType(Microsoft.Office.Interop.Excel.XlChartType.xlLine);
//~~> Set the data range
xlexcel.ActiveChart.SetSourceData(xlWorkSheet.Range["E2:E200"]);
xlexcel.ActiveChart.ChartWizard(misValue, Title: chartName + " (" + processName + ")", CategoryTitle: "Iterations", ValueTitle: processType);
Microsoft.Office.Interop.Excel.ChartObjects chartObjects =(Microsoft.Office.Interop.Excel.ChartObjects)(xlWorkSheet.ChartObjects(Type.Missing));
foreach (Microsoft.Office.Interop.Excel.ChartObject co in chartObjects)
{
co.Select();
Microsoft.Office.Interop.Excel.Chart chart = (Microsoft.Office.Interop.Excel.Chart)co.Chart;
chart.Export(ConfigurationManager.AppSettings.Get("Charts") + "\\ProcessFiles" + #"\" + chartName + " (" + processName + "of" + processType + ")" + ".png", "PNG", false);
co.Delete();
}
xlWorkBooks[1].Close(true, misValue, misValue);
xlexcel.Quit();
Any guidance would be greatly appreciated.
Thanks!
I tried your code and made some modifications, I hope this will work
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
//string appPath = Path.GetDirectoryName(Application.ExecutablePath);
string fileName = "" + "YOUR_PATH" + "\\Templates\\myCSV.csv";
string processName = "test";
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(fileName);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet.Shapes.AddChart(misValue, misValue, misValue, misValue, misValue).Select();
//~~> Make it a Line Chart
xlApp.ActiveChart.ApplyCustomType(Microsoft.Office.Interop.Excel.XlChartType.xlLine);
//~~> Set the data range
xlApp.ActiveChart.SetSourceData(xlWorkSheet.Range["B1:B30"]);
string chartName = "TEST CHART", processType="TEST TYPE";
xlApp.ActiveChart.ChartWizard(misValue, Title: chartName + " (" + processName + ")", CategoryTitle: "Iterations", ValueTitle: processType);
Excel.ChartObjects chartObjects = (Excel.ChartObjects)(xlWorkSheet.ChartObjects(Type.Missing));
foreach (Excel.ChartObject co in chartObjects)
{
co.Select();
Excel.Chart chart = (Excel.Chart)co.Chart;
chart.Export("C:\\YOUR_PATH" + #"\" + chart.Name + ".png", "PNG", false);
}
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
xlWorkSheet = null;
xlWorkBook = null;
xlApp = null;
releaseObject(xlWorkBook);
releaseObject(xlWorkSheet);
releaseObject(xlApp);
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show(ex.Message);
}
finally
{
GC.Collect();
}
}

How to pass data from C# to an excel existing file

I want to make a button which you press for passing data from 3 textboxes to an excel table but I want to use the same table every time and just add data to a new row. Every time I want to add something, it creates me a new excel file. Here's my code.
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet.Cells[1, 1] = "Book name";
xlWorkSheet.Cells[1, 2] = "Author";
xlWorkSheet.Cells[1, 3] = "Rating";
string curFile = #"g:\Biblioteca.xls";
if (!File.Exists(curFile))
{
xlWorkBook.SaveAs("g:\\Biblioteca.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkSheet.Cells[++k, 1] = getName;
xlWorkSheet.Cells[k, 2] = getAuthor;
xlWorkSheet.Cells[k, 3] = getRating;
MessageBox.Show("Excel created succesfuly");
}
else
{
Excel.Application excelApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(curFile,
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
xlWorkSheet.Cells[++k, 1] = getName;
xlWorkSheet.Cells[k, 2] = getAuthor;
xlWorkSheet.Cells[k, 3] = getRating;
}
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
}
}
You are not opening any existing file!
See #gmiley's second reference for an example of opening an existing spreadsheet. You may need to study Range to work out how to place your new data.

How to create readonly Excel sheet using C# .net

I am creating a dynamic Excel sheet using ExcelWorksheet. I need to create a non-editable excel. ws.Cells["A1:Q12"].Style.Locked = true is not working.
Here is my code :
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string filePath = Server.MapPath("~/Download/Sample.xlsx");
using (ExcelPackage pck = new ExcelPackage())
{
FileInfo summaryFilePath = new FileInfo(filePath);
ExcelWorksheet ws= pck.Workbook.Worksheets.Add("Sample Page");
CreateForamters(ws);
}
}
private void CreateForamters(ExcelWorksheet ws)
{
ws.Cells["B8:L8"].Value = "SamplePage";
ws.Cells["B10:L10"].Value = DateTime.Now.ToString("MMM-yy");
ws.Cells["B11:L11"].Value = "test data........-";
ws.Cells["B8:L11"].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells["B8:L11"].Style.Font.Bold = true;
ws.Cells["B8:L11"].Style.Font.Name = "Arial";
ws.Cells["B8:L11"].Style.Font.Size = 16;
ws.Cells["B8:L11"].Style.Font.Color.SetColor(Color.Blue);
ws.Cells["B8:L11"].Style.Fill.BackgroundColor.SetColor(Color.White);
ws.Cells["B8:L11"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
ws.Cells["B8:L8"].Merge = true;
ws.Cells["B9:L9"].Merge = true;
ws.Cells["B10:L10"].Merge = true;
ws.Cells["B11:L11"].Merge = true;
ws.Cells["A1:Q12"].Style.Locked = true;
}
Thank you all in advance for your response.
I am creating a dynamic Excel sheet using ExcelWorksheet. I need to create a non-editable excel. ws.Cells["A1:Q12"].Style.Locked = true is not working.
To create NON-Editable Cells, you have to use
ws.get_Range("A1", "Q12").Locked = true;
And then you need to protect the worksheet. Without protecting the worksheet, the .Locked command doesn't have any significance.
Here is a basic example (TRIED AND TESTED IN VS2010 + OFFICE 2010)
object misValue = System.Reflection.Missing.Value;
ws.get_Range("A1", "Q12").Locked = true;
string Password = "Sid";
ws.Protect(Password, misValue, misValue, misValue, misValue, misValue,
misValue, misValue, misValue, misValue, misValue, misValue, misValue,
misValue, misValue, misValue);
NOTE: By default all cells in Excel are locked. If you don't want to protect the rest of the cells in the sheet then remember to set their .Locked property to False.
ws.Cells.Locked = false;
and then use the above code.
if you want to save Excel WorkBook as ReadOnly Save as Below:
object misValue = System.Reflection.Missing.Value;
ExcelWorkBook.ActiveWorkbook.SaveAs(save_path, Excel.XlFileFormat.xlWorkbookNormal, misValue , misValue , True, True,XlSaveAsAccessMode.xlShared, false, false, misValue, misValue , misValue );

Categories