"Exception from HRESULT: 0x800A01A8" - c#

I've written this code to count the number of rows that are populated in an excel worksheet. It works until it gets yo a certain number of rows (not the total). Then comes up with the error message "Exception from HRESULT: 0x800A01A8" Any help much appreciated
namespace ConsoleApplication1
{
class ExcelClass
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Excel.Application excelApp = new Excel.Application(); // Creates a new Excel Application
excelApp.Visible = true; // Makes Excel visible to the user.
// The following code opens an existing workbook
string workbookPath = "D:\\RSG_D.xls"; // Add your own path here
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath, 0,
false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true,
false, 0, true, false, false);
// The following gets the Worksheets collection
Excel.Sheets excelSheets = excelWorkbook.Worksheets;
// The following gets Sheet1 for editing
string currentSheet = "Sheet1";
Excel.Worksheet excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(currentSheet);
//declare a variable to hold the CurrentCulture
System.Globalization.CultureInfo oldCI;
//get the old CurrenCulture and set the new, en-US
//void SetNewCurrentCulture()
//{
oldCI = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
//}
int rowCounter = 1;
while ( rowCounter != null)
{
Excel.Range countRows = (Excel.Range)excelWorksheet.Cells[rowCounter, 1] as Excel.Range;
object CountRows = countRows.Value;
rowCounter++;
Console.WriteLine(CountRows);
}
excelWorkbook.Close(0);
excelApp.Quit();
//reset Current Culture back to the originale
System.Threading.Thread.CurrentThread.CurrentCulture = oldCI;
}
}
}

I had the exact same problem tonight: Here is the code I have used and it's worked properly for me:
Excel.Application oExcel = new Excel.Application();
//oExcel.Visible = true; (this caused me huge problems
Excel.Workbook oBook = oExcel.Workbooks.Open(#"C:\Yoink\Birr Castle Demesne Interactive Map\Birr Castle Demesne Interactive Map\bin\Debug\Red Tree Trail.xlsx");
Excel.Worksheet oSheet1 = oBook.Worksheets["Red Tree Trail"] as Excel.Worksheet; (use your own worksheet title there)
Excel.Range rng = oSheet1.get_Range("A1", "AJ51"); (use your own range there
int rowCount = rng.Rows.Count;
int colCount = rng.Columns.Count;
string[,] tsReqs = new string[rowCount, colCount];
for (int i = 1; i <= rowCount; i++)
{
for (int j = 1; j <= colCount; j++)
{
string str = rng.Cells[i, j].Text;
tsReqs[i - 1, j - 1] = str;
}
}
I think your problem is in this line:
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath, 0,
false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true,
false, 0, true, false, false);

Related

Reading Cell Value of Excel in C#, null reference exception

I am trying to read the cell value from an Excel sheet, and used Value and Value2 to see the Cell value. It keeps throwing "System.NullReferenceException: 'Object reference not set to an instance of an object.'" Error. I am unable to figure out where is the issue in code.
I know the file path and the Excel sheet it's reading is correct.
public String readEDriver()
{
int nRows = 1;
int nCols = 1;
String driverLoc = null;
Excel.Application excelApp = new Excel.Application();
if (excelApp != null)
{
Workbook excelWorkbook;
excelWorkbook = excelApp.Workbooks.Open("C:\\A\\Config.xlsx", 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
Worksheet excelWorksheet;
excelWorksheet = (Excel.Worksheet)excelWorkbook.Worksheets[1];
excelWorksheet.Activate();
String eName =excelWorksheet.Name;
if (excelWorksheet == null)
{
throw new Exception(string.Format("Named worksheet ({0}) not found.", excelWorksheet));
}
else
{
var cellVal = ((Microsoft.Office.Interop.Excel.Range)excelWorksheet.Cells[nRows, nCols]).Value2;
if (excelWorksheet.Cells[nRows,nCols]!=null)
{
cellVal = ((Microsoft.Office.Interop.Excel.Range)excelWorksheet.Cells[nRows, nCols]).Value2;
driverLoc = cellVal.ToString();
}
}
excelWorkbook.Close();
excelApp.Quit();
}
return driverLoc;
}
it breaks at the
var cellVal = ((Microsoft.Office.Interop.Excel.Range)excelWorksheet.Cells[nRows, nCols]).Value2;
It fails to retrieve the Excel Range and gives NullReferenceException
Message:
System.NullReferenceException : Object reference not set to an instance of an object.
Stack Trace:
I tried your code because it seemed OK.
It works for me with a couple of minor compiling topics:
1.- Use "/" instead od "\" for the paths. Windows doesn´t like those.
2.- I had to add the Excel.Workbook and Excel.Worksheet because the compiler warned me
Apart from that it works. Below your code with my slight corrections.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string aux = readEDriver();
Console.WriteLine(aux);
Console.ReadLine();
}
public static string readEDriver()
{
int nRows = 1;
int nCols = 1;
String driverLoc = null;
Excel.Application excelApp = new Excel.Application();
if (excelApp != null)
{
Excel.Workbook excelWorkbook;
excelWorkbook = excelApp.Workbooks.Open("C:/Users/Usuario/Desktop/PruebasTxtFile.xlsx", 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
Excel.Worksheet excelWorksheet;
excelWorksheet = (Excel.Worksheet)excelWorkbook.Worksheets[1];
excelWorksheet.Activate();
String eName = excelWorksheet.Name;
if (excelWorksheet == null)
{
throw new Exception(string.Format("Named worksheet ({0}) not found.", excelWorksheet));
}
else
{
var cellVal = ((Microsoft.Office.Interop.Excel.Range)excelWorksheet.Cells[nRows, nCols]).Value2;
if (excelWorksheet.Cells[nRows, nCols] != null)
{
cellVal = ((Microsoft.Office.Interop.Excel.Range)excelWorksheet.Cells[nRows, nCols]).Value2;
driverLoc = cellVal.ToString();
}
}
excelWorkbook.Close();
excelApp.Quit();
}
return driverLoc;
}
}
}
Hope that helps!

