Delete and remove the row matching string? - c#

I want to search for a string in DataTable if it starts with "null" delete this string, if this row has no values then erase this row too. Can someone show me how to do it?
ID Name Comment
2 lola hallo
5 miky hi
null0 // delete null0 and remove this row
null1 ko // delete null1 but do not remove this row
1 hub why
3 null2 //delete null2 but do not remove this row
I tried to delete "null" but it doesn't work.
My Code:
int ct1 = 0;
for (int i = 0; i < resE1.Rows.Count; i++ )
{
if(resE1.Rows[i]["SignalName"].ToString() == "null" + ct1)
{
resE1.Rows[i].SetField<String>(2, "");
}
ct1++;
}
I find a solution to replace "null*" with empty spaces, but now I want to erase this row if the cells values of this row are empty, how can i do it?
int ct1 = 0;
for (int i = 0; i < resE1.Rows.Count; i++)
{
string fix = resE1.Rows[i]["SignalName"].ToString();
if(fix.Contains("null"))
{
resE1.Rows[i].SetField<String>(2, "");
}
ct1++;
}

I tried this. Works for me.
List<DataRow> rowsToRemove = new List<DataRow>();
foreach (DataRow dr in resE1.Rows)
{
if (dr["Name"].ToString().IndexOf("null") == 0)
{
dr.SetField("Name", "");
}
bool hasValue = false;
for (int i = 0; i < dr.ItemArray.Count(); i++)
{
if (!dr[i].ToString().Equals(String.Empty))
hasValue = true;
}
if (!hasValue) rowsToRemove.Add(dr);
}
foreach(DataRow dr in rowsToRemove)
{
dr.Delete();
}

Here is your code changed so it works although I don't like how it is written. Check the answer:
int ct1 = 0;
int i = 0;
while(i < dt.Rows.Count)
{
if ( dt.Rows[i]["Name"].ToString() == "null" + ct1)
{
if ((dt.Rows[i][0] == null || dt.Rows[i][0].ToString() == string.Empty) && (dt.Rows[i][2] == null || dt.Rows[i][2].ToString() == string.Empty))
{
dt.Rows.RemoveAt(i);
i--;
}
else
{
dt.Rows[i].SetField<String>(1, "");
}
ct1++;
}
i++;
}

Assuming your DataTable has column "Name" of type string you can achieve it like this:
private DataTable RemoveUnwanted(DataTable source)
{
var rowsEnu = source.Rows.GetEnumerator();
while (rowsEnu.MoveNext())
{
((DataRow)rowsEnu.Current)["Name"] = ((DataRow)rowsEnu.Current)["Name"].ToString().StartsWith("null") ? string.Empty : ((DataRow)rowsEnu.Current)["Name"];
}
return (from i in source.AsEnumerable()
where !(i.ItemArray.All(o => string.IsNullOrEmpty(o.ToString())))
select i).CopyToDataTable();
}
You will also need reference to System.Data.DataSetExtensions.

To answer one of your questions, to delete the entire row do something like this:
if(resE1.Rows[i].Contains("null") && (resE1.Rows[i]["ID"].ToString() == "") && (resE1.Rows[i]["Comment"].ToString() == ""))
{
resE1.Rows[i].Delete();
}
bool emptyFlag = false;
if(resE1.Rows[i].Contains("null"))
{
for(int j = 0; j < resE1.Columns.Count; j++)
{
if(resE1.Rows[i][j].Equals(""))
emptyFlag = true;
else
emptyFlag = false;
}
if(emptyFlag)
resE1.Rows[i].Delete();
}

You need something like this:
String test = "Null01";
if (test.IndexOf("Null") == 0)
{
test = test.Replace("Null", String.Empty);
}
For second part of your question, just check if Comments are null or empty then replace the string too.
Arrange code according to your own requirement.

Related

Check value of datatable with C#

