いろいろはまった
C#においてExcellのように扱えるオブジェクトdataGridView
ですが、扱いにはクセがあります(仕様であり個人の感想でしかなく、仕様嫁)。
セルの値を数値解釈(変換)できるかどうか
セルに値を入力したときは基本的に文字列として受け取ります。
これをのちのち数値変換するので数値解釈(変換)できないときはその入力をキャンセルしたい、ということを考えました。
入力があったとき発動するアクションを設定したいので、似たような下記3つのアクションのうちここでは3番になります。
1番は入力前、セル選択時に発動するので該当セルが空白の状態で動作します。
2番は単独ではこれでも動きますが、他の関数からセルに入力されたりしたときにも動きます。
3番が手動入力のみに発動します。
//1 private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) { //セルを選択したときに動く } //2 private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { //他の関数から書き込みしたときも動く } //3 private void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e) { //セルの入力が完了したときに動く }
セルの入力を空白(削除)にする。
""
にしたくなりますが、これは何も起きません。null
を与えます。
//× dataGridView1[e.ColumnIndex, e.RowIndex].Value = ""; //〇 dataGridView1[e.ColumnIndex, e.RowIndex].Value = null;
セルの値を数値変換する
先に述べたとおりdataGridView
に持たせられる「数値」は文字列になります。
何かしらの計算を行うには数値に変換する必要があります。
ここにたとえば文字列"1"
を与えたとすると、
//1 × 構文エラー、dataGridView1[1, 1].Valueはオブジェクトのため double L1 = double.Parse(dataGridView1[1, 1].Value); //2 構文的には〇、 double.Parseが受け取るのはString double L1 = double.Parse(dataGridView1[0, i].Value.ToString()); //3 構文的には〇、 double.Parseが受け取るのはString double L1 = double.Parse((String)dataGridView1[0, i].Value); //4 構文的には〇、(double)が受け取る型は何でもいい? L1 = (double)dataGridView1[0, i].Value;
(double)
や(String)
はキャストといわれる型変換で、ToString()
は文字列表現を得るものです。
いずれも数値変換不可能な文字列が与えられたときは例外が発生します。
数値変換可能なことが保証されていれば4でよい気がします。
数値変換可能かどうか
変換可能かどうかわからないときはdouble.TryParse
で変換可能か否かを取得します。
以下ではtrue
のときその数値を取得し、false
のときnull
にします。
if (double.TryParse(dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString(), out m) == true) //if (double.TryParse((String)dataGridView1[e.ColumnIndex, e.RowIndex].Value, out m) == true) { dataGridView1[e.ColumnIndex, e.RowIndex].Value = m; //列,行 } else { dataGridView1[e.ColumnIndex, e.RowIndex].Value = null; }
まとめ
C#で文字列その他の数値変換を扱う方法について調べたら結構複雑でした、という話でした。