Explosion lambda expression

The code below works for me, however I would like to add a condition before adding it to the table. What I need is if the "Scan time" is between two dates, then it should be added to the "table", if not, then it should be ignored.

This is for file selection.

private void btnSelectFile_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog() { Title = "Select the file to open.", Filter = "DAT (*.dat)|*.dat|TXT (*.txt)|*.txt|All Files (*.*)|*.*", InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) }; if (ofd.ShowDialog() == DialogResult.OK) { txtFilePath.Text = ofd.FileName; loadDataToGridview(); } } 

This is for reading a file and then adding it to a datagridview

 private void loadDataToGridview() { DataTable table = new DataTable(); table.Columns.Add("Emp ID"); table.Columns.Add("Scan Time"); table.Columns.Add("Undefined 1"); table.Columns.Add("Undefined 2"); table.Columns.Add("Undefined 3"); table.Columns.Add("Undefined 4"); var lines = File.ReadAllLines(txtFilePath.Text).ToList(); lines.ForEach(line => table.Rows.Add(line.Split((char)9))); return table; } 

I got the loadDataToGridview method, but I don't know how to blow

 lines.ForEach(line => table.Rows.Add(line.Split((char)9))); 

lambda expression include the condition I need. Suppose the names of datepickers are dateFrom and dateTo. Your help is greatly appreciated.

+5
source share
3 answers

Do not use the ReadAllLines method, because it will load the entire file into memory. In other words, why upload the entire file if there is only one line between the dates.

Use the ReadLines method instead. What for? See my answer here .

 var lines = File.ReadLines("").Select(x => Split(x)).Where(x => IsBetweenDates(x[1])); lines.ForEach(row => table.Rows.Add(row)); dataGridView1.DataSource = table; 

You should add your own error handling here to suit your needs. I have added a few for you:

 private bool IsBetweenDates(string value) { var dateValue = DateTime.ParseExact(value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); return dateValue >= fromDate.Value && dateValue <= toDate.Value; } private string[] Split(string line) { if (string.IsNullOrWhitespace(x)) { // There is nothing in this line. Is this allowed in your case? // If yes do whatever you need to do here. For example, log it or something. } var splits = line.Split((char)9); if (splits.Length != 6) { // This line does not have 6 fields so what do you want to do? } return splits; } 
+3
source

Use Where() as suggested by @CodingYoshi , but first split the line (so you don't need to do this twice) using the Select() statement:

 var lines = File.ReadAllLines(txtFilePath.Text).Select(line => line.Split(';')).Where(fields => fields[1] >= fromDate && fields[1] <= toDate).ToList(); lines.ForEach(row => table.Rows.Add(row)); 

You might also consider using something like CsvHelper instead of parsing the file manually.

0
source

Perhaps you can also use the Select Method , which in turn receives an array of all DataRow objects that match the filter criteria.

 DataTable table = new DataTable(); table.Columns.Add("Emp ID"); //Add All your columns var lines = File.ReadAllLines(txtFilePath.Text).ToList(); lines.ForEach(line => table.Rows.Add(line.Split((char)9))); //Till the data has been already there in your DataTable. //Create a new DataTable for Filtered Records. DataTable FilteredTable = new DataTable(); //The Statement works like a SQL Statement which is equal to //Select * from TableName Where DateColumn Between two dates. DataRow[] rows = table.Select("date >= #" + from_date + "# AND date <= #" + to_date + "#"); //Now add all rows to the new Table. foreach (DataRow dr in rows) { FilteredTable.ImportRow(dr); } dataGridView1.DataSource = FilteredTable; 

if from_date and to_date is a DateTime, not a string, you need to use ToString (date format) to get the correct sql statement

0
source

Source: https://habr.com/ru/post/1262193/


All Articles