excel import using c#

i am working on excel import to grid view using DataTable in c#, but my problem is its working fine on my local system but its redirecting to login page on my online server and i have tried both Microsoft.Office.Interop.Excel & OLEdb connection. but the problem is same. please tell me what is the problem with these or any one have any other function to import Excel data in GridView.
private void processExcel(string filename)
{
filename = Server.MapPath("~/Files/WM-0b23-productsBook.xlsx");
Microsoft.Office.Interop.Excel.Application xlApp;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
var missing = System.Reflection.Missing.Value;
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(filename, false, true, missing, missing, missing, true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, '\t', false, false, 0, false, true, 0);
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Microsoft.Office.Interop.Excel.Range xlRange = xlWorkSheet.UsedRange;
Array myValues = (Array)xlRange.Cells.Value2;
int vertical = myValues.GetLength(0);
int horizontal = myValues.GetLength(1);
System.Data.DataTable dt = new System.Data.DataTable();
// must start with index = 1
// get header information
for (int i = 1; i <= horizontal; i++)
{
dt.Columns.Add(new DataColumn(myValues.GetValue(1, i).ToString()));
}
// Get the row information
for (int a = 2; a <= vertical; a++)
{
object[] poop = new object[horizontal];
for (int b = 1; b <= horizontal; b++)
{
poop[b - 1] = myValues.GetValue(a, b);
}
DataRow row = dt.NewRow();
row.ItemArray = poop;
dt.Rows.Add(row);
}
// assign table to default data grid view
GridView1.DataSource = dt;
GridView1.DataBind();
xlWorkBook.Close(true, missing, missing);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
Have a look:
private void processExcel(string filename)
{
filename = Server.MapPath("~/Files/WM-0b23-productsBook.xlsx");
Microsoft.Office.Interop.Excel.Application xlApp;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
var missing = System.Reflection.Missing.Value;
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(filename, false, true, missing, missing, missing, true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, '\t', false, false, 0, false, true, 0);
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Microsoft.Office.Interop.Excel.Range xlRange = xlWorkSheet.UsedRange;
Array myValues = (Array)xlRange.Cells.Value2;
int vertical = myValues.GetLength(0);
int horizontal = myValues.GetLength(1);
System.Data.DataTable dt = new System.Data.DataTable();
// must start with index = 1
// get header information
for (int i = 1; i <= horizontal; i++)
{
dt.Columns.Add(new DataColumn(myValues.GetValue(1, i).ToString()));
}
// Get the row information
for (int a = 2; a <= vertical; a++)
{
object[] poop = new object[horizontal];
for (int b = 1; b <= horizontal; b++)
{
poop[b - 1] = myValues.GetValue(a, b);
}
DataRow row = dt.NewRow();
row.ItemArray = poop;
dt.Rows.Add(row);
}
// assign table to default data grid view
GridView1.DataSource = dt;
GridView1.DataBind();
xlWorkBook.Close(true, missing, missing);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
It is better not using MS Office interop in server cases which will bring a lot of performance and memory issues in the future. Recommend using some 3rd party library, for example: https://www.nuget.org/packages/Spread.Services/ to get what you wanted.

How to check if a cell is empty (Excel\VisualC#)

My aim is to check line per line in the Sheet1 in order to discover how many rows are, so i put a do\while that should stop once it reaches a blank cell
Example:
row1 data row2 data row3 datarow4 datarow5 data
row6 data row7 data
In this case I need only the first 5 rows, so the do\while check is intended to stop once it reaches the blank cell. This doesn't happens, because the check doesn't loop (it stops after completing a circle like it finds a blank cell even if it is filled with data).
string str;
int rCnt = 11; //the data I need is after the 10th row in excel
int cCnt = 1;
int valori = 1;
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(label4.Text, 0, false, 5, "", "",
false, Excel.XlPlatform.xlWindows,
"", true, false, 0, true, false,
false);
Excel.Sheets xlsheet = xlWorkbook.Worksheets;
string sheet1 = "Sheet1";
Excel.Worksheet xlWorksheet = (Excel.Worksheet)xlsheet.get_Item(sheet1);
Excel.Range xlCell;
do
{
rCnt++;
str = "A" + rCnt;
xlCell = (Excel.Range)xlWorksheet.get_Range(str, str);
} while (xlCell.Value2 == null);
I tried changing Value2 to Value or Text and trying to set == "" instead of null.
If you want the loop stop when reach blank cell then .. Try to change
while (xlCell.Value2 == null);
with
while (! IsNull(xlCell.Value2));
Simple way to check a cell is empty:
if (sheet.Cells[4,3] == null || sheet.Cells[4,3].Value2 == null || sheet.Cells[4,3].Value2.ToString() == "")
MessageBox.Show(“cell on row 4 col 3 is empty”);
You can use the Text property of the selected cell. It can be converted to a string type via "as". The result string can already be checked as usual in C#, like not-empty
string TempText = excelWorksheet.Cells[1, 1].Text as string;
if (!string.IsNullOrWhiteSpace(TempText)){
// actions
}
The issue mainly comes from when you don't know what sort of data to expect. When I work with Excel reads I often do something similar to:
var _cell = range.Cells[1, 2].Value2;
if (_cell.GetType() != typeof(Double))
In your instance if you always are getting a string returned then you should be able to assume the cast:
string _str = (string)(range.Cells[str, str] as Excel.Range).Value2;
and then check that is not empty.
This is working for me:
using Excel = Microsoft.Office.Interop.Excel; to read excelsheet:
var excelApp = new Excel.Application();
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(path, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Excel.Worksheet excelWorksheet = (Excel.Worksheet)excelWorkbook.Sheets[2];
Excel.Range excelRange = excelWorksheet.UsedRange;
int rowCount = excelRange.Rows.Count;
int colCount = excelRange.Columns.Count;
string wwdEmpty = Convert.ToString(excelRange.Cells[5, 14].value2);
// this is working code with NULL Excell cell
do
{
rCnt++;
str = Sheet.Cells[rCnt, 5].Value;
} while (str != null);

I want to Read Multiple excel sheets in one file without using OLEDB in C#

Im reading an Excel document from C# Windows Form.. There are 25 worksheets in Excel Workbook.. i can read 1st worksheet successfully.. But when i change it to worksheet 2.. it won't working at all.. Im not using OLEDB..
I want to read 100 Row in every sheet.. following is my code...
` dt.Columns.Add("Amount", typeof(double));
dt.Columns.Add("ChequeNo", typeof(int));
dt.Columns.Add("month", typeof(int));
int AmountRow = 100;
int ChequeNoRow = 101;
int Column = 3;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open(path, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Sheets[2];\\This place is the changing worksheets
range = xlWorkSheet.UsedRange;
double chequeAmount;
double chequeNo;
for (int i = Column; i < 15; i++)
{
chequeAmount = (double)(range.Cells[AmountRow, i] as Excel.Range).Value2;
chequeNo = (double)(range.Cells[ChequeNoRow, i] as Excel.Range).Value2;
if (chequeNo != 0.0)
{
dt.Rows.Add(Convert.ToDouble(chequeAmount), Convert.ToInt32(chequeNo), i);
}
}
dataGridView1.DataSource = dt;
xlWorkBook.Close(true, null, null);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);`
releaseObject methods are not here.. those working perfectly...
`xlWorkSheet = (Excel.Worksheet)xlWorkBook.Sheets[1];`
This is how i change my worksheets.. The following line gives an exception..[Null point Exception]
chequeAmount = (double)(range.Cells[AmountRow, i] as Excel.Range).Value2;
Hope you'll know answers..
Try this instead:
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets[2];
The Sheets property can include non-worksheet sheets, which could be the issue in your scenario.

Import excel sheet data to datagrid without using oledb

In my Windows based application(C#)
i want to import excel sheet to show its data in DatatGridView
i dont want to use oledb
any Help
using Excel = Microsoft.Office.Interop.Excel;
You'll obviously need to add the reference to your project, and then it's plain simple :)
private void ProcessExcel(string filepath)
{
Excel.ApplicationClass ExcelObj = new Excel.ApplicationClass();
Excel.Workbook theWorkbook = ExcelObj.Workbooks.Open(filepath, 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);
Excel.Sheets sheets = theWorkbook.Worksheets;
Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);
Excel.Range range = worksheet.UsedRange;
System.Array myvalues = (System.Array)range.Cells.Value2;
int vertical = myvalues.GetLength(0);
int horizontal = myvalues.GetLength(1);
string[] headers = new string[horizontal];
string[] data = new string[horizontal];
DataTable ResultsHeader = New DataTable();
DataSet ds = New DataSet();
for (int x = 1; x <= vertical; x++)
{
Utils.inicializarArrays(datos);
for (int y = 1; y <= horizontal; y++)
{
if (x == 1)
{
headers[y - 1] = myvalues.GetValue(x, y).ToString();
}
else
{
string auxdata = "";
if (myvalues.GetValue(x, y) != null)
auxdata = myvalues.GetValue(x, y).ToString();
data[y - 1] = auxdata;
}
}
if(x == 1) //headers
{
for(int w = 0; w < horizontal; w++)
{
ResultsHeader.Columns.Add(New DataColumn(headers[w], GetType(string)));
}
ds.Tables.Add(ResultsHeader);
}
else
{
DataRow dataRow = ds.Tables[0].NewRow();
for(int w = 0; w < horizontal; w++)
{
dataRow(headers[w]) = data[w]
}
ds.Tables[0].Rows.Add(dataRow);
}
}
DataView myDataView = new DataView();
myDataView.Table = ds.Tables[0];
MydataGrid.CurrentPageIndex = 0;
MydataGrid.DataSource = myDataView;
MydataGrid.DataBind();
}
I'm late to the party, but I have something worthwhile to add! I tried Juan's code and it didn't compile out-of-the-box. I modified it a little bit after researching the internet for a few more hours and got it to do exactly what the original poster asked (as I needed to do the same thing). I had to piece code together from other sources, and unfortunately, I did not keep track of what bits and pieces I tried and changed so I can't comment much about it.
The following code works in Visual Studio 2008 with .NET 3.5. Also, the formatting is lost when the data is put into the array (for example, dates become doubles which require a conversion with DateTime.FromOADate() to change it back). The issue with that is you can't tell if a value is an actual double or a date from a coding viewpoint, but if you know ahead of time a column is going to be a date, then format it as you insert the data into the table.
private void processExcel(string filename)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
var missing = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open(filename, false, true, missing, missing, missing, true, Excel.XlPlatform.xlWindows, '\t', false, false, 0, false, true, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Excel.Range xlRange = xlWorkSheet.UsedRange;
Array myValues = (Array)xlRange.Cells.Value2;
int vertical = myValues.GetLength(0);
int horizontal = myValues.GetLength(1);
DataTable dt = new DataTable();
// must start with index = 1
// get header information
for (int i = 1; i <= horizontal; i++)
{
dt.Columns.Add(new DataColumn(myValues.GetValue(1,i).ToString()));
}
// Get the row information
for (int a = 2; a <= vertical; a++)
{
object[] poop = new object[horizontal];
for (int b = 1; b <= horizontal; b++)
{
poop[b - 1] = myValues.GetValue(a, b);
}
DataRow row = dt.NewRow();
row.ItemArray = poop;
dt.Rows.Add(row);
}
// assign table to default data grid view
dataGridView1.DataSource = dt;
xlWorkBook.Close(true, missing, missing);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
Those codes above does not work.
That code works for me (.NET Framework 4.7.1)
private void processExcel(string filename)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
var missing = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(filename, false, true, missing, missing, missing, true, Excel.XlPlatform.xlWindows, '\t', false, false, 0, false, true, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Excel.Range xlRange = xlWorkSheet.UsedRange;
Array myValues = (Array)xlRange.Cells.Value2;
int vertical = myValues.GetLength(0);
int horizontal = myValues.GetLength(1);
DataTable dt = new DataTable();
// must start with index = 1
// get header information
try
{
for (int i = 1; i <= horizontal; i++)
{
dt.Columns.Add(new DataColumn(Convert.ToString(myValues.GetValue(1, i))));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
// Get the row information
for (int a = 2; a <= vertical; a++)
{
object[] rows = new object[horizontal];
for (int b = 1; b <= horizontal; b++)
{
rows[b - 1] = myValues.GetValue(a, b);
}
DataRow row = dt.NewRow();
row.ItemArray = rows;
dt.Rows.Add(row);
}
// assign table to default data grid view
dataGridView1.DataSource = dt;
xlWorkBook.Close(true, missing, missing);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}

Categories