質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

Q&A

解決済

2回答

8337閲覧

DataTableからLINQで値を抽出するコードの改善

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

0グッド

0クリップ

投稿2016/09/23 08:55

var query = from data in getDt.AsEnumerable() where data["仕様2"].ToString() == "LDWS" && data["項目"].ToString() == "PNFV" && data["パーツ名称_No"].ToString() == "FLD1" && (data["詳細項目_No"].ToString() == "1" || data["詳細項目_No"].ToString() == "2" || data["詳細項目_No"].ToString() == "3" || data["詳細項目_No"].ToString() == "4") select data;

あるExcelシートから値を抽出することをLINQで挑戦しています。
シートの表はDataTable型のgetDtに全て格納しています。
"詳細項目_No"という列に1以上の数値が割り振られたセルがあります。
この数値を抽出条件に加える時、たとえば1からnまで指定したい場合、n行追加して
いかなければならないこのコードを改善する方法が知りたいです。

//自分で試してみた方法 var arr = new[]{"1","2","3","4"}; var query = from data in getDt.AsEnumerable() where data["仕様2"].ToString() == "LDWS" && data["項目"].ToString() == "PNFV" && data["パーツ名称_No"].ToString() == "FLD1" && data["詳細項目_No"] == arr select data;

配列やListを使ってみましたが、queryにはEmptyと表示され何も格納されていませんでした。
そもそも根本的に何か間違えている気がするのですが、答えじゃなくても何か例やヒントでも貰えていただければうれしいです。

###補足情報(言語/FW/ツール等のバージョンなど)
Windows7
Visual Studio 2008
.NET 3.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

c#

1Enumerable.Range(1, n + 1).Select(Convert.ToString).Contains(data["詳細項目_No"].ToString())

とかですかね。
動かなかったらすみません。

投稿2016/09/23 09:15

htsign

総合スコア870

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/23 09:36

ありがとうございます。 以下のように足してみたのですが、エラーで動きませんでした。 そもそも使い方が私の使い方が違う気がしますが ```ここに言語を入力 for (int n = 0; n <= 3; n++) { var query = from data in getDt.AsEnumerable() where data["仕様2"].ToString() == "LDWS" && data["項目"].ToString() == "PNFV" && data["パーツ名称_No"].ToString() == "FLD1" && Enumerable.Range(1, n + 1).Select(Convert.ToString).Contains(data["詳細項目_No"].ToString()) select data; foreach (var item in query) {     //itemに関する処理 } } ``` エラー 4 メソッド 'System.Linq.Enumerable.Select<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TResult>)' に対する型引数を使い方から推論することはできません。型引数を明示的に指定してください。
htsign

2016/09/23 09:38

失礼しました。 .Select(Convert.ToString) を .Select<int, string>(Convert.ToString) あるいは .Select(i => i.ToString()) などとすると改善されるかと思います。
退会済みユーザー

退会済みユーザー

2016/09/23 09:52 編集

