質問: False End If '以下略(値7~9の場合の場合の分岐処理) End Select '以下略(申請項目数分繰り返し) End If End Sub ``` ### 試したこと 上記ソースはGridViewのRowDataBound処理の内容になります。 (実ソースそのままは出すことが出来ないため、簡略化しています) 一応、このソースで目的の動作をすることは確認できているのですが、うまく共通化や簡略化が 出来ず、RowDataBoundイベントが大変長くなってしまっています。(350行ほど) また、上記表の列「申請項目」に該当するものが、全部で6列あります。 項目ごと分岐数や表示文字列が異なったりするため、共通関数にうまく落とし込めません。 そもそも、チェックボックスやラベルの表示/非表示を切り替える、という やり方が、一般的なのかどうかもわかりません。 もっとスマートな書き方や、一般的にはこうするんじゃない?という情報があれば、 教えていただきたいです。 GridViewにもこだわりませんので、ご意見やアイディア、ヒントを伺えれば助かります。 ### 補足情報(言語/FW/ツール等のバージョンなど) asp.net(VB) .NetFramework 4.0 Visual Studio 2010
回答: せっかく説明していただいたのに何ですが、判定ロジックが理解できませんので、判定ロジックの改善案の提案はできません。(350 行を短くするための提案や判定ロジックのコードを読みやすくするための提案はできませんという意味です) 代わりに、もっと基本的な改善案、プレゼンテーション層、ビジネスロジック層、データ層という 3 層構造に分けることを提案します。 3 層構造がどういうものかについては以下の記事の図1を見てください。 第1回 ASP.NETによる3階層Webアプリ「ITブック」構築 今の質問者さんのコードは、判定ロジックが ASPX ページのコードビハインドに含まれている、即ち、プレゼンテーション層(ASPX ページ)とビジネスロジック層(判定ロジック)が一緒になっていて 2 層構造になっています。 これを 3 層構造にする、即ち、GridView の RowDataBound イベントのハンドラに判定ロジックを含めるのではなく、別にクラスファイルを作ってそれに含めるようにします。そうすれば、少なくとも ASPX ページのコードの可読性や全体の保守性はかなり上がると思います。 具体的には、クラスファイルに、DB から生データの取得 ⇒ それをベースに各列に何を表示するかを判定 ⇒ 判定結果を戻り値として返す・・・というメソッド(即ち、ビジネスロジック)を実装します。 メソッドの戻り値は、先の質問者さんのスレッド で私が例として書いた List 型にするのが良いと思います。 T は例えば(あくまで例えばです)以下のようにし、Application1 ~ 6 には判定ロジックで生データを判定した結果("applied", "N/A", "check", "unckeck" など)を格納します。 ``` public class Result { public string ControlNumber { get; set; } public string UserName { get; set; } public string Application1 { get; set; } public string Application2 { get; set; } public string Application3 { get; set; } public string Application4 { get; set; } public string Application5 { get; set; } public string Application6 { get; set; } } ``` ASPX ページには GridView と ObjectDataSource を実装し、クラスファイルに実装したメソッドを ObjectDataSource の SelectMethod に設定すれば、判定結果(上の例で言うと "applied", "N/A", "check", "unckeck")が表示できます。 ChackBox にする必要はなくて、結果を文字列として表示できれば良いのであればそれだけで済むはずです。 どうしても CheckBox と Label を切り替えて表示したいということであれば、GridView の RowDataBound イベントのハンドラで処置するなどもう一工夫必要ですが、ASPX ページのコードの可読性は格段に上がるはずです。 **【追記】** サンプルを作ったのでアップしておきます。Result クラスは上のものから簡略化しました。.aspx のコードで、GridView1 が文字列で表示、GridView2 が CheckBox と Label を切り替えて表示するようにしています。 **ビジネスロジック** ``` using System; using System.Collections.Generic; using System.Linq; using System.Web; public class Result { public string Name { get; set; } public string App1 { get; set; } public string App2 { get; set; } public string App3 { get; set; } } public class BusinessLogic { public List GetResults() { List results = new List() { new Result() { Name = "ユーザー1", App1 = "チェック未", App2 = "申請不可", App3 = "チェック未" }, new Result() { Name = "ユーザー2", App1 = "チェック済", App2 = "チェック未", App3 = "申請済" }, new Result() { Name = "ユーザー3", App1 = "チェック未", App2 = "チェック済", App3 = "チェック済" } }; return results; } } ``` **.aspx** ``` <%@ Page Language="C#" AutoEventWireup="true" CodeFile="0022-GridViewCheckBox.aspx.cs" Inherits="_0022_GridViewCheckBox" %> ``` **.aspx.cs** ``` using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class _0022_GridViewCheckBox : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected bool LabelVisible(string str) { if (str == "チェック未" || str == "チェック済") { return false; } return true; } protected bool CheckBoxVisible(string str) { if (str == "チェック未" || str == "チェック済") { return true; } return false; } protected bool IsChecked(string str) { if (str == "チェック未") { return false; } if (str == "チェック済") { return true; } return false; } } ```