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

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

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

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

Q&A

解決済

2回答

8013閲覧

C#、エクセルシートのデータを配列に入れる際のループの回し方について

tomi0416

総合スコア43

C#

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

0グッド

0クリップ

投稿2015/05/13 09:23

lang

1var objWsAaa = (object[,])wsAaa.Range[wsAaa.Cells[12,2],wsAaa.Cells[r,c]].Cells.Value2;

上記ワークシートのデータをリストに入れる際に
大枠のループでは列数、
中のループでは行数で処理にあてはめなければいけません。
可能でしょうか。
また、どのようにリストに入れることができますか。

lang

1var listObjWsAss = new double[r]; 2v = 0; 3for(k = 1; k < c + 1; k++) 4{ 5 for(n = 1; n < r + 1; r++) 6 { 7 listObjWsAss[n][v] = double.Parse((string)objWsAaa[n,k]); 8 } 9}

今の状況は上記です。
よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

コメント踏まえて、シートA→シートBへのデータ反映部分を組んでみました。

lang

1//列毎に処理 2for(int currentCol = 1; currentCol <= c - 2; currentCol++) 3{ 4 //シートA対象列の全行取得 5 var rowsData = new List<object>(); 6 for(int currentRow = 1; currentRow <= r - 12; currentRow++) 7 { 8 rowsData.Add(objWsAaa[currentRow, currentCol]); 9 } 10 11 //対象列をシートBにコピーするか判定(1つでも条件を満たすセルがあればコピーしない) 12 var isExist = rowsData.Any((x) => 13 { 14 //True:セルが対象外とする条件を満たす 15 return true; 16 }); 17 18 //シートBデータへ反映 19 if(!isExist) //対象列のみ 20 { 21 for(int currentRow = 1; currentRow <= r - 12; currentRow++) 22 { 23 //便宜上、上書きしてる。加算とか、なんでも良い。 24 objWsB[currentRow, currentCol] = rowsData[currentRow - 1]; 25 } 26 } 27} 28//※シートAのデータ行数≦シートBのデータ行数を前提としたのでチェックしてない。 29//※doubleの必要性がよくわからなかったのでobjectのまま処理している

未検証です。ループが1回多く回るとか、凡ミスがあるかも。

投稿2015/05/14 06:12

Tak1wa

総合スコア4791

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

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

tomi0416

2015/05/14 08:13

ありがとうございます。 一点質問があります。 "var isExist = rowsData.Any((x) =>{});" 上記の"(x)"って何ですか?!
Tak1wa

2015/05/14 08:20

rowsDataの1要素です。 rowsDataはList<object>なのでobjectですね。
tomi0416

2015/05/14 09:44

もう少しでできそうです。 ありがとうございました!
guest

0

こんにちは。

tomi0416さんのやりたいことが、ちゃんと理解出来ているか自信が無いですが、
おそらく、案2ですか?

lang

1//案1:行列の番号でリスト作りたいなら 2var result = new Dictionary<Tuple<int, int>, double>(); 3for (k = 1; k < c + 1; k++) 4{ 5 for (n = 1; n < r + 1; n++) 6 { 7 //TODO:Cast可否チェックしたほうが良いです。 8 result.Add( 9 new Tuple<int, int>(n, k), 10 double.Parse((string)objWsAaa[n, k]) 11 ); 12 } 13} 14 15//案2:Excelの行列番号ではなく0始まりで配列作るのであれば 16const int startCol = 12; //wsAaa.Cells[12,2]の12 17const int startRow = 2; //wsAaa.Cells[12,2]の2 18var listObjWsAss = new double[r,c]; 19//v = 0; vって固定で0ですか?つかいどころがイマイチわかりませんでした。 20for (k = 1; k < c + 1 - startCol; k++) 21{ 22 for (n = 1; n < r + 1 - startRow; n++) 23 { 24 listObjWsAss[n - 1, k - 1] = double.Parse((string)objWsAaa[n, k]); 25 } 26}

未検証!

投稿2015/05/13 09:56

編集2015/05/13 09:57
Tak1wa

総合スコア4791

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

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

tomi0416

2015/05/13 10:29

ありがとうございます!!! 案2です! しかし、案2を記載した際に、”[n - 1, k - 1]”でエラーになります。 エラー内容は、”Cannot apply indexing to an expression of type 'object'”です。
tomi0416

2015/05/13 10:33

エラー内容を間違えました。 正、"Indexer has 1 paramerter(s) but is invoked with 2 argument(s)" 誤、"Cannot apply indexing to an expression of type 'object'"
Tak1wa

2015/05/13 10:54

うーん、実装したコードを見せてもらえますか?
tomi0416

