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

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

新規登録して質問してみよう
ただいま回答率
85.42%
DataSet

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

C#

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

4回答

18036閲覧

DataTableに入っているデータを順番にすべて取り出しながら配列に入れたいです。

kariaka2020

総合スコア37

DataSet

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

C#

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/01/07 13:43

編集2020/01/09 14:27

実現したいこと

独学でC#の勉強をしています。
for文やforeachを使用してDataTableに入っている値を取得しようとしています。
DataTableに入っているデータを順番にすべて取り出しながら3次元配列に入れたいです。

発生している問題

現在、foreach文で列ごとに取得し、配列に代入するところまで(該当のソースコード)は分ったのですが、列名を指定せず、列をまたいでも処理を継続できるように改良したいと考えています。

理想としては
配列の中身が、{3.2,田中} , {2.4,山田} , {3.5,斎藤} , {5.6,田中} , {5.7,山田} , {4.9,斎藤} , {3.9,田中}…のようになることです。
(列aの一番上から一番下まで行ったら列b、列c…と繰り返す)

拙い文章で申し訳ありませんがお力を貸してくださると幸いです。
よろしくお願いいたします。

DataTableの中身

見づらくてすみません。例ですがこのようなものです。

id | 氏名 | 列名a | 列名b | 列名c | 列名d ・・・
1 | 田中 | 3.2 | 5.6 | 3.9 | 2.1
2 | 山田 | 2.4 | 5.7 | 3.4 | 2.3
3 | 斎藤 | 3.5 | 4.9 | 2.9 | 3.0


該当のコード (1列のみ)

C#

