トップ回答者
Integer型配列変数の宣言位置による挙動の違いについて

質問
-
10年ぶりにプログラミングをしています。ASP.NET+VBでWEBフォームを作成しております。
GridViewのFooterRowに合計を表示するため、以下のようなコードを作成しました。Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound Dim i As Integer Dim total(3) As Integer Dim cname() As String = New String(3) {"hoge0", "hoge1", "hoge2", "hoge3"} Select Case e.Row.RowType Case DataControlRowType.DataRow For i = 0 To 3 total(i) += CInt(DataBinder.Eval(e.Row.DataItem, cname(i))) Next Case DataControlRowType.Footer For i = 0 To 3 e.Row.Cells(i + 2).Text = total(i).ToString("#,##0") Next End Select End Sub
上記コードの結果、FooterRowの合計値は全て「0」で返ってきてしまいます。
一方で、Dim total(3) as Integer の宣言をページ冒頭ですれば、意図した通りに合計が計算されます。この挙動の違いについて、理由がわからず、とまどっている状況です。
数値型の配列は、Protected Sub内で宣言してはダメなのでしょうか?
回答
-
すでに解決済みとなっていますが、せかっくレスを書いたのでアップしておきます。
GridView1_RowDataBound メソッドの中の Dim total(3) As Integer の行にブレークポイントを設定しデバッグ実行してみてください。
RowDataBound イベントはヘッダ、フッタを含めた行の数だけ発生しますが、そのたび GridView1_RowDataBound メソッドが呼び出され Dim total(3) As Integer で total の各要素はゼロに初期化されるのが分かると思います。
そして、最後にフッタ行で RowDataBound イベントが発生し GridView1_RowDataBound メソッドが実行されると再び Dim total(3) As Integer で total の各要素はゼロに初期化されます。
e.Row.Cells(i + 2).Text = total(i).ToString("#,##0") でフッタに値を書き出していますが、total 全要素はゼロなので、
> 上記コードの結果、FooterRowの合計値は全て「0」で返ってきてしまいます。
ということになります。
質問者さんが気付かれた通り、
> Dim total(3) as Integer の宣言をページ冒頭ですれば、意図した通りに合計が計算されます。
とすれば、前回の RowDataBound イベントでの total の各要素の値は保持されますので、そうするのが正解です。
その他、値の取得方法など見直した方がよさそうなところがあります。以下の記事のようにしてはいかがでしょう?
GridView, ListView に合計表示
http://surferonwww.info/BlogEngine/post/2010/11/07/Show-sum-in-GridView-or-ListView.aspx- 回答としてマーク SoushokukeiOyaji 2020年6月16日 5:46
-
ご提示いただいたプログラムだけを拝見して言えることは・・・、
このSubの中でtotal()にセットされた値は、Subから一度出る際に失われます。total()に値をセットする動作と、e.RowCells().Textに値をセットする動作は、このSubの1回の実行で両方行うのではなく、このSubの別の回の実行になるんだと推察します。そうであれば、e.RowCells().Textに値をセットする際のtotal()の値は、ご提示いただいたプログラムの場合は初期値しか入っておらず、ゼロになってしかるべきです。
- 編集済み 外池 2020年6月16日 3:58
- 回答としてマーク SoushokukeiOyaji 2020年6月16日 4:38
すべての返信
-
ご提示いただいたプログラムだけを拝見して言えることは・・・、
このSubの中でtotal()にセットされた値は、Subから一度出る際に失われます。total()に値をセットする動作と、e.RowCells().Textに値をセットする動作は、このSubの1回の実行で両方行うのではなく、このSubの別の回の実行になるんだと推察します。そうであれば、e.RowCells().Textに値をセットする際のtotal()の値は、ご提示いただいたプログラムの場合は初期値しか入っておらず、ゼロになってしかるべきです。
- 編集済み 外池 2020年6月16日 3:58
- 回答としてマーク SoushokukeiOyaji 2020年6月16日 4:38
-
すでに解決済みとなっていますが、せかっくレスを書いたのでアップしておきます。
GridView1_RowDataBound メソッドの中の Dim total(3) As Integer の行にブレークポイントを設定しデバッグ実行してみてください。
RowDataBound イベントはヘッダ、フッタを含めた行の数だけ発生しますが、そのたび GridView1_RowDataBound メソッドが呼び出され Dim total(3) As Integer で total の各要素はゼロに初期化されるのが分かると思います。
そして、最後にフッタ行で RowDataBound イベントが発生し GridView1_RowDataBound メソッドが実行されると再び Dim total(3) As Integer で total の各要素はゼロに初期化されます。
e.Row.Cells(i + 2).Text = total(i).ToString("#,##0") でフッタに値を書き出していますが、total 全要素はゼロなので、
> 上記コードの結果、FooterRowの合計値は全て「0」で返ってきてしまいます。
ということになります。
質問者さんが気付かれた通り、
> Dim total(3) as Integer の宣言をページ冒頭ですれば、意図した通りに合計が計算されます。
とすれば、前回の RowDataBound イベントでの total の各要素の値は保持されますので、そうするのが正解です。
その他、値の取得方法など見直した方がよさそうなところがあります。以下の記事のようにしてはいかがでしょう?
GridView, ListView に合計表示
http://surferonwww.info/BlogEngine/post/2010/11/07/Show-sum-in-GridView-or-ListView.aspx- 回答としてマーク SoushokukeiOyaji 2020年6月16日 5:46