Click here to Skip to main content
15,886,052 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello,

I have to get the information from a range of cells from an Excel file and transfer to a list to process it later on.

The case is that I do not know how long is the list of filled cells and I get an error when I read a cell further on the populated range.

The rest of the code works well until I reach the cell out of the range.

My code is as follows:

C#
// Get Data
string itemPartNumber;
int itemQuantity;
int iLoop = 2; // Skip the column title
bool exitLoop = false;

ClearList(ref bomList);  //Clear my destination list

while (!exitLoop)
{
    var itemPn = xlsSheet.Cells[iLoop,1].Value2;
    var itemQu = xlsSheet.Cells[iLoop,2].Value2;

    exitLoop = (itemPn == null);
    if (!exitLoop)
    {
        itemPartNumber = (string) itemPn;
        itemQuantity = Int32.Parse(itemQu.ToString());
        ComponentPNQ itemList = new ComponentPNQ(itemPartNumber, itemQuantity);
        bomList.Add(itemList);
        iLoop++;
    }
}



My problem is that I can not found the right comparison to exit the Loop, before I assing the values, that makes the error (it is marked on the "itemQuantity" row, that is an integer. No error with the string itemPartNumber, but then the loop never ends)

I have tryed several ways, but I am not able to solve it.

Can anyone give me an idea?

Thank you very much in advance.

David
PS: I would like to attach my excel file as example, but I do not get the way.
Posted
Updated 14-Mar-13 5:25am
v2
Comments
PeiWHoward 18-Jul-17 5:46am    
Check this excel automation's alternative, it provides a strongly typed value that you can use, for instance like this:

ExcelFile xlsBook = ExcelFile.Load("Sample.xls");
ExcelWorksheet xlsSheet = xlsBook.Worksheets[0];

bool exitLoop = false;

while (!exitLoop)
{
ExcelCell cellPn = xlsSheet.Cells[iLoop, 0];
ExcelCell cellQu = xlsSheet.Cells[iLoop, 1];

exitLoop = cellPn.ValueType == CellValueType.Null;
// ...
}

Also check here how to use Excel's cells and ranges in C#, notice that you have a general ExcelCell.Value but you also have strongly typed ExcelCell.IntValue, ExcelCell.StringValue, etc.

Hi,
you are using the implicit type var against the dynamic type Value2. the Value2 will return the type whether it is an int, string, or DateTime. Parsing an dynamic type to implicit type, you will not know what you are actually getting.

if you are sure that the item quantity is number, then you can explicitly define the type
C#
int itemQu = xlsSheet.Cells[iLoop,2].Value2;

So if the returned value type is wrong, then you code fail in that point, rather than failing later.
Also you have another problem of converting to string, if the value returned is null, and converting a null to string will throw exception. if I know the type, I wouldn't convert it for no reason.

Stick a break point on the ItemPn and ItemQu, make sure the type you are receiving, make those variable explicit, cast the Value2 to its correct type if you need to, the both your while loop and the parsing of the quantity will work.


Edit:
If the cell value is text then the Value2 will return type string, if the cell value is number then the Value2 will return type double. if the cell is empty the return type is COM object null.

so you need amend your code as follows:
C#
string itemPartNumber;
int itemQuantity;
int iLoop = 2; // Skip the column title

ClearList(ref bomList);  //Clear my destination list

while (!string.IsNullOrEmpty(itemPartNumber = xlsSheet.Cells[iLoop,1].Value2))
{
    itemQuantity = (int) (xlsSheet.Cells[iLoop,2].Value2 ?? 0);
    ComponentPNQ itemList = new ComponentPNQ(itemPartNumber, itemQuantity);
    bomList.Add(itemList);
    iLoop++;
}


Regards
Jegan
 
Share this answer
 
v4
Comments
NeueStudium2012 14-Mar-13 9:54am    
Hi Jegan,
Thank you for your answer.