1 2foreach (DataRow dr1 in dt.Rows)   3{ 4    test[i, 0] = dr1["列名a"]; 5    test[i, 1] = dr1["氏名"]; 6    //Console.WriteLine("氏名," + test[i, 1]); 7    //Console.WriteLine("列名aの値," + dr1["列名a"]); 8    i++; 9} 10

試してみたこと

「該当のソースコード」のforeachを2重にすれば良いのかと考えましたが上手くできませんでした。

補足情報

visual studio2017を使用しています。

###解決後
初心者のため、かなり汚く効率の悪いコードになっているとは思いますが、自分用の記録、同じ疑問を持つ人用に残しておきます。

c#

1 foreach (DataColumn retu in dt.Columns) //列ごと この書き方だとid列、氏名列も対象になってる。 2 {    3 //列名が「id」「氏名」のところを回避する。 4 if (3 <= ct2 && ct2 <= 896) 5 { 6 foreach (DataRow dr1 in dt.Rows)  //行ごと 7 { 8 //retuName = retu.ColumnName; //String型で列名取得できる 9 test[j, i, 0] = dr1[retu.ColumnName]; 10 test[j, i, 1] = dr1["氏名"]; 11 12          //チェック用 13 //Console.WriteLine("{0},{1}",j,i); 14 //Console.WriteLine("氏名," + test[j, i, 1]);//氏名,山田 とか 15 //Console.WriteLine(retu.ColumnName + "," + dr1[retu.ColumnName]);//列名B,5.7 とか 16 //Console.WriteLine(); 17 i++; 18 } 19 j++; 20 i = 0; 21 22 } 23 ct2++; 24}

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/01/07 23:21

配列に入れる目的はなんですか? そうするのが実用的な事例は無さそうですし(自分が知らないだけという可能性は否定しきれませんが)、XY問題になっているような気がします。
kariaka2020

2020/01/08 01:56

回答ありがとうございます。 配列に入れる目的といたしましては、データを扱いやすくしたいというのが主な目的です。 処理の内容としては データベースからdatatableとしてとってくる。(1度のみ) →配列にデータを入れる。(1度のみ)※この質問の部分 という処理をした後に →別で用意してある配列の値と一つずつ比較する(実行中は常時ループ) という処理を行いたいからです。 このプログラムは仕事で作成しているものではなく、個人的に勉強として取り組んでいるものになるので、実用的かどうかはあまり重視していません。 (重視していないというより力不足によりこの方法しか思いつくことができませんでした。) 質問が分かりづらくて申し訳ありません。よろしくお願いいたします。
papinianus

2020/01/08 03:46

第一コメントの繰り返しになりますが id 1 の列 b が配列の何番目になるかがテーブル全体の行数に依存するということが、合目的的とは思えません。返信からすると山田さんが3.4を持つかを知りたいなどを想定しましたが、そういうことを質問したほうが勉強になりそうです。
退会済みユーザー

退会済みユーザー

2020/01/08 07:46

> 配列に入れる目的といたしましては、データを扱いやすくしたいというのが主な目的です。 本当に扱いやすくなるかどうかはよく吟味されることをお勧めします(普通、逆に扱いにくくなると思いますので)。やってみなければわからないということでとにかくやってみたい、個人の勉強なので時間と労力はいとわないということであれば、頑張ってくださいとエールを送るほかないですが・・・
退会済みユーザー

退会済みユーザー

2020/01/09 01:00

Teratail などの Q&A サイトを見ていると、初学者の方は配列を使うことを考える傾向にあるようですが、配列を使うのが適切というケースはほとんどないと記憶しています。今回のケースでは DB からデータを取ってくるということなので、なおさら配列を使うのは不適切ではないかと思います。DbContext, Linq to Entities を使って List<T> 型のオブジェクトを取得する方向に進むのがよさそうです。後で回答欄にその具体例を書いておきます。
guest

回答4

0

配列に取得するのはどうすればよいかという質問の直接の答えではありませんが・・・

質問に対する私の 2020/01/09 10:00 のコメントで、

Teratail などの Q&A サイトを見ていると、初学者の方は配列を使うことを考える傾向にあるようですが、配列を使うのが適切というケースはほとんどないと記憶しています。今回のケースでは DB からデータを取ってくるということなので、なおさら配列を使うのは不適切ではないかと思います。DbContext, Linq to Entities を使って List<T> 型のオブジェクトを取得する方向に進むのがよさそうです。後で回答欄にその具体例を書いておきます。

・・・と書きましたが、具体例を以下に書いておきます。余計なお世話だったら以下はスルーしてください。

List<T> というのが何かを簡単に説明すると MSDN ライブラリの抜粋ですが "インデックスを使用してアクセスできる、厳密に型指定されたオブジェクトのリストを表します。リストの検索、並べ替え、および操作のためのメソッドを提供します。" ということです。T には自分で定義したカスタムクラスを使えます。(それ以上の詳しい説明はググって調べてください)

まず、Visual Studio のウィザードを使って DB から Entity Data Model を自動生成します。

具体例は、SQL Server の場合ですが、以下の記事のステップ (1) ~ (10) を見てください。ASP.NET Web アプリの例ですが、Windows Forms アプリでもステップ (8) で web.config が app.config に変わる以外は同じです。 (注:CORE ではこの手順は使えませんので注意)

スキャフォールディング機能
http://surferonwww.info/BlogEngine/post/2017/07/23/creating-controller-and-view-in-mvc-using-scaffolding-function.aspx

そうすると以下の画像にあるような DbContext を継承したコンテキストクラスと、

イメージ説明

各テーブルを表すクラス定義のコードが自動生成されます。以下の画像は数あるテーブルの中の一つ Products テーブルを表すクラスです。

イメージ説明

例えば、上の DbContext を継承した NORTHWINDEntities クラスを使って SQL Server の Products テーブルから全レコードを List<Products> 型のオブジェクトとして取得する場合は以下のように 2 行で可能です。

イメージ説明

DataTable から配列を作ることを考える前に、上記の方向に進んで、質問者さんの目的が果たせないか考える方がよさそうな気がします。

投稿2020/01/09 02:08

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kariaka2020

2020/01/09 14:06

画像付きで詳しく説明していただき本当にありがとうございます。 こちらに質問を投稿するまでに「Linq」「List<T> 型」というものを何度か見かけ、存在自体に気づいてはいたのですが、いままで全く触ったことのないものよりC言語を軽く学んだ時に使用していた配列の方がイメージしやすく、こちらに逃げてしまっていました。 今回は半ば強引に配列を使って解決してしまいましたが、次回からはこちらのList<T>型も選択の候補に入れられるよう励みたいと思います。 質問に対する解決案という意味では少し違うのでベストアンサーは別の方にしますが、本当に感謝しています。 この度は回答、アドバイスをいただきありがとうございました。
guest

0

ベストアンサー

外側のループをDataTable.Columnsプロパティで回して、内側のループを提示されたコードで回せばいいのではないでしょうか。
列名でデータにアクセスするのであれば、DataColumn.ColumnNameプロパティを利用すればよろしいかと思います。

投稿2020/01/07 15:22

YAmaGNZ

総合スコア10323

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

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

kariaka2020

2020/01/08 01:44

回答ありがとうございます。 内側のループなのですが、 test[i, 0] = dr1["列名a"]; test[i, 1] = dr1["氏名"]; のうち、 test[i, 0] = dr1["列名a"]; で、"列名a"の列を指定しています。900列程あるのでひとつひとつ指定せずに何とかしたいのですが、ここを列指定せずどの列にも対応できるようにするにはどうすればでしょうか。 重ねての質問で申し訳ありません。よろしくお願いいたします。
YAmaGNZ

2020/01/08 01:50

回答に書いてある通り、ColumnNameプロパティから列名を取得するようにしてください。
kariaka2020

2020/01/08 02:00

ありがとうございます。 列名でデータにアクセスするという言葉の意味を勘違いしてしまっていました。 帰宅後調べなおして試してみます。
kariaka2020

2020/01/09 14:33

質問後すぐに的確な回答をいただいていたにもかかわらず、自分の力不足でお礼が遅くなり申し訳ありません。 ご指摘通り、.Columns,.ColumnsNameプロパティで疑問を解決することができました。 この度は回答ありがとうございました。
guest

0

勉強目的かつ提示コードが動作する前提

csharp

1var test = new List<(string, int)>(); 2 3//ここで i を開始列から終了列まで繰り返す for を入れてください 4 5foreach (DataRow dr1 in dt.Rows)   6{ 7    test.Add((dr1["氏名"],dr1[i])); 8}

配列にしたければ作ってからToArray()してください

投稿2020/01/08 03:55

編集2020/01/08 03:57
papinianus

総合スコア12705

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

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

papinianus

2020/01/08 03:56

vsみてないので動かない都思います。
kariaka2020

2020/01/09 14:10

返事が遅くなり申し訳ありません。 今回は別の方法での解決となってしまいましたが、List型を勉強するきっかけになりました。 この度は回答ありがとうございました。
guest

0

System.DataのDataRowクラスであれば、Itemプロパティより取り出せるような気がいたしますがいかがでしょうか?
dtr1[列のインデックス];

投稿2020/01/08 02:00

編集2020/01/08 02:14
kgreenjp

総合スコア97

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

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

kariaka2020

2020/01/08 02:07

回答ありがとうございます。 帰宅後Itemプロパティについて調べてみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.42%

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

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

質問する

関連した質問