2012-03-28 5 views
1

datetimepickerを使用して日付に基づいてdatagridviewをフィルタリングできるアプリケーションがあります。私のデータベースの「日付」列はdatetimeデータ型です。したがって、日付と時刻は格納されますが、日付のみのデータがいくつかあります。私の問題は、私のdatetimepickerフィルタは日付= 12:00:00のこれらのデータのみをフィルタリングできることです。 datatimepickerを使用して日付を選択すると、それ以外の時間を含むデータはフィルタリングできません。私は何が問題なのか分からない。日付をフィルタリングできますが、日時をフィルタできませんか?

第一:テキストを連結し、これまで構成しないクエリ、私はいくつかのコメントをしなければならない

public trackInput() 
    { 
     InitializeComponent(); 
     dataGridView1.Visible = false; 
     webBrowser1.Location = new Point(12, 141); 
    } 

    /*private void trackInput_Load(object sender, EventArgs e) 
    { 
     // TODO: This line of code loads data into the 'trackingBMSDATADataSet.BRDATA' table. You can move, or remove it, as needed. 
     this.bRDATATableAdapter.Fill(this.trackingBMSDATADataSet.BRDATA); 

    }*/ 
    private void trackBtn_Click(object sender, EventArgs e) 
    { 

     dataGridView1.Visible = true; 
     if (dataGridView1.Visible == true) 
     { 
      webBrowser1.Location = new Point(12, 397); 
     } 
     //DataTable dt = null; 
     string connoInput = textBox1.Text; 
     string conString = Properties.Settings.Default.BMSDATAConnectionString; 
     using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\TrackCon\TrackCon\BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$")) 
     { 

       string Ids = "conno= '" + System.Text.RegularExpressions.Regex.Replace(textBox1.Text.Trim(), @"\s*\n\s*", "' OR conno= '") + "'"; 
       SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " +Ids, con); 
       SqlCeDataAdapter adap = new SqlCeDataAdapter(com); 
       DataSet set = new DataSet(); 
       adap.Fill(set); 
       if (set.Tables.Count > 0) 
       { 
        bRDATABindingSource1.DataSource = set.Tables[0]; 
       } 
       bRDATABindingSource1.Filter = null; 
       dataGridView1.DataSource = bRDATABindingSource1; 
       con.Close(); 
     } 
    } 

    private void trackMPSbtn_Click(object sender, EventArgs e) 
    { 
     dataGridView1.Visible = true; 
     if (dataGridView1.Visible == true) 
     { 
      webBrowser1.Location = new Point(12, 397); 
     } 
     //DataTable dt = null; 
     //string connoInput = textBox1.Text; 
     string conString = Properties.Settings.Default.BMSDATAConnectionString; 
     using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\TrackCon\TrackCon\BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$")) 
     { 
      dataGridView1.DataSource = bRDATABindingSource1; 
      string Ids = "cmpsno= '" + System.Text.RegularExpressions.Regex.Replace(textBox2.Text.Trim(), @"\s*\n\s*", "' OR cmpsno= '") + "'"; 
      con.Open(); 
      SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " + Ids, con); 
      SqlCeDataAdapter adap = new SqlCeDataAdapter(com); 
      DataSet set = new DataSet(); 
      adap.Fill(set); 
      if (set.Tables.Count > 0) 
      { 
       bRDATABindingSource1.DataSource = set.Tables[0]; 
      } 
      bRDATABindingSource1.Filter = null; 
      dataGridView1.DataSource = bRDATABindingSource1; 
      con.Close(); 
     } 
    } 

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e) 
    { 
     bRDATABindingSource1.Filter = string.Format("dsysdate = #{0:d/M/yyyy HH:mm tt}#", dateTimePicker1.Value.ToLongDateString()); 
    } 

答えて

1

DateTimePickerには、選択した日付を含むプロパティがあります。この日付を使用して、次のようなクエリを作成します。

where somedate >= datetimepicker.Value.Date 
    and somedate < datetimepicker.Value.Date.AddDays(1) 

ここで、DateはDateTimeの日付部分のみを返します。

" where conno >= @startDate and conno < @endDate" 

とSqlCeCommandの一部が

com.Parameters.Add (new SqlCeParameter("@startDate", SqlDbType.DateTime, 
        textbox1.Value.Date)); 
com.Parameters.Add (new SqlCeParameter("@endDate", SqlDbType.DateTime, 
        textbox1.Value.Date.AddDays(1))); 

をSqlCeCommandする2つのパラメータを追加し、cmpsnoと同様の運動を行う場所where句製造するためには、交換してください。

更新日:私は最後の方法を完全に逃しました。説明で

private void dateTimePicker1_ValueChanged(object sender, EventArgs e) 
    { 
     bRDATABindingSource1.Filter = string.Format("dsysdate >= '{0:yyyy-MM-dd}' AND dsysdate < '{1:yyyy-MM-dd}'", dateTimePicker1.Value, dateTimePicker1.Value.AddDays(1)); 
    } 

