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

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

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

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

1回答

1604閲覧

DataTableの内容を参照して算定を行いたい。

m21c003

総合スコア0

C#

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

1クリップ

投稿2020/06/29 01:51

編集2020/06/29 08:05

前提・実現したいこと

C#を使ってテキストファイルベースのある解析データを処理しようとしております。
処理の内容は,元のファイルから必要なデータをDataTableに格納した後に,乗算を行うという単純なものになります。
以下に流れを示すと,
1.ループでDataTable3のi行目を読み込む。
2.DataTable3中のデータをParseを用いてdouble型に変換。
3.DataTable3.Rows[i+1][2]>0,DataTable3.Rows[i+2][2]<0なら,乗算してそれぞれ個別のlistに追加する。
4.次の目標の行は4行先なので,i=i+3とする。

ここで問題が生じているのは,2のDataTableの中をdouble型に変換する箇所なのですが,必ず一番最後の要素で**入力文字列の形式が正しくありません。**と表示されてしまいます。
そこでdouble型に変換する前にstring check1,2に置き換えて確認したところ,string check2が""になっていました。
しかしDataTableは,元データを配列に格納して,そのうち文字列と空白を削除してlist<double>型に格納してDataTable.Rowに追加していることから,""となる意味が理解できませんでした。

追記:一番最後の要素とは,画像に示すi=156時A(157)のように,次の4行目(A161)にデータがない場合という意味になります。

発生している問題・エラーメッセージ

System.FormatException: '入力文字列の形式が正しくありません。'

該当のソースコード

C#