ありがとうございます。 追記通りに以下の修正をすると無事やりたいことができました。 for (int n = 0; n <= 3; n++) { var query = from data in getDt.AsEnumerable() where data["仕様2"].ToString() == "LDWS" && data["項目"].ToString() == "PNFV" && data["パーツ名称_No"].ToString() == "FLD1" && Enumerable.Range(1, n + 1).Select(i => i.ToString()).Contains(data["詳細項目_No"].ToString()) select data; foreach (var dr in drs) { //itemの処理 } }
guest

0

この数値を抽出条件に加える時、たとえば1からnまで指定したい場合

思いつきレベルなのでハズレかもしれませんが、以下のようにしてできないですか?

(data["詳細項目_No"] >= 1 && data["詳細項目_No"] <= n)

【追伸】

コメントに書きましたが、検証に使ったサンプルをアップしておきます。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; namespace ConsoleAppLinq2 { class Program { // データソース用の DataTable を作成 protected DataTable CreateDataSource() { DataTable dt = new DataTable(); DataRow dr; dt.Columns.Add(new DataColumn("ID", typeof(Int32))); dt.Columns.Add(new DataColumn("Name", typeof(string))); dt.Columns.Add(new DataColumn("Type", typeof(string))); dt.Columns.Add(new DataColumn("Price", typeof(Int32))); dt.Columns.Add(new DataColumn("Qty", typeof(Int32))); dt.Columns.Add(new DataColumn("Amount", typeof(Int32))); dt.Columns.Add(new DataColumn("CategoryID", typeof(Int32))); dt.Columns.Add(new DataColumn("Note", typeof(string))); dt.Columns.Add(new DataColumn("Discontinued", typeof(bool))); dt.Columns.Add(new DataColumn("DateTime", typeof(DateTime))); for (int i = 0; i < 25; i++) { dr = dt.NewRow(); dr["ID"] = i; dr["Name"] = "Product Name_" + i.ToString(); dr["Type"] = "Product Type " + (100 - i).ToString(); dr["Price"] = 123000 * (i + 1); dr["Qty"] = (i + 1) * 20; dr["Amount"] = 123000 * (i + 1) * (i + 1); dr["CategoryID"] = 100 - i; dr["Note"] = "Note_" + i.ToString(); dr["Discontinued"] = (i % 2 == 0) ? true : false; dr["DateTime"] = DateTime.Now.AddDays(i); dt.Rows.Add(dr); } return dt; } static void Main(string[] args) { Program prg = new Program(); DataTable getDt = prg.CreateDataSource(); int n = 5; var query = from data in getDt.AsEnumerable() where ((int)data["ID"] >=1 && (int)data["ID"] <= n) select data; foreach (DataRow row in query) { Console.WriteLine("ID: {0}, Name: {1}, Type: {2}, Price: {3}", row["ID"], row["Name"], row["Type"], row["Price"]); } /* 結果は: ID: 1, Name: Product Name_1, Type: Product Type 99, Price: 246000 ID: 2, Name: Product Name_2, Type: Product Type 98, Price: 369000 ID: 3, Name: Product Name_3, Type: Product Type 97, Price: 492000 ID: 4, Name: Product Name_4, Type: Product Type 96, Price: 615000 ID: 5, Name: Product Name_5, Type: Product Type 95, Price: 738000 */ } } }

投稿2016/09/23 09:15

編集2016/09/23 10:32
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/23 09:42

ありがとうございます。 以下のようなエラーが出て動きませんでした。 var query = from data in getDt.AsEnumerable() where data["仕様2"].ToString() == "LDWS" && data["項目"].ToString() == "PNFV" && data["パーツ名称_No"].ToString() == "FLD1" && (data["詳細項目_No"] >= 1 && data["詳細項目_No"] <= 4) select data; エラー 4 演算子 '>=' を 'object' と 'int' 型のオペランドに適用することはできません。 エラー 5 演算子 '<=' を 'object' と 'int' 型のオペランドに適用することはできません。 一応、以下のことも試してみましたが動きませんでした。 (data["詳細項目_No"].Int32() >= 1 && data["詳細項目_No"].Int32() <= 4) エラー 4 'object' に 'Int32' の定義が含まれておらず、型 'object' の最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。
退会済みユーザー

退会済みユーザー

2016/09/23 09:51

キャストしないとダメかもしれません。後で確認してみます。
退会済みユーザー

退会済みユーザー

2016/09/23 09:57

ありがとうございます。 htsign様の回答で解決はしましたが、後日、SurferOnWww様の解決方法も後学のために教えて頂けたらと思います。
退会済みユーザー

退会済みユーザー

2016/09/23 10:25

確認しました。data は DataRow 型になって data["詳細項目_No"] は object を返すので、DataTbable の「詳細項目_No」列が int 型であれば int にキャストする必要がありました。回答欄に検証に使ったサンプルをアップしておきます。
退会済みユーザー

退会済みユーザー

2016/09/25 16:40

ありがとうございます。 大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問