How can I read data from DataGridView in C#? I want to read the data appear in Table. How do I navigate through lines?
something like
for (int rows = 0; rows < dataGrid.Rows.Count; rows++)
{
for (int col= 0; col < dataGrid.Rows[rows].Cells.Count; col++)
{
string value = dataGrid.Rows[rows].Cells[col].Value.ToString();
}
}
example without using index
foreach (DataGridViewRow row in dataGrid.Rows)
{
foreach (DataGridViewCell cell in row.Cells)
{
string value = cell.Value.ToString();
}
}
If you wish, you can also use the column names instead of column numbers.
For example, if you want to read data from DataGridView on the 4. row and the "Name" column.
It provides me a better understanding for which variable I am dealing with.
dataGridView.Rows[4].Cells["Name"].Value.ToString();
Hope it helps.
string[,] myGridData = new string[dataGridView1.Rows.Count,3];
int i = 0;
foreach(DataRow row in dataGridView1.Rows)
{
myGridData[i][0] = row.Cells[0].Value.ToString();
myGridData[i][1] = row.Cells[1].Value.ToString();
myGridData[i][2] = row.Cells[2].Value.ToString();
i++;
}
Hope this helps....
Code Example : Reading data from DataGridView and storing it in an array
int[,] n = new int[3, 19];
for (int i = 0; i < (StartDataView.Rows.Count - 1); i++)
{
for (int j = 0; j < StartDataView.Columns.Count; j++)
{
if(this.StartDataView.Rows[i].Cells[j].Value.ToString() != string.Empty)
{
try
{
n[i, j] = int.Parse(this.StartDataView.Rows[i].Cells[j].Value.ToString());
}
catch (Exception Ee)
{ //get exception of "null"
MessageBox.Show(Ee.ToString());
}
}
}
}
private void HighLightGridRows()
{
Debugger.Launch();
for (int i = 0; i < dtgvAppSettings.Rows.Count; i++)
{
String key = dtgvAppSettings.Rows[i].Cells["Key"].Value.ToString();
if (key.ToLower().Contains("applicationpath") == true)
{
dtgvAppSettings.Rows[i].DefaultCellStyle.BackColor = Color.Yellow;
}
}
}
Related
I'm trying to compare the rows and columns with 2 datagridview. The first column s1 in (DGV1) has found the duplicate values in s1 (DGV2). The second column s2 in (DGV1) is mismatched with the second column s2 in (DGV2). What's wrong with the code?
for (int i = 0; i < dataGridView1.RowCount ; i++)
{
for (int j = 0; j < dataGridView2.RowCount; j++)
{
if ( dataGridView1.Rows[i].Cells[0].Value.ToString() ==
dataGridView2.Rows[j].Cells[0].Value.ToString())
{
dataGridView1.Rows[i].Cells[0].Style.BackColor =
Color.Yellow;
dataGridView2.Rows[j].Cells[0].Style.BackColor =
Color.YellowGreen;
}
}
}
enter image description here
try this
for (int i = 0; i < dataGridView1.RowCount ; i++)
{
for (int j = 0; j < dataGridView2.RowCount; j++)
{
if ( (dataGridView1.Rows[i].Cells[0].Value.ToString() ==
dataGridView2.Rows[j].Cells[0].Value.ToString()) &&
(dataGridView1.Rows[i].Cells[1].Value.ToString() ==
dataGridView2.Rows[j].Cells[1].Value.ToString()) )
{
dataGridView1.Rows[i].Cells[0].Style.BackColor =
Color.Yellow;
dataGridView1.Rows[i].Cells[1].Style.BackColor =
Color.Yellow;
dataGridView2.Rows[j].Cells[0].Style.BackColor =
Color.YellowGreen;
dataGridView2.Rows[j].Cells[1].Style.BackColor =
Color.YellowGreen;
}
}
}
foreach (DataGridViewRow row1 in table1.Rows) //LOOP ROWS TABLE 1
{
foreach (DataGridViewCell cell1 in row1.Cells) //LOOP COLUMNS TABLE 1
{
foreach (DataGridViewRow row2 in table2.Rows) //LOOP ROWS TABLE 2
{
foreach (DataGridViewCell cell2 in row2.Cells) //LOOP COLUMNS TABLE 2
{
if (cell1.Value != null && cell2.Value != null&& cell2.Value.ToString() == cell1.Value.ToString())
{
cell1.Style.BackColor = Color.Yellow;
cell2.Style.BackColor = Color.YellowGreen;
}
}
}
}
}
Hey Marcel16, this should solve your problem:
I want to extract some data in the datatable, and want to send the email.
But when I extract the data, excel has many blanks between the extracted data.
The data which is not extracted make a blank row.
When I try to use RemoveRow() function, it doesn't work and still has a blank row.
private void Email()
{
//get the data from database
DataTable data = GetData();
int maxLavel = Convert.ToInt32(data.Compute("max([AssignedID])", string.Empty));
IWorkbook workbook;
workbook = new HSSFWorkbook();
for (int Emp = 0; Emp < maxLavel; Emp++)
{
ISheet sheet1 = workbook.CreateSheet("Sheet 1");
int num = 0;
//make a header row
IRow row1 = sheet1.CreateRow(0);
for (int j = 0; j < data.Columns.Count; j++)
{
ICell cell = row1.CreateCell(j);
String columnName = data.Columns[j].ToString();
cell.SetCellValue(columnName);
}
//loops through data
for (int i = 0; i < data.Rows.Count; i++)
{
IRow row = sheet1.CreateRow(i + 1);
if (Emp == Convert.ToInt32(data.Rows[i][0]))
{
num++;
ICell cell = row.CreateCell(j);
for (int j = 0; j < data.Columns.Count; j++)
{
sheet1.AutoSizeColumn(j); //control cell width
String columnName = data.Columns[j].ToString();
cell.SetCellValue(data.Rows[i][columnName].ToString());
}
}
else ///here has problems
{
var row = sheet1.GetRow(i);
//sheet1.RemoveRow(row);
sheet1.ShiftRows(i + 1, sheet1.LastRowNum + 1, -1);
}
}
if (num != 0)
{
//send email
}
}
}
I'm not sure why you need to resend the same file again with different contents instead of simply sending a different file, but could you perhaps try moving the creation of your sheet inside the for loop, and try removing the entire sheet instead? E.g. something like this:
private void Email()
{
//get the data from database
DataTable data = GetData();
int maxLavel = Convert.ToInt32(data.Compute("max([AssignedID])", string.Empty));
IWorkbook workbook;
workbook = new HSSFWorkbook();
for (int Emp = 0; Emp < maxLavel; Emp++)
{
ISheet sheet1 = workbook.CreateSheet("Sheet 1");
int num = 0;
//make a header row
IRow row1 = sheet1.CreateRow(0);
for (int j = 0; j < data.Columns.Count; j++)
{
ICell cell = row1.CreateCell(j);
String columnName = data.Columns[j].ToString();
cell.SetCellValue(columnName);
}
//loops through data
for (int i = 0; i < data.Rows.Count; i++)
{
IRow row = sheet1.CreateRow(i + 1);
if (Emp == Convert.ToInt32(data.Rows[i][0]))
{
num++;
for (int j = 0; j < data.Columns.Count; j++)
{
ICell cell = row.CreateCell(j);
sheet1.AutoSizeColumn(j); //control cell width
String columnName = data.Columns[j].ToString();
cell.SetCellValue(data.Rows[i][columnName].ToString());
}
}
}
if (num != 0)
{
//send email
}
workbook.remove(sheet1);
}
}
I figure it out..I don't need to remove the row.
IRow row = sheet1.CreateRow(i);
This should be changed.
for (int i = 0; i < data.Rows.Count; i++)
{
if (Emp == Convert.ToInt32(data.Rows[i][0]))
{
IRow row = sheet1.CreateRow(row_num);
num++; row_num++;
for (int j = 0; j < data.Columns.Count; j++)
{
ICell cell = row.CreateCell(j);
sheet1.AutoSizeColumn(j); //control cell width
String columnName = data.Columns[j].ToString();
cell.SetCellValue(data.Rows[i][columnName].ToString());
}
}
}
I am trying to count header columns only having data in excel sheet using openxml(c#).
For example if the data is present in A1,D1,F1, then the count should be 3 and not 6 (i.e A to F).
Please suggest how it can be done.
To know if a cell contains a value check if CellValue is not null. The following should work for you:
Row row1 = worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>().FirstOrDefault();
int counter = 0;
foreach (Cell cell in row1.Elements<Cell>())
{
if (cell.CellValue != null)
{
Console.WriteLine(cell.CellReference);
counter++;
}
}
I did something like this and it working fine for me.
foreach (Cell cell in row.Descendants<Cell>())
{
if (cell.CellValue != null)
{
var NumberOfCol = datatable.Columns.Count;
DataRow tempRow = datatable.NewRow();
for (int k = 0; k < NumberOfCol; k++)
{
if (tempRow[k] != null)
{
tempRow[k] = row.Count() > k ? GetValue(spreadsheet, row.Descendants<Cell>().ElementAt(k)) : "";
}
else
{
tempRow[k] = "";
}
}
}
}
I have a horrible method that extracts data from a DataTable and converts it to a desirable formatted DataTable. I'm sure there is a much nicer way to do this in LinQ but I'm not really experienced with it. I would appreciate if somebody could show me a nicer solution.
Heres the code
private static void ExtractImportLayoutFromExcelDt(DataTable importDt, DataTable dtExtracted, int languages)
{
// The number of Locale colums included in the excel file.
for (int x = 0; x < languages; x++)
{
// The total number of friendlynames-keys / language included in the excel.
for (int j = 0; j < dtExtracted.Rows.Count; j++)
{
var row = dtExtracted.Rows[j];
DataRow tempRow = importDt.NewRow();
// Filling in the 3 columns. (FriendlyName - LocaleID - Text)
for (int i = 0; i <= 2; i++)
{
if (i == 0)
{
tempRow[i] = row[i]; // Friendly names: This is always going to be column 1 [0].
}
else if (i == 1)
{
tempRow[i] = Regex.Match(dtExtracted.Columns[x + 1].ToString(), #"\d+").Value; // LocaleIDs: Getting rid of non numeric characters from this column.
}
else
{
tempRow[i] = row[x + 1];
}
}
importDt.Rows.Add(tempRow);
}
}
}
i would rewrite inner for loops
for (int x = 0; x < languages; x++)
foreach (DataRow row in dtExtracted.Rows)
importDt.Rows.Add
(
row[0],
Regex.Match(dtExtracted.Columns[x + 1].ToString(), #"\d+").Value; // LocaleIDs: Getting rid of non numeric characters from this column.
row[x + 1]
);
DataTable.Rows collection has overload of Add method, which accept an array of objects: Add
I am not quite sure if LINQ could be of any help here, but apart from rewriting the entire mapping logic I would at least split this method into two:
private static void ExtractImportLayoutFromExcelDt(DataTable importDt, DataTable dtExtracted, int languages)
{
// The number of Locale colums included in the excel file.
for (int x = 0; x < languages; x++)
{
// The total number of friendlynames-keys / language included in the excel.
for (int j = 0; j < dtExtracted.Rows.Count; j++)
{
AddRow(importDt, dtExtracted, dtExtracted.Rows[j], x+1);
}
}
}
private static void AddRow(DataTable table, DataTable dtExtracted, DataRow originalRow, int language)
{
var row = table.NewRow();
row[0] = originalRow[0];
row[1] = Regex.Match(dtExtracted.Columns[language].ToString(), #"\d+").Value;
row[2] = originalRow[language];
table.Rows.Add(row);
}
You can write something like this but in this case is more like abuse of Linq but if you do it for educational purposes ..The main power of LINQ is when you want to enumerate or filter for example collections not in cases like this.
public static void ExtractImportLayoutFromExcelDt(DataTable importDt, DataTable dtExtracted, int languages)
{
Enumerable.Range(0, languages)
.ToList().ForEach(x =>
{
Enumerable.Range(0, dtExtracted.Rows.Count)
.ToList().ForEach(j =>
{
var row = dtExtracted.Rows[j];
DataRow tempRow = importDt.NewRow();
AddRow(importDt, dtExtracted, x, row, tempRow);
});
});
}
private static void AddRow(DataTable importDt, DataTable dtExtracted, int x, DataRow row, DataRow tempRow)
{
for (int i = 0; i <= 2; i++)
{
if (i == 0)
{
tempRow[i] = row[i]; // Friendly names: This is always going to be column 1 [0].
}
else if (i == 1)
{
tempRow[i] = Regex.Match(dtExtracted.Columns[x + 1].ToString(), #"\d+").Value; // LocaleIDs: Getting rid of non numeric characters from this column.
}
else
{
tempRow[i] = row[x + 1];
}
}
importDt.Rows.Add(tempRow);
}
I have datatable and I am displaying those values in the datagridview with the helping of code :
dataGridView1.ColumnCount = TableWithOnlyFixedColumns.Columns.Count;
dataGridView1.RowCount = TableWithOnlyFixedColumns.Rows.Count;
for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
dataGridView1[j, i].Value = TableWithOnlyFixedColumns.Rows[i][j].ToString();
}
}
TableExtractedFromFile.Clear();
TableWithOnlyFixedColumns.Clear();
Now I want to save the records in the datatable in csv file.How can I do that ?
You could do this:
// we'll use these to check for rows with nulls
var columns = yourTable.Columns
.Cast<DataColumn>();
// say the column you want to sort by is called "Date"
var rows = yourTable.Select("", "Date ASC"); // or "Date DESC"
using (var writer = new StreamWriter(yourPath)) {
for (int i = 0; i < rows.Length; i++) {
DataRow row = rows[i];
// check for any null cells
if (columns.Any(column => row.IsNull(column)))
continue;
string[] textCells = row.ItemArray
.Select(cell => cell.ToString()) // may need to pick a text qualifier here
.ToArray();
// check for non-null but EMPTY cells
if (textCells.Any(text => string.IsNullOrEmpty(text)))
continue;
writer.WriteLine(string.Join(",", textCells));
}
}