C#で複数フィールドの条件付き抽出について

このQ&Aのポイント
  • C#を使用して、複数のフィールドに対して条件を付けて検索する方法について質問です。
  • Accessデータベースで、複数のテーブルに対して同じ条件を満たすレコードを抽出する方法について教えてください。
  • データベースに関する知識が乏しいため、本や他の情報源では解決策が見つからなかったので、助けを求めています。
回答を見る
  • ベストアンサー

C#での複数フィールドの条件付き抽出について

Visual C# 2010 Expressと.NET Framework 4.5での質問です。 Accessデータベースの複数のフィールドに対して条件をつけて検索したいと思っています。 dView = new DataView(dSet.Tables["t_" + (テーブル名)] ,"(フィールド1に対する条件式)" , "", DataViewRowState.CurrentRows); dView = new DataView(dSet.Tables["t_" + (テーブル名)] , "(フィールド2に対する条件式)", "", DataViewRowState.CurrentRows); this.dataGridView2.DataSource = dView; 参照元のテーブル名が同じであるためか、これを実行すると後半のフィールド2に対する 条件式を満たすレコードがすべてdataGridViewに表示される結果になります。 両方の条件を満たすレコードだけを表示するにはどうしたらいいでしょうか。 C#などの本でも、データベースに関してはそれほど詳しくは書いていないので困っています・・・。 どうか、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Picosoft
  • ベストアンサー率70% (274/391)
回答No.4

> 「式ベースのフィルターは、文字列ベースのフィルターよりもはるかに強力で複雑なフィルター機能を提供します。 > 文字列ベースのフィルターと式ベースのフィルターは、相互に排他的です。 > DataView をクエリから作成した後に文字列ベースの RowFilter を設定した場合、 > クエリから推論される式ベースのフィルターはクリアされます。」 ここで言う「クエリ」とは#3の方が使っておられる、LINQを使った抽出方法のことを指します。 RowFilterを使った抽出(#1, #2の方法)とクエリを使った抽出(#3の方法)は両立できませんよー、ということを述べています。 > A AND B > B AND A > (Aは文字列型フィールド、Bはdouble型フィールド) > 両方とも、Aの条件に合うレコードが全部書かれてしまう状況です。 AとBの両方の条件に合うレコードが出てくるはずです。 Bの条件に合わないレコードはでていますか? 望んだ結果が得られないなら、一度AccessでSQLを書いて抽出条件を再度確認した方がいいかもしれません。 > r["double型フィールド"] >= double型変数 r["フィールド名"]はフィールドの型によらずobject型になりますので、 double型にキャストしてください。 > r["文字列型フィールド"] = '文字列型変数' r["文字列型フィールド"] == 文字列型変数 としてください。

mattari96
質問者

お礼

重ね重ねありがとうござます。 私事で恐縮ですが、体調不良のため検証が遅れます。 申し訳ありません。

mattari96
質問者

補足

回答有難うございました。 > A AND B > B AND A > (Aは文字列型フィールド、Bはdouble型フィールド) > 両方とも、Aの条件に合うレコードが全部書かれてしまう状況です。 AとBの両方の条件に合うレコードが出てくるはずです。 Bの条件に合わないレコードはでていますか? 改めてソース全体を見なおしたところ、教えていただいた方法(RowFilter)で無事に解決出来ました。 潜在していたバグも一緒に潰すことができて、二重に感謝しています。 本当にありがとうございました。

その他の回答 (3)

回答No.3

VC# 2010は.NET Framework 4.5を対象とするプログラムを作れませんが……。 # .NET Framework 2.0/3.0/3.5/3.5 Client Profile/4/4 Client Profile対象。 それはともかく,DataSetに対してもLINQが使えるので, dSet.Tables["t_" + (テーブル名)].AsEnumerable().Where(r => (r["フィールド1"]に対する条件式) && (r["フィールド2"]に対する条件式)).AsDataView() とか, (from r in dSet.Tables["t_" + (テーブル名)].AsEnumerable() where (r["フィールド1"]に対する条件式) && (r["フィールド2"]に対する条件式)).AsDataView() でDataViewが取得できます。 AsDataViewが使える条件については,以下を参照して下さい。 http://msdn.microsoft.com/ja-jp/library/bb669080(v=vs.100).aspx

mattari96
質問者

補足

回答ありがとうございます。動作システムについての記述が曖昧ですみませんでした。 >(r["フィールド1"]に対する条件式) の記述の仕方ですが、例えば、 r["double型フィールド"] >= double型変数 と書くと、>=はobjectとdouble型のオペランドの間では使えないと言われ、 r["文字列型フィールド"] = '文字列型変数' と書くと、'文字列型変数'のところで文字リテラルに文字が多すぎると言われます。 出て当たり前のエラーなのだとは思いますが、対処方法がわからず困っています。 どうか教えていただけないでしょうか。

  • Picosoft
  • ベストアンサー率70% (274/391)
