0

Hi I keep getting this error from the below code, was wondering if anyone can help.

error processing excel file: cannot perform runtime binding on a null reference

Code:

    private void Import_Click(object sender, RoutedEventArgs e)
    {
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

        // Show open file dialog box
        Nullable<bool> result = dlg.ShowDialog();

        // Process open file dialog box results
        if (result == true)
        {
            // Open document
            string filename = dlg.FileName;

            Microsoft.Office.Interop.Excel.Application vExcelObj = new Microsoft.Office.Interop.Excel.Application();
            try
            {
                Microsoft.Office.Interop.Excel.Workbook theWorkbook = vExcelObj.Workbooks.Open(filename, Type.Missing, true);

                Microsoft.Office.Interop.Excel.Worksheet sheet = theWorkbook.Worksheets[1];  

                string vFirstName = "temp";
                string vLastName = "temp";
                int vIndex = 1;

                while (vFirstName != "")
                {
                    // Change the letters of the appropriate columns here!  
                    // In my example, 'A' is first name, 'B' last name
                    vFirstName = sheet.get_Range("A" + vIndex.ToString()).Value.ToString(); // if i take out the exception handling the error is on this line
                    vLastName = sheet.get_Range("B" + vIndex.ToString()).Value.ToString();


                    this.SaveNewCustomer(vFirstName, vLastName); 

                    vIndex++;

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error processing excel file : " + ex.Message);
            }
            finally
            {
                vExcelObj.Quit();
            }
        }
    }

    private void SaveNewCustomer(string firstName, string lastName) 
    {
        string uri = "http://localhost:8002/Service/Customer";
        StringBuilder sb = new StringBuilder();
        sb.Append("<Customers>");
        sb.AppendLine("<FirstName>" + firstName + "</FirstName>");
        sb.AppendLine("<LastName>" + lastName + "</LastName>");
        sb.AppendLine("</Customers>");
        string NewStudent = sb.ToString();
        byte[] arr = Encoding.UTF8.GetBytes(NewStudent);
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
        req.Method = "POST";
        req.ContentType = "application/xml";
        req.ContentLength = arr.Length;
        Stream reqStrm = req.GetRequestStream();
        reqStrm.Write(arr, 0, arr.Length);
        reqStrm.Close();
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        reqStrm.Close();
        resp.Close();
    }

}

The code just takes a excel document and trys to send the data to my web service.

So I tryed using the below method but it freezes the application :S no error just hangs. Edit attempt:

                while (vFirstName != "")
                {
                        var columnACell = sheet.get_Range("A" + vIndex.ToString());
                        var columnBCell = sheet.get_Range("B" + vIndex.ToString());
                        var columnACellValue = columnACell.Value;
                        var columnBCellValue = columnBCell.Value;


                    if (columnACellValue != null && columnBCellValue != null)
                    {
                        vFirstName = columnACellValue.ToString();
                        vLastName = columnBCellValue.ToString();

                        this.SaveNewStaff(vFirstName, vLastName); //, vPassword

                        vIndex++;
                    }
                }
            }

enter image description here

Kirsty White
  • 1,210
  • 3
  • 26
  • 54

3 Answers3

3

EDIT 2

Just took the code, and stepped through it. Found the problem. I think I misunderstood what was happening originally.

What's happening is that the loop while (vFirstName != "") will keep going until vFirstName is an empty string. But this will never happen! Here's why:

  • Everything will be fine as long as columns A and B will have values. The code will behave as expected.
  • When the code gets to an Excel row that doesn't have a value, it hits an empty cell, which will have .Value set to null. This causes the exception.

So the real solution here is to have the loop keep going until it hits a cell with a null value, and then exit. Kind of like this:

while (true) {
    // Split the satements 
    var columnACell = sheet.get_Range("A" + vIndex.ToString());
    var columnBCell = sheet.get_Range("B" + vIndex.ToString());
    var columnACellValue = columnACell.Value;
    var columnBCellValue = columnBCell.Value;

    if (columnACellValue != null && columnBCellValue != null) {
        vFirstName = columnACellValue.ToString();
        vLastName = columnBCellValue.ToString();

    } else {
        break;
    }

    this.SaveNewCustomer(vFirstName, vLastName);

    vIndex++;

};

Just tested this on my end, and it seems to work.