I want to check if values of datatable of the same column are equals to "int" or not , so if it's true i want to calculate with content value the sum. This is my code which return always when i click on sum button "pas tous entier" .
Thank you in advance!
private void button7_Click(object sender, EventArgs e)
{
int i = 0, s = 0;
String type ="int";
DataTable dt = new DataTable("Table_insertion");
bool exists = dt.AsEnumerable().Any(row => type == row.Field<String>("Type"));
if (exists== true)
{
for (i = 0; i < dataGridView1.Rows.Count; ++i)
{
s += Convert.ToInt32(dataGridView1.Rows[i].Cells[2].Value);
}
label5.Text = s.ToString();
}
else
{
MessageBox.Show("pas tous entiers");
}
}
The datatable seems unnecessary here.
Maybe the following is enough.
for (i = 0; i < dataGridView1.Rows.Count; ++i)
{
var str = dataGridView1.Rows[i].Cells[2].Value?.ToString();
if( !string.IsNullOrEmpty(str) && Int32.TryParse(str, out var parsed)
{
s += parsed;
}
}
If you want to check the type of the column in a datatable you can check its DataType.
foreach (var col in datatable1.Columns)
{
if ( col.DataType == typeof(System.Int16) || col.DataType == typeof(System.Int32)) // Or other types
{
....
Are you just trying to evaluate if the string returned contains only numbers? If so, you may want to use a regex match on the data. There is a great example here: Regex for numbers only

How do I set specific columns in a DataGridView to 0 if it is blank?

In this example I am looping through each cell individually.
However, I have a name column and another optional column which I want to avoid. So I'd rather want to loop through a specific set of columns without the optional one instead but I'm not sure how.
This is how I did the thorough sweep:
foreach (DataGridViewRow row in DGVExcel.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
if (row.Cells[i].Value == null || row.Cells[i].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[i].Value.ToString()))
{
row.Cells[i].Value = 0;
//DGVExcel.RefreshEdit();
}
}
}
However, I have a name column [...] so I'd rather'd loop through specific columns instead
If I understand you correctly you could get the index of the column and you can skip one for-loop:
int colindex = DGVExcel.Columns["SpecificColumnName"].Index;
foreach (var row in DGVExcel.Rows)
{
if (row.Cells[colindex].Value == null || row.Cells[colindex].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[colindex].Value.ToString()))
{
row.Cells[colindex].Value = 0;
//DGVExcel.RefreshEdit();
}
}
EDIT
Is there a way to list the excluded columns instead of the included ones, because listing each one would be messy
In this case I would leave it with 2 for-loops. Basically you could save all the names in a List and check whether it contains the name of the current column and if it doesn't then you can do your 0 replacement.
List<string> ExcludedColumnsList = new List<string> { "ExcludedColumnName_1", "ExcludedColumnName_2" };
foreach (DataGridViewRow row in DGVExcel.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
if (!ExcludedColumnsList.Contains(DGVExcel.Columns[i].Name))
{
if (row.Cells[i].Value == null || row.Cells[i].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[i].Value.ToString()))
{
row.Cells[i].Value = 0;
//DGVExcel.RefreshEdit();
}
}
}
}
Another option could also be to use linq. Get all indices except the excluded columns and foreach only through those:
List<string> ExcludedColumnsList = new List<string> { "ExcludedColumnName_1", "ExcludedColumnName_2" };
List<int> indexList = dataGridView1.Columns.Cast<DataGridViewColumn>()
.Where(x => !ExcludedColumnsList.Contains(x.Name))
.Select(x => x.Index).ToList();
foreach (DataGridViewRow row in DGVExcel.Rows)
{
foreach (int i in indexList)
{
if (row.Cells[i].Value == null || row.Cells[i].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[i].Value.ToString()))
{
row.Cells[i].Value = 0;
//DGVExcel.RefreshEdit();
}
}
}

How To Compare a Textbox With An Array in C#