回答No.2

> ANDを""で囲わずにベタ打ちすると構文エラーになってしまいます。 DataViewコンストラクタのRowFilter引数はstring型ですので、 ANDは""で囲う必要があります。 (+演算子でだらだら繋いでいくよりもstring.Format等を使った方が見やすいかと) string rowFilter = string.Format("Field1 >= {0:0.0} AND Field2 = '{1}'", co, 文字列変数); dView = new DataView(dSet.Tables["テーブル名"], rowFilter, "", DataViewRowState.CurrentRows); > 実行結果はAND以下の部分が反映されている感じです。 条件式は正しいですか?

mattari96
質問者

お礼

たびたびの回答ありがとうございます。 >(+演算子でだらだら繋いでいくよりもstring.Format等を使った方が見やすいかと) なるほど、コードがすっきりして見やすいですね。 アドバイスありがとうございます。 しかし、作っていただいたコードでも、AND以下しか反映されない・・・。 いろいろ試してみます、お忙しいところありがとうございました! >条件式は正しいですか? 条件式を個々に検索するとちゃんと動くので、間違っていないと思います。

mattari96
質問者

補足

たびたび失礼します。 http://msdn.microsoft.com/ja-jp/library/bb669073(v=vs.100).aspx 上記MSDN内に次のような記述がありました。 「式ベースのフィルターは、文字列ベースのフィルターよりもはるかに強力で複雑なフィルター機能を提供します。 文字列ベースのフィルターと式ベースのフィルターは、相互に排他的です。 DataView をクエリから作成した後に文字列ベースの RowFilter を設定した場合、 クエリから推論される式ベースのフィルターはクリアされます。 」 私の場合、double型フィールドの数字と文字列型フィールドの内容を使ってレコードを抽出しようと していますが、これは不可能ということでしょうか。 実際、文字列型フィールドの方しか機能していないような動きです。 A AND B B AND A (Aは文字列型フィールド、Bはdouble型フィールド) 両方とも、Aの条件に合うレコードが全部書かれてしまう状況です。

  • Picosoft
  • ベストアンサー率70% (274/391)
回答No.1

SQLのWHERE句と似たような感じで書けばOKです。 http://msdn.microsoft.com/ja-jp/library/system.data.datacolumn.expression%28v=vs.80%29.aspx たとえば、Nameフィールドが"hoge"でAgeフィールドが20である行を抽出したい場合、  dView = new DataView(dSet.Tables["TableName"], "Name='hoge' AND Age=20", "", DataViewRowState.CurrentRows); と書くことができます。 本を読んだりサイトを探したりするのも有用ですが、 一番の情報源はMSDNライブラリです。 クラス名やメソッド名にカーソルを合わせてF1キーを押してみてください。

mattari96
質問者

お礼

お礼が遅くなりすみません。 補足にも対応していただき感謝しています。 ありがとうございます。

mattari96
質問者

補足

回答有難うございました。さっそく以下の様なコードを書いてみました。 dView = new DataView(dSet.Tables["テーブル名"] , "(数値型フィールド)>=" + co.ToString("0.0") + " AND "            + "(文字列型フィールド)='" + 文字列変数 + "'" , "",                       DataViewRowState.CurrentRows); 実行結果はAND以下の部分が反映されている感じです。 ANDを""で囲わずにベタ打ちすると構文エラーになってしまいます。 Unicode文字列にしろと怒られます・・・。 MSDNやSQLのサイトなど探していますが、いまいちわかりません。。。 申し訳ありません。どこが間違っているのでしょうか。

