Hello I work on a method to extract data from Cells. This works but every time I reach an empty cell I get a NullBinderException.
My question is how can I prevent this?
Here is the part that makes problems:
while ((range.Cells[startpoint, cell] as Excel.Range).Value2.ToString() != null)
{
for (int i = 1; i <= numberOfColumns; i++)
{
string sValue = (range.Cells[startpoint, cell] as Excel.Range).Value2.ToString();
stringList.Add(sValue);
cell++;
}
startpoint++;
cell = 1;
}
Stuff that I tried:
range.Offset = Cant use becouse this is not an aviable Member.
IsNullOrEmpty = Makes no difference
So there is something I don't get. Any help or advise would be great and thanks for your time.
The Cell Range and/or Value2 may be null. Check these within your Where clause.
while ((range.Cells[startpoint, cell] as Excel.Range) != null && (range.Cells[startpoint, cell] as Excel.Range).Value2 != null)
{
for (int i = 1; i <= numberOfColumns; i++)
{
string sValue = (range.Cells[startpoint, cell] as Excel.Range).Value2.ToString();
stringList.Add(sValue);
cell++;
}
startpoint++;
cell = 1;
}
You can make your while loop as:-
while (! IsNull(range.Cells[startpoint, cell] as Excel.Range).Value2))
You could try catch you exception like:
try
{
while ((range.Cells[startpoint, cell] as Excel.Range).Value2.ToString() != null)
{
for (int i = 1; i <= numberOfColumns; i++)
{
string sValue = (range.Cells[startpoint, cell] as Excel.Range).Value2.ToString();
stringList.Add(sValue);
cell++;
}
startpoint++;
cell = 1;
}
}
catch(nullBinderException e)
{
//you find an empty cell
//... break? jump over and continue?
//... your logic...
}
Related
I want to add the exact value of textbox into datagridview my problem is if i will add another item the last item I add will also change. Here is the print screen of sample problem..
1st try
2nd try
This is my code.
int n = dataGridView3.Rows.Add();
for (int j = 0; j < dataGridView3.RowCount; j++)
{
if (dataGridView3.Rows[j].Cells[1].Value != null && (textBox4.Text == dataGridView3.Rows[j].Cells[4].Value.ToString()))
{
MessageBox.Show("Item Already on List!");
dataGridView3.Rows.Remove(dataGridView3.Rows[n]);
return;
}
else
{
dataGridView3.Rows[j].Cells[1].Value = textBox43.Text;
dataGridView3.Rows[j].Cells[4].Value = textBox4.Text;
dataGridView3.Rows[j].Cells[2].Value = DateTime.Now.ToShortDateString();
dataGridView3.Rows[j].Cells[3].Value = dateTimePicker3.Text;
dataGridView3.FirstDisplayedScrollingRowIndex = n;
dataGridView3.CurrentCell = dataGridView3.Rows[n].Cells[0];
dataGridView3.Rows[n].Selected = true;
}
}
You are looping over the complete array and if it is not yet on the list it goes in to the else part of your if. In that block you assign the current entered values to your row, for every single row you already have.
To fix that I separated the Check for duplicates and the Add part more clearly.
Do notice that if you would have run this through the debugger and stepped on each line of your code (hitting F10 in Visual Studio) you would have spotted this bug easily. Have a look at the blog from Scott Guthrie (among others) http://weblogs.asp.net/scottgu/debugging-tips-with-visual-studio-2010
// check if we already added that one
for (int j = 0; j < dataGridView3.RowCount; j++)
{
if (dataGridView3.Rows[j].Cells[1].Value != null && (textBox4.Text == dataGridView3.Rows[j].Cells[4].Value.ToString()))
{
MessageBox.Show("Item Already on List!");
return;
}
}
// lets add it!
int n = dataGridView3.Rows.Add();
dataGridView3.Rows[n].Cells[1].Value = textBox43.Text;
dataGridView3.Rows[n].Cells[4].Value = textBox4.Text;
dataGridView3.Rows[n].Cells[2].Value = DateTime.Now.ToShortDateString();
dataGridView3.Rows[n].Cells[3].Value = dateTimePicker3.Text;
dataGridView3.FirstDisplayedScrollingRowIndex = n;
dataGridView3.CurrentCell = dataGridView3.Rows[n].Cells[0];
dataGridView3.Rows[n].Selected = true;
I am trying to search every cell in my datagridview for a value "test". However it is only searching the first row... (i believe it is searching all the columns) Any ideas on how I can fix this?
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
string searchValue = "test";
int searching = -1;
while (searching < 7)
{
searching++;
try
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[searching].Value.ToString().Equals(searchValue))
{
row.Cells[searching].Selected = true;
break;
}
}
}
catch (Exception exc)
{
// MessageBox.Show(exc.Message);
}
}
use this snippet.. basically we iterate through every row/column and set its value as selected if we find a match.
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
string searchValue = "test";
for (int row = 0; row < dataGridView1.Rows.Count; ++row)
{
for (int col = 0; col < dataGridView1.Columns.Count; ++col)
{
var cellValue = dataGridView1.Rows[row].Cells[col].Value;
if (cellValue != null && cellValue.ToString().Equals(searchValue))
{
dataGridView1.Rows[row].Cells[col].Selected = true;
// if you want to search every cell for the searchValue then you shouldn't break.
// break;
}
}
}
you can also do the above as follows, using concise LINQ code:
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
string searchValue = "test";
dataGridView1.Rows.ToList().ForEach(row => row.Cells.ToList().ForEach(cell =>
{
cell.Selected = (cell.Value != null && cell.Value.ToString().Equals(searchValue));
}));
I have a function that retrieves a list of device names and stores then in a variable. Then the next step is to get info using 1 device name per line and keep going till the loop is complete.
String text = "";
String errors = "";
for (int i = 0; i < collection.Result.Count; i++)
{
deviceNames += collection.Result[i].DeviceName + Environment.NewLine;
getvirtuals.Location = deviceNames;
var virtuals = client.GetKnownVirtuals(getvirtuals, LtmKeyType.VirtualAddressPort);
if (virtuals.Result == null)
{
i++;
getvirtuals.Location = deviceNames;
for (int v = 0; v < virtuals.Result.Count; v++)
{
try
{
LtmKey virtualKey = new LtmKey();
virtualKey.Location = virtuals.Result[v].Location;
virtualKey.LocationType = virtuals.Result[v].LocationType;
virtualKey.Key = virtuals.Result[v].Key;
virtualKey.KeyType = LtmKeyType.VirtualAddressPort;
virtualKey.AdminGroup = admingroupComboBox.Text;
var memberStatus = client.GetMemberStatus(virtualKey);
for (int j = 0; j < memberStatus.Result.Count; j++)
{
VirtualMemberStatus status = memberStatus.Result[j];
text += String.Format("{5},{4},{0},{1},{2},{3}" + Environment.NewLine, status.Member.Address, status.Member.Port, status.EffectiveStatus, status.DesiredStatus, virtualKey.Key.Replace(":", ","), DateTime.UtcNow);
toolStripProgressBar1.PerformStep();
}
}
catch
{
errors += String.Format("{0} Error Code: 2, Error occurred, check device name (case senstive) and admin group. This error may also occur due to connection loss, try again." + Environment.NewLine, DateTime.UtcNow);
}
}
this.allResultsBox.Text = text;
getallstatusButton.Enabled = true;
}
}
The problem that I am running into is that if virtuals is null the tool crashes, instead what I want to do is if virtuals = null I want to move onto the next item from the list. I have tried a if statement but it is not working the way planned, it still comes back as null.
Well this seems like a problem to start with:
if (virtuals.Result == null)
{
i++;
getvirtuals.Location = deviceNames;
for (int v = 0; v < virtuals.Result.Count; v++)
...
If virtuals.Result is null, how do you expect virtuals.Result.Count to work? I suspect you meant:
if (virtuals.Result != null)
However, I suspect you really just want:
// Keep going with the next iteration of the for loop
if (virtuals == null || virtuals.Results == null)
{
continue;
}
If all you want is to go to the next loop iteration if virtuals is null then you want
if (virtuals == null) continue;
How about just inserting:
if(virtuals == null)
continue;
right after the line
var virtuals = client.GetKnownVirtuals(getvirtuals, LtmKeyType.VirtualAddressPort);
Have you tried changing the line:
if (virtuals.Result == null)
to:
if ((virtuals != null) && (virtuals.Result != null))
If this doesn't solve your issue, then you need to indicate what the additional errors are.
if (virtuals.Result == null)
make this
if (virtuals == null)
I have been saving into the ComboBox a value out of the selected column in datagridview with below code.
My question is:How can I prevent duplicate records when I save the values into the ComboBox? How can I do that?
Code:
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
CmbAra.Items.Add(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString());
}
Please try this
private void dgvServerList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
if (e.ColumnIndex == 1)
{
string id = dgvServerList[e.ColumnIndex, e.RowIndex].Value.ToString();
int duplicaterow = 0;
for (int row = 0; row < dgvServerList.Rows.Count; row++)
{
if (row != e.RowIndex && id == dgvServerList[e.ColumnIndex, row].Value.ToString())
{
duplicaterow = row + 1;
MessageBox.Show("Duplicate found in the row: " + duplicaterow);
this.dgvServerList[e.ColumnIndex, e.RowIndex].Value = "";
break;
}
}
}
}
catch
{
}
}
you could first transfer your datagridview items to a dictionary (which guarantees uniqueness) and then transfer that dictionary content to the combobox. or you could check for uniqueness yourself using a 'Contains' method on the combobox. you could even tie the dictionary to the combobox as a source for the combobox items.
Dictionary<string,bool> d = new Dictionary<string,bool>();
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
d[dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString()] = true;
}
CmbAra.Items.AddRange(d.Keys);
Use a set:
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
HashSet<string> set = new HashSet<string>();
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
string s = dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString();
if(!set.Contains(s)) {
CmbAra.Items.Add(s);
set.Add(s);
}
}
by using the following check and then determine to add or not
if(CmbAra.Items.Contains(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString()))
You can use the following code part.
if(!(CmbAra.Items.Contains(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString())))
{
CmbAra.Items.Add(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString());
}
else
{
MessageBox.Show("Value Already exists , not added");
}
I have an issue with a Loop that doesn't actually loop. I've posted a simplified version of my code below. Basically, using the NPOI excel library, I have an excel file with data on the first and second sheet, so I need to do a loop to get through both sheets.
Below is what I have done so far, however this only works through the first sheet and then exits. It fails to increment the variable w. As you can see, there are other loops implemented in this code which function fine so I don't get it.
It's been a very long day and perhaps I'm missing something very simple. I could have it placed wrong or something. If anyone else can spot what I might be doing wrong I'd be very grateful :)
public class SalesFileProcessor : ISalesProcessor
{
public List<FTPSalesRow> ProcessSalesFile(string filename)
{
try
{
using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read))
{
int numberOfSheets = 2;
//Loop through sheets - does not work
for (int w = 0; w <= numberOfSheets; w++)
{
HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs);
HSSFSheet sheet = templateWorkbook.GetSheetAt(w);
HSSFRow row = null;
for (int i = 1; i <= sheet.LastRowNum; i++)
{
FTPSalesDetails t = null;
int currentColumn = 0;
try
{
ModelContainer ctn = new ModelContainer();
row = sheet.GetRow(i);
if (row == null)
{
continue;
}
t = new FTPSalesDetails
{
RowNumber = i,
InvoiceDate = GetCellValue(row.GetCell(0)),
CountrySoldIn = GetCellValue(row.GetCell(1)),
NetUnitsSold = GetCellValue(row.GetCell(2)),
Item = GetCellValue(row.GetCell(3)),
ProductCode = GetCellValue(row.GetCell(5)),
};
if (t.ProductCode == null && t.NetUnitsSold == null)
{
return null;
}
int Qty = int.Parse(t.NetUnitsSold);
for (int x = 0; x < Qty; x++)
{
ItemSale ts = new ItemSale
{
ItemID = GetItemID(t.ProductCode),
ManufacturerID = GetManufacturerID("Samsung"),
DateSold = DateTime.Now,
};
ctn.AddToItemSales(ts);
ctn.SaveChanges();
}
}
catch (IndexOutOfRangeException) { }
}
} //End Loop - the one that doesn't work
}
}
catch (IOException exp)
{
throw new FTPSalesFileProcessingException("Could not open the Sales data file", exp);
}
catch (Exception exp)
{
throw new FTPSalesFileProcessingException("An unknown eror occured during processing the file", exp);
}
return null;
}
if (t.ProductCode == null && t.NetUnitsSold == null)
{
return null;
}
I'm going to guess that this is being hit, causing your entire function to exit. If you are trying to exit out of that iteration of the for loop try a break; instead, or a continue as Mike M pointed out in the comments.
For what you say, assuming your variables are all ok that is the loop is not empty... have you checked you're not hiting this line in the first iteration?
if (t.ProductCode == null && t.NetUnitsSold == null)
{
return null;
}
Looking at the code, the only obvious thing sticking out to me is:
HSSFSheet sheet = templateWorkbook.GetSheetAt(w);
HSSFRow row = null;
for (int i = 1; i <= sheet.LastRowNum; i++)
I would guess that sheet.LastRowNum either equals 0 or 1.
Maybe the indexOutOfRangeException is thrown and thats beacuse you have only one iteration, or instead of <= you sholud use <. Does the sheet numbers start with zero ?