2015/05/13 11:03

var listObjWsAss = new double[r]; v = 0; for(k = 1; k < c + 1; k++) { for(n = 1; n < r + 1; r++) { listObjWsAss[n-,v-] = double.Parse((string)objWsAaa[n,k]); } }
Tak1wa

2015/05/13 11:16

まず、格納する配列は多次元で定義してください。 →var listObjWsAss = new double[r,c];
Tak1wa

2015/05/13 11:17

変数vは結局使うのでしょうか?ずっと0ですけど…
tomi0416

2015/05/13 13:59

var listObjWsAss = new double[r,c]; v = 0; for(k = 1; k < c + 1; k++) { for(n = 1; n < r + 1; r++) { listObjWsAss[n-,v-] = double.Parse((string)objWsAaa[n,k]); } v = v + 1; }
Tak1wa

2015/05/13 14:18

とりあえずこちらでは以下で動いており、静的エラーも実行時エラーも発生していません。 var listObjWsAss = new double[r,c]; int v = 0; //便宜上ここで変数定義 for(k = 1; k < c + 1; k++) { for(n = 1; n < r + 1; n++) { listObjWsAss[n-1,v] = double.Parse((string)objWsAaa[n-1,k-1]); } v = v + 1; } "Indexer has 1 paramerter(s) but is invoked with 2 argument(s)" このエラーは listObjWsAss[n-1,v] = …の行で発生しているのでしょうか。 追加で以下を教えてください。 VisualStudioのバージョン、ターゲットフレームワークのバージョン
tomi0416

2015/05/14 04:20

VisualStudioのバージョン、2013 ターゲットフレームワークのバージョン、4.5 すみません、私の質問はTak1waさんが考えてくださった案2なのですが、 案2のvar listObjWsAss = new double[r,c];の部分で配列の要素数を指定しているのですが、要素数は、 for (k = 1; k < c + 1 - startCol; k++){}内の条件で決まります。 なので、宣言する際は要素数がわからない状態です。 var objWsAaa = (object[,])wsAaa.Range[wsAaa.Cells[12,2],wsAaa.Cells[r,c]].Cells.Value2; var listObjWsAss = new List<List<double>>(); v = 0; for(k = 1; k < c + 1; k++) { var listData = new List<double>(); for(n = 1; n < r + 1; r++) { listData [n][v] = double.Parse((string)objWsAaa[n,k]); }  listObjWsAss.Add(listData); } 上記、今の状態です。 やりたいことの詳細を追記させていただきます。 エクセルシートAにあるデータをエクセルシートBに貼りつけたいです。 その際に条件があります。 エクセルシートAの列ごとチェックします。(一個目のfor文) 条件を満たした列は、エクセルシートBにはりつける対象列になります。 二個目のfor文で対象列の行のデータを取得したいです。 どうぞ、よろしくお願いいたします。
Tak1wa

2015/05/14 04:24

なるほど。ありがとうございます。意味がわかりました。 ふたつ質問です。 1.対象外と判断された列はシートB上ではどうなりますか。空白列ですか?詰めますか? 2.ObjectのままではなくDouble型にしているのは何故ですか?
tomi0416

2015/05/14 05:07

ありがとうございます。 1.対象外と判断された列はシートB上ではどうなりますか。空白列ですか?詰めますか? → 対象外と判断された列はシートB上ではでは変化しないです。理由は、シートBのデータをオブジェクトに入れています。 var objWsB = (object[,])wsB.Range[wsB.Cells[a,2],wsB.Cells[b,c]].Cells.Value2; (a,b,cはシート内から出力したlong型のデータです。) 2.ObjectのままではなくDouble型にしているのは何故ですか? → シートBのデータがDoubleなのでDoubleにしました。もしかして、関係ないですか?!
Tak1wa

2015/05/14 05:29

objWsBの登場で複雑になってしまいました。 添え字のa, b, c, r などのせいで問題点がわかりにくくなっています…。 シートAでは12, 2, r, cが登場しますね。 シートBではa, 2, b, cが登場しますね。 このそれぞれのインデックスの関連性を教えてください。
tomi0416

2015/05/14 05:43

var objWsAaa = (object[,])wsAaa.Range[wsAaa.Cells[12,2],wsAaa.Cells[r,c]].Cells.Value2; var objWsB = (object[,])wsB.Range[wsB.Cells[a,2],wsB.Cells[b,c]].Cells.Value2; 関連性は特にないです。 変数にした理由は、固定ではないっということを伝えたかっただけです。 値は各シートのデータ量で変動します。 ご存じの通り、"シートBのデータ量" > "シートAのデータ量"です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問