関連するQ&A

  • C#でAccessの日時検索方法

    Visual C# 2010 Express, .NET Framework 4.5を使っています。 Accessデータベース内のある期間内(DateTime型フィールド)のレコードだけをDataGridViewに 表示させようとしています。 dView = new DataView(dSet.Tables["t_" + (テーブル名)] , "日付>" + startday.ToString("yyyy/MM/dd"), "", DataViewRowState.CurrentRows); dView = new DataView(dSet.Tables["t_" + (テーブル名)] , "日付<" + endday.ToString("yyyy/MM/dd"), "", DataViewRowState.CurrentRows); これを実行すると、論理演算子は使えないというようなエラーが出ます。 startday, enddayはDatetimePickerコントロールから値を取得しています。 これを解決するにはどうすればいいのでしょうか。 そもそも根本的に考え方を変えなければいけないのでしょうか。 説明がわかりづらいかもしれませんが、どなたかお教えください。 よろしくお願いします。

  • DataGridViewでのデータ抽出について

    C#からAccessデータベースを呼び出し、それをDataGridViewに表示しました。 その上で、条件に合うレコードのみを表示するコードを書こうとしました。 元のAccessのフィールドにはテキスト型のデータが入っています。         DataView dView; dView = new DataView(dSet.Tables["t_" + (テーブル名)] , "フィールド名=" + (文字列型変数), "", DataViewRowState.CurrentRows); dataGridView.RowHeadersVisible = false; this.dataGridView2.DataSource = dView; これをデバッグすると、2行目で、EvaluateExceptionはハンドルされませんでした。というエラーが出ます。 列[「(文字列型変数)]は見つかりません」という内容です。 これを回避して、フィールドに特定の文字列が入っているレコードを抽出して、DateGridViewに表示させる 方法はないでしょうか。 ちなみに数値型のレコードを抽出することはできているレベルです。 また、フィールドに日付が入っているような場合、ある期間内のレコードを抽出するやり方を ご存知のかたがおりましたら、お教え願います。 (直接のやり方でなくても、「この本が良い」というようなアドバイスでも大いに助かります)。 どうかよろしくお願いします。

  • DataSetの複数テーブルをひとつのDataGridViewでまとめて出したい

    こんにちは、いつも参考にさせていただいています。 VS2005のC#で制作しているのですが、 ひとつのデータセットの中に3つのテーブルがあります。 そのテーブル全てをデータグリッドビューでだしたいのですが、 ひとつのテーブルしか上手に出ません。 3つのテーブルをひとつのグリッドビューに出す方法を教えてください。 現状は以下のコードで一つのテーブルだけ表示しています。 dv = new DataView(dataset.Tables["data"], "", "", DataViewRowState.CurrentRows); dataGridView1.DataSource = dv;

  • OLE でACCESSデータを取得するとメモ型の内容255文字で切れてしまう

    お世話になります。 ■開発環境  VisualBasic2008 Express Edition  ACCESS2003(データ) ■質問内容  VBでaccessのmdbからデータを取得し、画面に表示しようと  しています。  ところが、メモ型の項目が255文字で切れてしまいます。  webでいろいろと調べましたが、jetエンジンの問題かなという  ところまではたどり着いたのですが、具体的にどうすれば改善  できるのかわかりません。  わかる方教えていただけないでしょうか。  よろしくお願いいたします。 ■ソース Dim SQL As String Dim Cn As OleDb.OleDbConnection = New OleDb.OleDbConnection( _ "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="c:\message.mdb;") Dim dAdp As OleDb.OleDbDataAdapter Dim dView As DataView Dim dSet As DataSet = New DataSet("Detail") SQL = "SELECT M_ID,M_Title,M_Detail FROM MESSAGE_TBL " dAdp = New OleDb.OleDbDataAdapter(SQL, Cn) dAdp.Fill(dSet, "Detail") dView = New DataView(dSet.Tables("Detail"), "", "", DataViewRowState.CurrentRows) DataGridView1.DataSource = dView M_ID : 数値型、M_Title : テキスト型、M_Detail : メモ型 DataGridView1に表示されるときには、M_Detailが255文字になっています。     また、 'MessageBox.Show(Len(dSet.Tables("Detail").Rows(1)(2)))     で見たときにすでに255文字に切れていました。

  • C#でアクセスに更新するときの文字の色&呼び出すときの文字の色

    はじめまして。今回質問させていただく内容は。 C#でSQL文によってACCESSに更新するとき、更新した文字を更新したとわかりやすくACCESSのテーブルに赤色で表示させたいのですが。 SQL文によってどのように文字の色を変化させて追加するのかわからずにいます。 そしてこのことが可能であるならば、ACCESSのテーブルをSQL文で呼び出しデータグリッドビューに表示させるときもACCESSのテーブルのレコードの文字の色もまるっきり同じに呼び出すことは可能でしょうか? 下記にSQLでアクセスに更新するプログラミングと呼び出すとき使ったプログラミングを記述しておきます。 もし可能なら方法などご回答いただけたら嬉しいです。 ACCESSのデータを更新するプログラム System.Data.OleDb.OleDbCommandBuilder cBuild; System.Data.OleDb.OleDbDataAdapter dAdp; DataSet dSet = new DataSet("t_作業実績"); DataTable dTbl; System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection( "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source =C:\\Documents and Settings\\05d9096\\デスクトップ\\MES.mdb;"); //データセットに取得する dAdp = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM 作業実績",cn); dAdp.Fill(dSet, "t_作業実績"); //コマンドビルダの作成 cBuild = new System.Data.OleDb.OleDbCommandBuilder(dAdp); //データセットからテーブルを取得して更新する dTbl = dSet.Tables["t_作業実績"]; dTbl.Rows[num-1]["移動個数"] = textBox2.Text; dAdp.Update(dSet, "t_作業実績"); MessageBox.Show("ok"); ACCESSからデータグリッドビューへ呼び出すプログラム System.Data.OleDb.OleDbDataAdapter dAdp; DataSet dSet = new DataSet("作業実績"); System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=C:\\Documents and Settings\\05d9096\\デスクトップ\\MES.mdb;"); //C:\\Documents and Settings\\05d9096\\デスクトップ\\MES.mdb //datasetに取得し、DATAGRIDVIEWに関連ずけする dAdp = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM 作業実績", cn); dAdp.Fill(dSet, "作業実績"); dataGridView2.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray; dataGridView2.DataSource = dSet.Tables["作業実績"];

  • アクセスで複数フィールドを結合して1フィールドを作る際

    こんにちは。 OSはWIN2KでAccess2000を使用しております。 「T_データ」テーブルには、 社員コード(数値型)、社員名(テキスト型)、 給料(数値型)、住所(テキスト型)フィールドがあります。 この4つのフィールドを以下の条件を満たしつつ 「T_結合」テーブルの「結合データ」フィールドという 一つのフィールド(テキスト型)に追加したいのです。 ------------------------------------------------ 1.社員コードは 5桁、社員名は半角30桁、 給料は10桁、住所は全角20桁。 2.社員コード、給料は右詰とし残りは0で、 社員名、住所は左詰とし、残りは空白("")で埋める。 ------------------------------------------------- 最終的に「T_結合」テーブルを1レコード85バイトの レコードとしてエクスポートするのが目標です。 アクセスはUnicodeで管理されているというので単純には いかなそうなので、どなたかご教授願います。

  • Access 複数の抽出条件

    Access2002 windows2000 (例)次のようなテーブルとします。 フィールド名:名前 年齢 性別 レコード1 :山本 30 男 レコード2 :鈴木 40 女 レコード3 :田中 45 男 レコード4 :森本 26 女 クエリを利用して抽出する時、年齢が40以上で男を条件とすれば (1)年齢フィールドの抽出条件:>=40 (2)性別フィールドの抽出条件:男 として、田中が抽出されます。 では年齢が40以上で男、そして女は全て抽出したい時は(1)(2)の条件はどの様にすればいいでしょう? 抽出結果が 田中、鈴木、森本となりたいのです。 複数のクエリを作れば出来ますが、1つのクエリでは無理なのでしょうか。

  • DataViewで複数条件のフィルタのやり方

    よろしくお願いします。 開発環境は、Vb2005とACCESS2003です。 表題のとおりなんですが、データテーブルに名簿が登録してあり、フィルタ処理をしたいと思っています。ふりがなから、あ行、か行、という抽出を行いたいのですが、あ行でしたら、あ、い、う、え、お、と五つの条件が必要かと思うのですが、どうもうまくいきません。 どのように式を書くのかお教えください。 現在は下記のようなコードにしています。(当然ですがアで始まる人しか抽出できていません) Dim dv As New DataView dv.Table = DataSet1.Tables("社員") dv.RowFilter = "フリガナ LIKE 'ア%'" "フリガナ LIKE 'ア%'"に、ANDをつけてみたり&をつけたりしたんですが、 複数の条件をどのようにフィルタにかけるのかわからないので、うまくいきません。 すみませんがどのように書けばよいのかお教えください。よろしくお願いします。

  • C#言語に変換してください

    以下のコードはvisualVBで組んだものの一部なのですが, これをC#言語用に変換してもらいたいのでよろしくお願いいたします. Dim Table As DataTable = DirectCast(DataGridView1.DataSource, DataTable) Dim Tables As DataTable = DirectCast(DataGridView2.DataSource, DataTable)

  • VB 2008 Express Editionでデータの抽出ができない

    VB 2008 Express Editionでデータの抽出ができません。 「Btn検索」ボタン押下時に「TextBox1.text」のデータで抽出を行いたいのですがデバッグして「TextBox1.text」にデータを入力して「Btn検索」ボタンを押下すると 「OledbExceptionはハンドルされませんでした。1つ以上の必要な値のパラメータが設定されていません」と表示されてしまいます。 ちなみにソースは下記になります。 -------------------------------------------------------------- Private Sub Btn検索_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn検索.Click Dim cn As New OleDb.OleDbConnection Dim dView As New DataView Dim strRec As String cn.ConnectionString= "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source = C;\管理台帳データベース.mdb" dadp = New OleDb.OleDbDataAdapter("SELECT * FROM PC管理台帳 WHERE 新PC名=TextBox1.Text", cn) dadp.Fill(dset, "PC管理台帳") 'データベースの表示 DataGridView1.DataSource = dset.Tables("PC管理台帳") End Sub -------------------------------------------------------------- ちなみに下記のようにTextBox1.Textを'1111'とかにするとうまく抽出できます。 dadp = New OleDb.OleDbDataAdapter("SELECT * FROM PC管理台帳 WHERE 新PC名='1111'", cn) となたかアドバイスお願いします。

専門家に質問してみよう