Home>

【Consultation content】
Only the date and time (including time) displayed in the DataGridView
I would like to be able to search for partial or prefix matches, so please give me some advice.

[Details]
I am making a tool for inputting employee numbers and working hours and creating daily reports in C #.

I am in charge of a logger and have the log contents output to a text memo
I've even made it visible in a Windows Forms DataGridView.
The reason for not outputting directly to DataGridView is to reduce memory consumption as much as possible.

I also want to use it without connecting to the database for the same reason as above.
(Because it is actually output to the data grid.)

I'm using NLog and in the layout in NLog.config (XML)
${longdate} (format is yyyy-MM-dd HH: mm: ss: mmm)
Since we are using, it will also appear in the data grid as well.

When creating a search function, the log level is a short word, so it is an exact match
It's nice, but you can only search for dates with an exact match in the form yyyy-MM-dd HH: mm: ss: mmm.
I'm having a hard time adding a search function that matches only the date part (front).
Can anyone please give me some advice?

Error message
Corresponding source code
Public partial class Form1: Form
    {
        public Form1 ()
        {
            InitializeComponent ();
            toolTip1 = new ToolTip ();
        }
        private void Form1_Load (object sender, EventArgs e)
        {
            showLogs ();
        }
        private void button_Search_Click (object sender, EventArgs e)
        {
            searchLogs ();
        }
        private void button_Close_Click (object sender, EventArgs e)
        {
            try
            {
                throw new Exception ();
            }
            catch{
                LogUtil.Info ("test log output");
            }
            Close ();
        }
        DataTable table = new DataTable ();
        public void showLogs ()
        {
            table.Columns.Add ("date and time", typeof (string));
            table.Columns.Add ("log level", typeof (string));
            table.Columns.Add ("message", typeof (string));
            table.Columns.Add ("information", typeof (string));
            dataGridView1.DataSource = table;
            string [] lines = File.ReadAllLines (@ "C: ~~~ \ testlog \ testlog.log");
            string [] values;
            for (int i = 0;i<lines.Length;i ++)
            {
                values ​​= lines [i] .ToString (). Split ('/');
                string [] row = new string [values.Length];
                for (int j = 0;j<values.Length;j ++)
                {
                    row [j] = values ​​[j] .Trim ();
                }
                table.Rows.Add (row);
            }
        }
        public void searchLogs ()
        {
            DataTable sub = new DataTable ("sub");
            DataRow [] dRows1 = table.AsEnumerable ()
               .Where (row1 =>row1.Field<string>("date and time") == textBox1.Text) .ToArray ();
            DataRow [] dRows2 = table.AsEnumerable ()
               .Where (row2 =>row2.Field<string>("log level") == comboBox1.Text) .ToArray ();
            // Add column name
            sub.Columns.Add ("date and time");
            sub.Columns.Add ("log level");
            sub.Columns.Add ("message");
            sub.Columns.Add ("Information");
             foreach (var row1 in dRows1)
            {
                sub.Rows.Add (row1 [0],

 row1 [1],row1 [2],

 row1 [3]);
            }
            foreach (var row2 in dRows2)
            {
                sub.Rows.Add (row2 [0],

 row2 [1],

 row2 [2],

 row2 [3]);
            }
            dataGridView1.DataSource = sub;
// I tried the following, but it didn't work.
       System.Text.RegularExpressions.MatchCollection dRow1 =
                System.Text.RegularExpressions.Regex.Matches (
                textBox1.Text, @ "\ d \ d \ d \ d- \ d \ d- \ d \ d");
            foreach (System.Text.RegularExpressions.Match m in dRow1)
            {
                sub.Rows.Add (row1 [0],

 row1 [1],

 row1 [2],

 row1 [3]);
            }
        }
    }
What I tried

-Since ${longdate} in NLog.config displays the date and time with a hyphen
DateTimePicker in slash notation didn't seem to be possible.

-Match and Select methods were useless because DateSet is not used.

・ I think the specifications of the Contains method and IndexOf method are optimal.
I'm not writing the contents of the data grid directly in code (reading the text)
I didn't know how to write it.

Supplementary information (FW/tool version, etc.)

Environment: Visual Studio 2019

  • Answer # 1

    As I wrote in the comment section of the question, I will write the sample code for reference because the words alone will not come to my mind.

    First of all, I repeat what I wrote in the comment section ...

    I wrote a little now, but I got an error if there is no column and row definition for DateTime type. How should I define it?

    In the definition of the "Date and Time" column of the DataTable of the showLogs method,

    table.Columns.Add ("date and time", typeof (string));
    ↓ ↓ ↓
    table.Columns.Add ("date and time", typeof (DateTime));

    For that column only, parse the value of values ​​[j] .Trim () to DateTime type at row [j] = values ​​[j] .Trim ();and then assign it. How is it?

    That way, when searching for a specific date in Linq to Objects from the DataTable, you can use the various properties of the DataTime structure, so you can add a search function with a date-only part (prefix) match. I thought it would be easier to search for things like "difficulty".

    The sample code is below. On the design screen, drag and drop Panel, DataGridView, BindingSource to Form, and then drag and drop DateTimePicker, Button into Panel.

    using System;
    using System.Data;
    using System.Linq;
    using System.Windows.Forms;
    namespace WinFormsApp1
    {
        public partial class Form10: Form
        {
            private DataTable table;
            public Form10 ()
            {
                InitializeComponent ();
                this.dataGridView1.DataSource = this.bindingSource1;
            }
            private void Form10_Load (object sender, EventArgs e)
            {
                ShowLogs ();
                this.bindingSource1.DataSource = table;
            }
            protected void ShowLogs ()
            {
                this.table = new DataTable ();
                table.Columns.Add ("date and time", typeof (DateTime));
                table.Columns.Add ("log level", typeof (string));
                table.Columns.Add ("message", typeof (string));
                table.Columns.Add ("information", typeof (string));
                var today = DateTime.Now;
                for (int i = 0;i<50;i ++)
                {
                    DataRow row = table.NewRow ();
                    row ["date and time"] = today.AddDays (i);
                    row ["log level"] = "log level" + i;
                    row ["Message"] = "Message" + i;
                    row ["Information"] = "Information" + i;
                    table.Rows.Add (row);
                }
            }
            private void button1_Click (object sender, EventArgs e)
            {
                var result = this.table.AsEnumerable ().
                    Where (row =>row.Field<DateTime>("date and time"). Date == this.dateTimePicker1.Value.Date).
                    ToArray ();
            }
        }

    The execution result will be as shown in the image below. I just opened the DataTimePicker and selected 11/19.

    The following image shows the debug screen when the Search button is clicked with a breakpoint set on button1_Click in the sample code above. As expected, the data for 11/19 is selected.

  • Answer # 2

    If you know the format of the date and time string, you should cut out the date and time string from the log, convert it to DateTime with DateTime.TryParse (Exact), and perform a range search for DateTime.

Related articles