解説

実例で学ぶASP.NETプログラミング

第5回 DB連携ページをASP.NETで構築する(後編)

小田原 貴樹(うりゅう)
2003/04/22
Page1 Page2 Page3 Page4 Page5 Page6

■今月のお買い得酒表示機能の実装

 今月のお買い得酒表示機能能を実現するためには、実際の商品を表示するためのメソッドのほかに、「商品表」の中から列「特売価格」が0以上の数値になっている商品の主キーとなるIDを抽出するメソッドが必要だ。と、ここまでは「季節限定酒表示機能の作成」の項で作成したメソッドとほぼ同じなのだが、この機能は商品を2つ表示しなければならないという点が異なる。そこから先に作成することにして、コンポーネント・クラス(CORE.VB)の中に作成した情報表示用クラス「INFOV」の中に以下のコードを追加してほしい。

 1: Public Function TPRODID(ByVal VCNT As Integer) As Array
 2:   Dim PSET As New PVSET()
 3:   Dim PVIEW As New DataView()
 4:   Dim I As Integer
 5:   Dim TID(VCNT - 1) As Integer
 6:   DC.FDPV(PSET)
 7:   PVIEW.Table = PSET.Tables("酒完成表")
 8:   PVIEW.RowFilter = "特売価格 > 0"
 9:   Dim PMID() As String = RNDID(PVIEW.Count, VCNT)
10:   For I = 0 To VCNT - 1
11:     TID = PVIEW(PMID(I))("ID")
12:   Next
13:   Return TID
14: End Function
15:
16 :Public Function RNDID(ByVal MAXID As Integer, ByVal NEEDID As Integer) As Array
17:   Dim I As Integer
18:   Dim RID As New Random()
19:   Dim SPID As Integer
20:   Dim PTID As New System.Collections.Specialized.StringCollection()
21:   Dim PMID(NEEDID - 1) As String
22:   For I = 0 To NEEDID - 1
23:     Do
24:       SPID = RID.Next(0, MAXID - 1)
25:     Loop While PTID.IndexOf(SPID) = -1
26:     PTID.Add(SPID)
27:   Next
28:   PTID.CopyTo(PMID, 0)
29:   Return PMID
30: End Function
特売商品を2つ抽出するためのメソッド
特売商品を抽出するメソッドと、その中から重複しない2つのインデックス番号を選び出すメソッドが連携する。

 これら2つのメソッドは連携して動作するので、1度に解説したい。まず、メソッド「TPRODID」は引数として、返す必要のあるIDの数(この場合は「2」)を指定する。コード内の5行目までは宣言文でここまでで何度も説明したので繰り返さない。ちなみに4行目の数値型変数「TID」は配列で宣言しているが、これは引数で受け取った必要な数だけのIDを格納するためである。

 6行目〜8行目ではデータを取得して、そのデータに対して「特売価格が入力されているもの」という条件でフィルタをかけている。続く9行目でフィルタのかかったデータの総数、すなわち特売価格が入力されているレコード数と、返す必要のあるIDの数を引数にして、16行目から始まるもう1つののメソッド「RNDID」に受け渡している。ここで、コードの流れに従ってメソッド「RNDID」を見てほしい。

 RNDIDメソッドはRandomクラスを利用して乱数を生成するが、ここで作る機能では「重複しない2つの乱数」を必要とするので多少複雑になっている。

 20行目の「PTID」はStringCollectionオブジェクトという聞き慣れないオブジェクトを作成している。.NETでは従来の配列などに加えて、新しく「コレクション」という集合体クラスが追加されている。

 この新しい便利な概念には2つの利用方法がある。まず1つは「各種オブジェクトを何でも格納ができる配列」としての利用方法で、これにはもちろんWebコントロールも含まれるので、実行時における複数コントロール操作には欠かせない。

 もう1つは「配列の問題点を改善したオブジェクト」としての利用方法であり、ここで利用しているStringCollectionオブジェクトもその1つだ。その具体的な効果は、後ほど説明しよう。

 21行目の宣言文はこのメソッドの結果を格納するための文字列型配列だ。

 22行目〜27行目のFor〜Next文が実際の乱数生成にあたる。基本的な構文とこれまでに出てきた構文は割愛させていただいて、主要な部分を説明しよう。25行目Do〜Loop While文の終了条件「PTID.IndexOf(SPID) = -1」に前述のStringCollectionオブジェクトの機能性が表れている。StringCollectionオブジェクトのIndexOfメソッドは、引数として指定された文字列(ここでは生成された乱数である「SPID」)が、これまでにStringCollectionオブジェクトに格納されている文字列と一致しているかどうかを確認し、一致している場合にはそのインデックスを、一致していなければ「-1」を返す。

 ここで必要としている「重複していない2つの数値」という条件を定義するには、もってこいの機能で、同様のことを配列で行った場合のコードの煩雑さを考えると非常に機能的である。

 無事Do〜Loop While文を抜けた「重複していない」数値を26行目でStringCollectionオブジェクトのAddメソッドを利用して追加している。これも配列では煩雑になりがちな、「要素の追加」という機能をあっさりとこなせ、機能性が高い。

 こうしてFor〜Next文を抜けた「PTID」には重複していない2つの乱数が格納されているが、これを28行目のCopyToメソッドで配列にコピーしている。CopyToメソッドは引数として、コピー先の配列オブジェクト名と、コピーを開始するStringCollectionオブジェクトのインデックス番号を指定可能であり、これまた大変便利なメソッドだ。これで「ランダムに取得された重複しない2つのインデックス」が取得できたので、TPRODIDメソッドに戻し、取得したインデックス番号を元得られる商品の主キーであるIDを、さらに配列に格納して終了している。

 説明が長めになったがコレクション・オブジェクトを使い回すと、配列に比べコーディング(もちろんデバッグも)の効率が高まるということを感じていただければ幸いだ。これで表示する商品のIDは取得できたので、商品を表示するメソッドを作成しよう。

 1: Public Sub TPRODIN(ByVal PID As Integer, ByVal PI As HyperLink, ByVal PT As Label, ByVal PN As Label, ByVal PTK As Label, ByVal PNK As Label, ByVal PS As Label)
 2:     Dim PSET As New PVSET()
 3:     Dim CSET As New CASET()
 4:     DC.FDPV(PSET)
 5:     DC.FDCA(CSET)
 6:     Dim PR As PVSET.酒完成表Row = PSET.酒完成表.FindByID(PID)
 7:     Dim CR As CASET.酒カテゴリRow = CSET.酒カテゴリ.FindByID(PR.酒種ID)
 8:     PI.ImageUrl = "./PIMGM/" & PR.酒画像
 9:     PI.NavigateUrl = "PRODET.ASPX?ID=" & PR.ID