I am sure that the first column "itemPn" will return a string (when populated). I expected to use that in order to get an empty string when there are no more values in the table and end the loop.

I also tryed to define itemPn as string (and itemQu as int in the way that you propose), but then I have an exception of incompatible type assignment when the cell is empty.

I do not find the right comparison to determine when there is no data in the cell. What would be the type for an empty cell? and what would be the "empty" value for that type to compare with?
I could also use the variable type to check the empty type, but I do not know the type returned in that case.

My intention is to avoid the error. I have also tryed with breakpoints, but I do not find a solution.

Regards,
David
Jegan Thiyagesan 14-Mar-13 10:32am    
See my edit.
NeueStudium2012 15-Mar-13 3:01am    
Hallo Jegan,

Your proposal is fine and works. Thank you very much for your help.

Anyway, I adpoted a little different solution.
I leave it here for a future reference.

Best regards,
David.
 
Share this answer
 
Comments
NeueStudium2012 14-Mar-13 9:37am    
I have already found those two links, but unfortunately they do not solve my problem.
Thank you anyway.
Please, read this: var (C# reference)[^] and this: Implicity Typed Local Variables (C# programming guide)[^].

Try to change the type of variables declaration:
C#
string itemPn = xlsSheet.Cells[iLoop,1].Text;
string itemQu = xlsSheet.Cells[iLoop,2].Text;

then check if string IsNullOrEmpty[^].

;)
 
Share this answer
 
Comments
NeueStudium2012 15-Mar-13 3:13am    
Hallo Maciej

It does not work, as the string throws an error for null values.
Thank you anyway.
David
Jegan Thiyagesan 15-Mar-13 6:06am    
Hi Maciej,
The "xlsSheet.Cells[iLoop,1]" is a dynamic type, it returns a type during runtime, so during compile time you will not know what type is going to return, according to Microsoft we should be using "dynamic" type as
dynamic itemPn = xlsSheet.Cells[iLoop,1];

string str = (itemPn != null)? itemPn.ToString(): ""; // there is no reason why you shouldn't parse the type as it is, if you know the retuen value is text or a number, rather than converting to string.

http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx // half way down the page "Avoid the use of var in place of dynamic".
http://msdn.microsoft.com/en-us/library/vstudio/dd264741.aspx
Here is my solution.
Thank you for all your contributions.

C#
string itemPartNumber;
int itemQuantity;
int iLoop = 2;
bool exitLoop = false;

ClearList(ref bomList);

while (!exitLoop)
 {
     var itemPn = xlsSheet.Cells[iLoop, partColumn].Value2;
     var itemQu = xlsSheet.Cells[iLoop, quantityColumn].Value2;

     exitLoop = string.IsNullOrEmpty(itemPn);
     if (!exitLoop)
     {
         itemPartNumber = itemPn;
         itemQuantity = Convert.ToInt32(itemQu);
         ComponentPNQ itemList = new ComponentPNQ(itemPartNumber, itemQuantity);
         bomList.Add(itemList);
         iLoop++;
     }
 }
 
Share this answer
 
Comments
Jegan Thiyagesan 15-Mar-13 6:15am    
Hi Dave,
You are not checking for itemQu for null, Convert.ToIn32(null) will throw exception.

Also according to you code if the itemPn is null, then you not using the itemQu, this is why I have optimized the code in my solution version 4 such that, if the itemPn is null the code will not check for itemQu and you will not need to allocate an extra variable 'exitLoop'. Remember, every line of code is going to allocate some memory and consume time. Remember the less line of code the better the throughput.
NeueStudium2012 18-Mar-13 8:30am    
Hi Jegan,
Thank you for your Advice.
The rows that contain values in itemPn also do in itemQn (it is programmtically generated), so I do not take care about it.
Also I will use exitloop further on, but I think it is not advisable to write here the whole code.
Even though, I can save some lines.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900