の試み:

dsysdateとしてあなたは間隔深夜に始まり、翌日の深夜にストレッチをフィルタリングするために必要な時間成分を有する - これはValue.AddDays(1)です。残念ながら、BindingSourceのフィルタリングについてはあまりよく分かりません。なぜなら、主にデータベースレベル、つまり最初のコードでフィルタリングするためです。メモリ内をフィルタリングするのではなく、dateTimePicker1_ValueChangedを書き換えてデータベースからデータを取得したい場合があります。インデックスのために大きなテーブルを扱うときには恩恵を受けるでしょう。

あなたは、あなたのコードを別の方法で構造化することを検討するかもしれません。このようなタスクは、通常、フィルタリングコントロールをチェックし、クエリをビルドして実行し、重複したコードを排除し、一度にいくつかの条件でフィルタリングできるメソッドによって実行されます。フィルタリングコントロールの内容が変更されたときに呼び出されるメソッド。

+0

申し訳ありませんニコラ。同じまま、私はかなり理解していない。あなたはもう少しを説明することができます。shahrul1509 @ –

+0

更新を参照してください。提案@Nikolaため –

+0

ありがとうございました。実はテキストボックスは実際にはテキストボックスです。私のアプリケーションの総機能は実際には2つのフィルタを持っています。 1つはIDでフィルタリングします。ユーザーがIDを入力すると、システムはID情報を表示します。次に、ユーザーはdatetimepickerを使用して日付を選択することで、その情報をさらにフィルタリングできます。私の問題は、日付フィルタにあります。テキストボックスフィルタはうまく動作します:) –

0

:ここに私のコードです。これは、入力をクリーンアップしようとしても、SQLインジェクションの影響を受けます。代わりに、ストアドプロシージャまたはパラメータ化されたクエリを使用します.SQLインジェクションに完全に耐性があります。

第2:パラメータを使用するのは、元の形式で値をテキストに変換せずにそのまま渡すことができるためです。これにより、問題の一部が削除されます。ストアドプロシージャまたはパラメータ化されたクエリを使用できます。

第2 & 1/2:パフォーマンスと関係があるパラメータを使用する他の理由があります。

第3回:おそらくdatetimeによるフィルタリングは機能しますが、保証することはできません。あなたは秒と分数を含む正確な日時でフィルタリングできるようにしますか?それは良い考えではないと私は思う。それを再設計するか、何をしたいかを説明してください。それはあまり意味がないように見えます。日付を数秒または数分に「丸め」て、DBに格納することをお勧めします。 datetimeは正確ではないと考えるべきです。浮動小数点のように動作するので、問題なくこの値を直接比較できます。つまり、私はあなたのデザインを改善するのを助けるためにあなたのコメントを待っています。

を追加しました: あなたは時間の一部は重要ではありません言うように(パラメータを持つ日時列を比較しながら)、あなたは挿入時に、あるいは比較にそれを削除することができ、この「トリック」を使用して:

SELECT (CAST(FLOOR(CAST(YourDateTimeColumn as FLOAT)) AS DateTime)) 

日付は、基準日からの日数として内部的に格納されます。小数部は1日の割合を表します(hh:mm:ss ...)。したがって、小数点を取り除くと、日付部分のみが保持され、指定した日付と安全に比較できます。

時間の部分が不要な場合:SQL Server 2008以降を使用している場合は、列にDATE型を使用できます(時間を保存する必要がない場合)。または、前のバージョンのSQL Serverにデータを挿入するときに同じトリックを使用できます。

+0

ヒントありがとうございます。私はそれを念頭に置き、改善するつもりです。私はまだC#環境で新しく、まだ自分自身を改善しようとしています。あなたの3番目のコメントのために、もちろん、ユーザーは時間の正確な詳細を挿入する必要はありません。ユーザーは日付を選択するだけで、データグリッドビューは選択した日付のベースをフィルタリングします。しかし、私が言ったように、日付が選択された後、時刻= 12:00:00を含むデータだけがフィルタによって検出される。それ以外の時間を含むデータは、フィルタリングされていると検出することはできません。 –

+0

datetime部分を取り除く方法を見てください。他にもいくつかの方法がありますが、これはもっと速いと思います。 – JotaBe

+0

申し訳ありませんが、理論的にはどのように動作するのか理解していますが、コードのどの部分に配置する必要があるのか​​よく分かりません。私はここでそれを入れてみてください: 'ます。private void dateTimePicker1_ValueChanged(オブジェクト送信者、EventArgsの電子) {SqlCeCommandセンチ= 新しいSqlCeCommandを( "(SELECT CAST(FLOOR(CAST FLOATとして(dsysdate)のDateTime AS ))BRDATA FROM" ); bRDATABindingSource1.Filter = String.Formatの( "dsysdate =#{0:DD/MM/YYYY}#"、dateTimePicker1.Value.ToLongDateString());} ' 私は実行すると、問題はまだ –

関連する問題