I'm pretty new in C# and i couldn't find an answer for this.
I'm getting the values of a column named NUMERO_CTA from my DB in an array within valores variable. But I have to compare this array of values with a textbox to check if one of the values contained in valores matches with the value of the textbox named txtCuentaDestino. How can I compare a textbox.text with an array?. Thanks in advanced!
Here's my code:
DataTable tbl = ds.Tables[0];
for (int i = 0; i < tbl.Rows.Count; i++)
{
DataRow myRow = tbl.Rows[i];
valores = new string[] {myRow["NUMERO_CTA"].ToString()};
}
if (ds.Tables[0].Rows.Count == 0)
{
GuardaCuenta();
return false;
}
else if (txtCuentaDestino.Text == resultado)
{
return true;
}
else
{
return false;
}
You can't compare an array of strings and a string. You want to compare the string from the textbox to each string in your array, one at a time.
In this case if you want to check if there is a string in the array which matches your textbox string you can use the linq method Contains.
Ex.
if (arrayOfStrings.Contains(singleString))
{
// Do something
}
you need to iterate over the valores array and make the comparison.
foreach(string s in valores)
{
if(s == txtCuentaDestino.Text)
{
//do something magical
}
}
Thanks for the answers:
Both helped me a lot! Here is the result:
for (int i = 0; i < tbl.Rows.Count; i++)
{
DataRow myRow = tbl.Rows[i];
valores = new string[] { myRow["NUMERO_CTA"].ToString() };
foreach (string x in valores)
{
if (x.Contains(cuentaDestino))
{
f_Script("alerta", "<script>alert('Cuenta a crear ya Existe.');window.location.href = 'RW_CuentasBancarias.aspx';</script>");
contador = 1;
}
}
if (contador == 1)
{
break;
}
}
if(contador != 1){
GuardaCuenta();
f_Script("alerta", "<script>alert('Su cuenta ha sido creada.');window.location.href = 'RW_Solicitud_Reembolso.aspx';</script>");
}

Seeing if a notepad contains the same word as the combo box has selected