1private void GetShearForce(DataTable DataTable3) 2 { 3 dblNumOfFormerElement = double.Parse(DataTable3.Rows[0][0].ToString()); 4 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[0][1].ToString()); 5 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[0][2].ToString()); 6 7 for (int i = 0; i < DataTable3.Rows.Count; i++) 8 { 9 if (dblNumOfFormerElement - double.Parse(DataTable3.Rows[i][0].ToString()) +1 < 0 || 10 dblTypeOfFormerElement != double.Parse(DataTable3.Rows[i][1].ToString()) || 11 dblThicknessOfFormerElement != double.Parse(DataTable3.Rows[i][2].ToString()) 12 ) 13 { 14 var result = MessageBox.Show($"要素X方向のサイズもしは要素番号が変化しました。現在と異なるグループですか?" + 15 $"\r\n要素番号{dblNumOfFormerElement}→{double.Parse(DataTable3.Rows[i][0].ToString())}" + 16 $"\r\n要素タイプ番号{dblTypeOfFormerElement}→{double.Parse(DataTable3.Rows[i][1].ToString())}" + 17 $"\r\n要素厚さ{dblThicknessOfFormerElement}→{double.Parse(DataTable3.Rows[i][2].ToString())}","Notify",MessageBoxButton.YesNo); 18 if (result == MessageBoxResult.Yes) 19 { 20 listPositiveShearForce.Add(listTempData1.Sum()); 21 listNegativeShearForce.Add(listTempData2.Sum()); 22 listTempData1 = new List<double>(); 23 listTempData2 = new List<double>(); 24 } 25 } 26 27 if (strLoadingStep == "PositiveToNegative") 28 { 29 if (double.Parse(DataTable3.Rows[i + 1][2].ToString()) < 0 & double.Parse(DataTable3.Rows[i + 2][2].ToString()) > 0) 30 { 31 listTempData1.Add(double.Parse(DataTable3.Rows[i + 1][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 32 listTempData2.Add(double.Parse(DataTable3.Rows[i + 2][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 33 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 34 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 35 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 36 i = i + 3; 37 continue; 38 } 39 else if (double.Parse(DataTable3.Rows[i + 1][2].ToString()) > 0 & double.Parse(DataTable3.Rows[i + 2][2].ToString()) > 0) 40 { 41 listTempData2.Add(double.Parse(DataTable3.Rows[i + 2][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 42 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 43 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 44 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 45 i = i + 3; 46 continue; 47 } 48 else if (double.Parse(DataTable3.Rows[i + 1][2].ToString()) < 0 & double.Parse(DataTable3.Rows[i + 2][2].ToString()) < 0) 49 { 50 listTempData1.Add(double.Parse(DataTable3.Rows[i + 1][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 51 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 52 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 53 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 54 i = i + 3; 55 continue; 56 } 57 else 58 { 59 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 60 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 61 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 62 i = i + 3; 63 continue; 64 } 65 } 66 else 67 { 68 string check1 = DataTable3.Rows[i + 1][2].ToString(); 69 string check2 = DataTable3.Rows[i + 2][2].ToString(); 70 71 if (double.Parse(DataTable3.Rows[i + 1][2].ToString()) > 0 & double.Parse(DataTable3.Rows[i + 2][2].ToString()) < 0) 72 { 73 listTempData2.Add(double.Parse(DataTable3.Rows[i + 1][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 74 listTempData1.Add(double.Parse(DataTable3.Rows[i + 2][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 75 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 76 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 77 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 78 i = i + 3; 79 continue; 80 } 81 else if (double.Parse(DataTable3.Rows[i + 1][2].ToString()) < 0 & double.Parse(DataTable3.Rows[i + 2][2].ToString()) < 0) 82 { 83 listTempData1.Add(double.Parse(DataTable3.Rows[i + 2][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 84 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 85 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 86 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 87 i = i + 3; 88 continue; 89 } 90 else if (double.Parse(DataTable3.Rows[i + 1][2].ToString()) > 0 & double.Parse(DataTable3.Rows[i + 2][2].ToString()) > 0) 91 { 92 listTempData2.Add(double.Parse(DataTable3.Rows[i + 1][2].ToString()) * double.Parse(DataTable3.Rows[i][1].ToString()) * double.Parse(DataTable3.Rows[i][2].ToString())); 93 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 94 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 95 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 96 i = i + 3; 97 continue; 98 } 99 else 100 { 101 dblTypeOfFormerElement = double.Parse(DataTable3.Rows[i][1].ToString()); 102 dblThicknessOfFormerElement = double.Parse(DataTable3.Rows[i][2].ToString()); 103 dblNumOfFormerElement = double.Parse(DataTable3.Rows[i][0].ToString()); 104 i = i + 3; 105 continue; 106 } 107 } 108 } 109 110 listPositiveShearForce.Add(listTempData1.Sum()); 111 listNegativeShearForce.Add(listTempData2.Sum()); 112 113 for (int i = 0; i < listPositiveShearForce.Count; i++) 114 { 115 DataTable4.Columns.Add(i.ToString()); 116 } 117 118 DataTable4.Rows.Add(listPositiveShearForce); 119 DataTable4.Rows.Add(listNegativeShearForce); 120 return; 121 }

試したこと

まずDataTableをCSV形式で保存して内容を確認。画像黄色で塗りつぶした箇所がエラー時に参照しようとしているデータ。
イメージ説明
dblNumOfFormerElementがエクセルの(A153)の1653であるので,現在読み込もうとしている行が(A157)の1654であることはi=156であることから確認できる。
check1=DataTable3.Rows[i+1][2].ToString()が-0.219と参照が正しく行えている。
check1=DataTable3.Rows[i+2][2].ToString()が本来-0.223であるが,実際は""と参照ができていない。
イメージ説明
DataTableをDataGridにバインディングした結果。空白等は確認できない。
イメージ説明
追記:i=157に該当するItemArray
イメージ説明
追記:i=158に該当するItemArray
イメージ説明

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

YAmaGNZ

2020/06/29 02:27 編集

DataTable3に格納した時点で内容が正しいかは確認したのですか? List<double>としてDataRowに入れているのなら、Listの要素はdoubleなのではないのですか?
m21c003

2020/06/29 05:15

ご回答ありがとうございます。ご指摘の通り,元のデータをStreamReader.ReadLineで1行よみ,double.TryParseがTrueかつ,!String.IsNullOrWhiteSpaceがTrueの場合にlist<double>に追加したものをDataRowとしているので,当然doubleにParse可能であると考えております。 因みにDataTableをCSVに保存する前にDataGridにバインディングしたものの結果も追記します。 ご指摘の意図と異なる回答でしたら申し訳ございません。
YAmaGNZ

2020/06/29 05:35

「DataTableをCSVに保存する前」にあるDataTableは問題のDataTable3とは異なるものなのですよね? DataTable3にデータをセットした直後にデータが正しいのか「実際に」確認してください。「考えております」では意味がありません。 また、DataTable3にセットした直後が正しいのであれば、GetShearForceが呼ばれるまでの間にデータを壊しうる箇所があるかも確認してください。
m21c003

2020/06/29 08:02

DataTableをCSVに保存する前のデータとは,DataTable3のことを指しており,DataTable3をDataGridにバインディングした直後にGetShearForce(DataTable3)として,該当のソースコードの関数を呼び出しているので,その間に「壊しうる?」箇所は確認できませんでした。 また,DataTable3のData.Rowについても,この場合のDataRowにあたるInsertDataのItemArrayを確認しても,エラーは確認できませんでした。
YAmaGNZ

2020/06/29 08:35

とりあえず、適当なDatatableを作って、提示されたソースを動かしてみましたが現象は確認できませんでした。 入力のDataTable3が思っているデータとなっていない可能性が高いと思います。 私はソース等から、1つのデータの塊は4行のデータだと思っているのですがあっていますか?
m21c003

2020/06/29 09:09

確認していただきありがとうございます。 ご指摘の通り1つのデータの塊は4行で1セットの形になっており,-999.9というのがセットの終わりになっています。 DataTable3の内容を精査したいともいます。
guest

回答1

0

C#

1for(int i = 0; i < DataTable3.Rows.Count; i++) 2{ 3 Console.WriteLine("-"); 4 Console.WriteLine(string.Join(",",DataTable3.Rows[i].ItemArray)); 5 Console.WriteLine(string.Join(",", DataTable3.Rows[i + 1].ItemArray)); 6 Console.WriteLine(string.Join(",", DataTable3.Rows[i + 2].ItemArray)); 7 Console.WriteLine(string.Join(",", DataTable3.Rows[i + 3].ItemArray)); 8 i += 3; 9} 10

このような感じで塊が判別しやすいように出力して確認してみてはどうでしょうか?

投稿2020/06/29 09:15

YAmaGNZ

総合スコア10489

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

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

m21c003

2020/06/30 05:12

ご回答ありがとうございました。自宅のパソコンで同様のプログラムを実行した結果,エラーが発生しなくなりました。一度作業していたパソコンのVisualStudioをクリーンインストールして確認したいと思います。 自宅のパソコンでご提示いただいた方法をMessageBoxで確認した結果,必要としていたデータと同様であることが確認できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問