On a separate note, make sure that you're fully quitting Excel, because calling Excel.Quit() is often not enough. Open Task Manager and check whether there are any extra instances of EXCEL.exe floating around. To prevent those I usually kill Excel after I'm done with it (easier than properly releasing Excel's COM objects), as described in this post.


ORIGINAL POST

It sounds like there are a few options here:

  • The cell is empty, which means that it's .Value will be null.
  • The sheet is null,
  • get_Range() returns null -- that sounds unlikely.

Split the line into separate statements and see which one of them throws an error. That will tell you where to look further.

Judging by what you're doing -- searching the column until you find first name -- it sounds like you're running into nulls inside the cells' Values. To deal with that, I usually add a quick if-statement to test Value for null.

EDIT

Here's an example (may not compile) that will hopefully fix null values inside the cells and help to pinpoint other null-related problems. Replace the offending lines with something like this:

var columnACell = sheet.get_Range("A" + vIndex.ToString());
var columnBCell = sheet.get_Range("B" + vIndex.ToString())
var columnACellValue = columnACell.Value;
var columnBCellValue = columnBCell.Value;

if (columnACellValue != null && columnBCellValue != null) {
    vFirstName = columnACellValue.ToString(); 
    vLastName = columnBCellValue.ToString();
}

Note that I assume that your C# compiler supports implicit static typing through var.

Community
  • 1
  • 1
ikh
  • 2,336
  • 2
  • 19
  • 28
  • Can you provide an example, im rubbish with C had to get help trying to create this in the first place. This was the original [Question](http://stackoverflow.com/questions/11270839/excel-doc-contents-to-webservice)? – Kirsty White Jul 24 '12 at 20:24
  • 1
    This nails it. +1. The only other thing I'd add/change is that while splitting the line into several statements will help narrow it down (and should be done regardless), using a debugger and checking the inputs and outputs will make it a sure thing. – Beska Jul 24 '12 at 20:24
  • Hey I tryed your method but it freezes the application? I put an edit on my question not sure if im doing it correctly – Kirsty White Jul 24 '12 at 20:35
  • It is working btw but I cant stop it from freezing? No errors or anything are being thrown but checking my web service they have been added? – Kirsty White Jul 24 '12 at 20:37
  • Is it possible that none of the cells in those columns have values? In the above code, if column A or column B don't have values, the code will run until the bottom of the workbook. – ikh Jul 24 '12 at 20:41
  • Ok I have posted a snippet of sheet1 in the excel document, how do I get it to terminate once it gets to blank cells? – Kirsty White Jul 24 '12 at 20:43
  • 1
    Are you using Visual Studio? Try [debugging](http://www.dotnetperls.com/debugging) your application (either hit F5 or start the app and use Tools->Attach to Process...). Put a break point right before the `while` loop, and step through the statements to see what's going on. This may pinpoint possible problems. – ikh Jul 24 '12 at 20:48
  • It could also be that you're on the wrong worksheet. What if you select the worksheet by name instead of number, e.g. `Worksheet sheet = theWorkbook.Worksheets["Sheet 1"];`? – ikh Jul 24 '12 at 20:52
  • Same situation its freezing the application, breakpoints show nothing aswell. Arghhh – Kirsty White Jul 24 '12 at 20:57
  • 1
    Just updated the post. I think I found the problem; let me know if this helps. – ikh Jul 24 '12 at 21:21
  • What helped me here is putting a break point right at the beginning of the code and stepping through the code line by line (F10) to see what logic the code was following. Another hint when working with Excel in C#: try adding `vExcelObj.DisplayAlerts = false` right after you initialize `vExcelObject` to make sure that application does not hang on any accidental dialogs (e.g. if you've navigated through the workbook and are closing it without saving). – ikh Jul 24 '12 at 21:33
0

Sheet is null. Perhaps there is only 1 worksheet? You're using Worksheets[1] which returns the second one, of course.. :)

Kieren Johnstone
  • 41,277
  • 16
  • 94
  • 144
  • Are you sure? All excel docs have 3 sheets as standard and looking at mine it has 3 worksheets I have to reference just the first worksheet? – Kirsty White Jul 24 '12 at 20:19
  • 3
    I think Worksheets[] is one-based (starts at one instead of zero), so Worksheets[1] would be the first worksheet in this case. – Brian Snow Jul 24 '12 at 20:20
  • Well, couldn't it also be the get_Range call returning null, and then throwing when they try to get the Value on it? – Beska Jul 24 '12 at 20:21
0

Try to split the code that reads the value and test if it is null.

object oName = sheet.get_Range("A" + vIndex.ToString()).Value;
vFirstName = (oName == null ? string.Empty : oName.ToString();
object oLast = sheet.get_Range("B" + vIndex.ToString()).Value;
vLastName = (oLast == null ? string.Empty : oLast.ToString());
if(vFirstName.Length > 0 && vLastName.Length > 0)
     this.SaveNewCustomer(vFirstName, vLastName);   

And noticed that in your SaveNewStaff/Customer(....) you close the RequestStream two times. Perhaps the second close freeze your code.

    reqStrm.Close();  
    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();  
    reqStrm.Close();  // <= Already closed before?
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Hi tryed that same issue app still freezes. It strange aswell because they are still added to the service, just dont understand why the programme is freezing after i open and import the excel doc. – Kirsty White Jul 24 '12 at 21:07
  • If you set a breakpoint on the while instruction and then step through your code pressing F11, on which line the code freezes? – Steve Jul 24 '12 at 21:10