So what my problem is and i have looked on the internet for this but really cannot find out how to do it.
I want to use my combo box which is populated with items from a notepad. i want the combo box to search through the notepad when an items from the combo box is selected and when it gets a match i want it to return the line number(ID).
This is what i thought would work, but it doesn't full work.
int items = File.ReadLines(#"C:\Users\PC\Documents\File\IDs.txt").Count();
string line;
int thisnum;
if (cboItemPick.SelectedIndex != -1)
{
if (cboItemPick.SelectedItem != null)
{
for (int i = 0; i <items;)
{
items = i;
line = File.ReadLines(#"C:\Users\PC\Documents\File\IDs.txt").ElementAt(items);
if (line == cboItemPick.Text)
{
MessageBox.Show("Boom");
break;
}
else
{
i++;
}
}
}
}
First of all, your code will have very bad performances. Please refer to this reviewed example:
if( cboItemPick.SelectedItem != null) {
var filepath = #"C:\Users\PC\Documents\File\IDs.txt";
var lines = File.ReadLines(filepath);
var keyword = cboItemPIck.SelectedItem as String;
for(var i = 0; i < lines.length; i++) {
var line = lines[i];
if( string.Compare(line, keyword) == 0) {
// Good, you have a match!
MessageBox.Show(string.Format("Item found at line: {0}", i));
break;
}
}
}
I hope this can help you.
You can try this:
var lines = File.ReadLines(#"C:\Users\PC\Documents\File\IDs.txt");
var result = lines.Select((i, index) => new { Value = i, Index = index }).ToList();
//Check if cboItemPick.SelectedItem is valid and set it to comboboxValue
var lineNumber = result.First(i => i.Value == comboboxValue).Select(i => i.Index);

Find a row in dataGridView based on column and value

I have a dataGridView that has 3 columns: SystemId, FirstName, LastName that is bound using database information. I would like to highlight a certain row, which I would do using:
dataGridView1.Rows[????].Selected = true;
The row ID I however do not know and the bindingsource keeps changing, thus row 10 could be "John Smith" in one instance but not even exist in another (I have a filter that filters out the source based on what user enters, so typing in "joh" would yield all rows where first / last name have "joh" in them, thus my list can go from 50 names to 3 in a click).
I want to find a way how I can select a row based on SystemId and a corresponding number. I can get the system ID using the following method:
systemId = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["SystemId"].Value.ToString();
Now I just need to apply it to the row selector. Something like dataGridView1.Columns["SystemId"].IndexOf(systemId} but that does not work (nor does such method exist). Any help is greatly appreciated.
This will give you the gridview row index for the value:
String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
if(row.Cells[1].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
break;
}
}
Or a LINQ query
int rowIndex = -1;
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
.First();
rowIndex = row.Index;
then you can do:
dataGridView1.Rows[rowIndex].Selected = true;
The above answers only work if AllowUserToAddRows is set to false. If that property is set to true, then you will get a NullReferenceException when the loop or Linq query tries to negotiate the new row. I've modified the two accepted answers above to handle AllowUserToAddRows = true.
Loop answer:
String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
if (row.Cells["SystemId"].Value != null) // Need to check for null if new row is exposed
{
if(row.Cells["SystemId"].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
break;
}
}
}
LINQ answer:
int rowIndex = -1;
bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;
dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
.First();
rowIndex = row.Index;
dgv.AllowUserToAddRows = tempAllowUserToAddRows;
Or you can use like this. This may be faster.
int iFindNo = 14;
int j = dataGridView1.Rows.Count-1;
int iRowIndex = -1;
for (int i = 0; i < Convert.ToInt32(dataGridView1.Rows.Count/2) +1; i++)
{
if (Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value) == iFindNo)
{
iRowIndex = i;
break;
}
if (Convert.ToInt32(dataGridView1.Rows[j].Cells[0].Value) == iFindNo)
{
iRowIndex = j;
break;
}
j--;
}
if (iRowIndex != -1)
MessageBox.Show("Index is " + iRowIndex.ToString());
else
MessageBox.Show("Index not found." );
Try this:
string searchValue = textBox3.Text;
int rowIndex = -1;
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
try
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["peseneli"].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
dataGridView1.CurrentCell = dataGridView1.Rows[rowIndex].Cells[0];
dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Selected = true;
break;
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
If you just want to check if that item exists:
IEnumerable<DataGridViewRow> rows = grdPdfs.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue));
if (rows.Count() == 0)
{
// Not Found
}
else
{
// Found
}
This builds on the above answer from Gordon--not all of it is my original work.
What I did was add a more generic method to my static utility class.
public static int MatchingRowIndex(DataGridView dgv, string columnName, string searchValue)
{
int rowIndex = -1;
bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;
dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception
if (dgv.Rows.Count > 0 && dgv.Columns.Count > 0 && dgv.Columns[columnName] != null)
{
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.FirstOrDefault(r => r.Cells[columnName].Value.ToString().Equals(searchValue));
rowIndex = row.Index;
}
dgv.AllowUserToAddRows = tempAllowUserToAddRows;
return rowIndex;
}
Then in whatever form I want to use it, I call the method passing the DataGridView, column name and search value. For simplicity I am converting everything to strings for the search, though it would be easy enough to add overloads for specifying the data types.
private void UndeleteSectionInGrid(string sectionLetter)
{
int sectionRowIndex = UtilityMethods.MatchingRowIndex(dgvSections, "SectionLetter", sectionLetter);
dgvSections.Rows[sectionRowIndex].Cells["DeleteSection"].Value = false;
}
Those who use WPF
for (int i = 0; i < dataGridName.Items.Count; i++)
{
string cellValue= ((DataRowView)dataGridName.Items[i]).Row["columnName"].ToString();
if (cellValue.Equals("Search_string")) // check the search_string is present in the row of ColumnName
{
object item = dataGridName.Items[i];
dataGridName.SelectedItem = item; // selecting the row of dataGridName
dataGridName.ScrollIntoView(item);
break;
}
}
if you want to get the selected row items after this, the follwing code snippet is helpful
DataRowView drv = dataGridName.SelectedItem as DataRowView;
DataRow dr = drv.Row;
string item1= Convert.ToString(dr.ItemArray[0]);// get the first column value from selected row
string item2= Convert.ToString(dr.ItemArray[1]);// get the second column value from selected row
string text = "param";
var rows = dataGridViewlist.Rows.OfType<DataGridViewRow>()
.Select(x => new { Value = x.Cells[6].Value.ToString(), Index = x.Index }).ToList();
var index= rows.Where(w => w.Value == text).Select(s => s.Index).FirstOrDefault();
You can try:
string DT = string.Empty;
try
{
DT = $"{dataGridView1.SelectedRows[0].Cells[1].Value}-{dataGridView1.SelectedRows[0].Cells[2].Value}-{dataGridView1.SelectedRows[0].Cells[3].Value}-{dataGridView1.SelectedRows[0].Cells[4].Value}";
}
catch { }
try
{
dataGridView1.Rows.Cast<DataGridViewRow>().Where(x => $"{x.Cells[1].Value}-{x.Cells[2].Value}-{x.Cells[3].Value}-{x.Cells[4].Value}" == DT).ToList()[0].Selected = true;
}
catch (Exception ex) { }

Categories