10:     PT.Text = CR.酒種
11:     PN.Text = PR.銘柄
12:     PTK.Text = PR.特売価格.ToString("C")
13:     PNK.Text = PR.小売価格.ToString("C")
14:     PS.Text = "(" & PR.容量 & "ml)"
15: End Sub
商品のIDを受け取って今月のお買い得酒を表示するメソッド

 このメソッドは、表示する内容が増えている以外は「季節限定酒表示機能の作成」の項で作成したKPRODINメソッドとほとんど変わりがないので、コード内容の解説はそちらを参照していただきたい。KPRODINメソッドとの違いは、後半の12行目および13行目で、文字列を通過形式で表示するためにToStringメソッドに書式指定をしているくらいだ。

 表示に必要な情報は整ったので、実際に表示するコードを記述しよう。メイン・フレーム・ページのコード・ビハインド・ファイル「MAIN.ASPX.VB」を開いて、Page_Loadメソッド内に以下のコードを足してほしい。

Dim TID() As Integer = INFO.TPRODID(2)
INFO.TPRODIN(TID(0), PLI1, PTL1, PNL1, PTKL1, PNKL1, PSL1)
INFO.TPRODIN(TID(1), PLI2, PTL2, PNL2, PTKL2, PNKL2, PSL2)
今月のお買い得酒を実際に表示するためのコード
MAIN.ASPX.VBのPage_Loadメソッドに追加する。

 ここまで読み進めて来た方なら、問題なく理解できると思う。表示のメソッドを2回実行している点は冗長なので、工夫によっては1つにまとめられるかもしれないが、今回のケースでは固定的に2つを表示するので、これでも充分だと思う。さて、ようやくメイン・フレームの構成要素もすべて出来上がった。


 INDEX
  実例で学ぶASP.NETプログラミング
  第5回 DB連携ページをASP.NETで構築する(後編)
    1.季節限定酒表示機能のデザインを作成する
    2.季節限定酒表示機能の実装
    3.DataSetオブジェクトの主キー作成
    4.今月のお買い得酒表示機能のデザインを作成する
  5.今月のお買い得酒表示機能の実装
    6.全体デザイン修正とデバッグ
 
インデックス・ページヘ  「解説 :実例で学ぶASP.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間