バックナンバー 第79号:VB2008 データベースプログラミング

VB 2008 Express Editiont と、SQL Server 2008 Express with Advanced Services を使って、フォームから入力した受注データを、受注ヘッダー表と受注ディテール表に登録する、受注伝票エントリープログラムを作成していきます。
受注伝票エントリー 第7回(商品クラス)
第79号(2009.12.08発行)
====================================================================
       ★★ -- VB.NETデータベースプログラミング奮闘記 -- ★★
           (VB 2008 Express & SQL Server 2008 Express)
--------------------------------------------------------------------
いつもご購読ありがとうございます。ADO.NETの基本的なサンプルプログラ
ムをお届けします。

やさしいVB2008 ADO.NET → http://adonetvb.com/index.html
====================================================================
                ■■ 受注伝票エントリー 第7回 ■■

フォームから入力した受注データを、受注ヘッダー表と受注ディテール表に
登録するプログラムを作成します。

フォーム    → http://adonetvb.com/OrderEntry/index.html

テーブル定義  → http://adonetvb.com/OrderEntry/DB.html

バックナンバー → http://adonetvb.com/MailMagazine/index.html

--------------------------------------------------------------------
                          ■ 商品クラス ■

今回は、商品クラスの ClsShohinを実装します。このクラスは、コンストラ
クタの引数に指定した商品コードのレコードを商品マスターから取得し、プ
ロパティから商品名称や販売金額を取得できるようにするクラスです。

まず、基本クラス(基底クラス)ClsShohinBaseに、商品マスター表の選択・
更新・削除処理で共通で使う定数・変数メンバー、商品名称プロパティ、販
売単価プロパティ、商品コードチェックメソッドを実装します。抽象クラス
なので、コンストラクタを実装しません。

ClsShohinは派生クラスとして、コンストラクタと商品コードプロパティを
実装します。コンストラクタでは、販売管理データベースアクセスクラスの、
ClsHanbaiKanriDBIOのGetRowsDataメソッドを呼び出し、

        Dim dbIO As New ClsHanbaiKanriDBIO( _
            TABLE_NAME, KEY_FIELD, sCode)
        Dim dt As DataTable = dbIO.GetRowsData()

として、商品マスター表からレコードを取得します。

それでは、プロジェクトにクラスファイルClsShohin.vbを追加し、
ClsShohinBaseとClsShohinをコーディングします。

--【プログラムソースリスト:ClsShohin.vb】--------------------------
Option Strict On

Imports System.Text.RegularExpressions

'%%%%%%%%%%%%%%% 基本抽象クラス:商品データ %%%%%%%%%%%%%%%%
Public MustInherit Class ClsShohinBase

    '-------------------< 定数メンバー >--------------------
    Protected Const TABLE_NAME As String = "商品マスター表"
    Protected Const KEY_FIELD As String = "商品コード"

    '-------------------< 変数メンバー >--------------------
    Protected sCodeValue As String          ' 商品コード 
    Protected sMeishoValue As String        ' 商品名称
    Protected tankaValue As Integer         ' 販売単価

    ' ● MustInheritなのでコンストラクタを宣言しない

    '-------------------------------------------------------
    ' プロパティ:商品名称
    '-------------------------------------------------------
    Public Property ShohinMeisho() As String

        ' Getプロパティ
        Get
            Return sMeishoValue
        End Get

        ' Setプロパティ
        Set(ByVal sMeisho As String)
            ' 未入力はエラー
            If sMeisho.Length = 0 Then
                Throw New ShohinMeishoException _
                    ("商品名称が未設定")
            Else
                sMeishoValue = sMeisho
            End If
        End Set

    End Property

    '-------------------------------------------------------
    ' プロパティ:販売単価
    '-------------------------------------------------------
    Public Property Tanka() As Integer

        ' Getプロパティ
        Get
            Return tankaValue
        End Get

        ' Setプロパティ
        Set(ByVal tanka As Integer)
            ' 未入力はエラー
            If tanka = Nothing Then
                Throw New ShohinCodeException _
                Throw New HanbaiTankaException _
                    ("販売単価が未入力です")
            End If

            ' 0以下はエラー
            If tanka > 0 Then
                tankaValue = tanka
            Else
                Throw New HanbaiTankaException _
                    ("0円以下の販売単価は設定できません")
            End If
        End Set

    End Property

    '*******************************************************
    ' 機能:商品コードのエラーチェックメソッド
    ' 引数:商品コード
    ' 補足:エラーがあれば例外をスロー
    '*******************************************************
    Protected Sub CheckShohinCode(ByVal sCode As String)

        ' 引数設定チェック
        If sCode.Length = 0 Then
            Throw New ShohinCodeException _
                ("商品コードが未入力です")
        End If

        ' 英数字以外はエラー
        If Not Regex.IsMatch(sCode, "^[0-9a-zA-Z]+$") Then
            ' 英数字以外はエラー
            Throw New ShohinCodeException _
                ("商品コードに英数字以外の文字があります")
        End If

        ' キー値長さチェック(商品コードは5桁)
        If Not sCode.Length = 5 Then
            ' 5桁以外はエラー
            Throw New ShohinCodeException _
                ("商品コードの桁数が正しくありません")
        End If

    End Sub

End Class

'////////////// 派生クラス:商品選択更新削除 ///////////////
Public Class ClsShohin
    Inherits ClsShohinBase

    '=======================================================
    ' 機能:コンストラクタ
    ' 引数:商品コード
    '=======================================================
    Public Sub New(ByVal sCode As String)

        ' 基本クラスのコンストラクタを呼び出す
        MyBase.New()

        ' 商品コードエラーチェック
        CheckShohinCode(sCode)

        ' 商品マスター表からレコード取得
        Dim dbIO As New ClsHanbaiKanriDBIO( _
            TABLE_NAME, KEY_FIELD, sCode)
        Dim dt As DataTable = dbIO.GetRowsData()
        If dt.Rows.Count = 1 Then
            ' レコードがあった時は正常
            sCodeValue = sCode
            ShohinMeisho = CStr(dt.Rows(0)("商品名称"))
            Tanka = CInt(dt.Rows(0)("販売単価"))
        Else
            ' レコードがなかった時は例外スロー
            Throw New ShohinCodeException _
                ("商品マスター表にレコードがありません")
        End If

    End Sub

    '-------------------------------------------------------
    ' プロパティ:商品コード(読取専用)
    '-------------------------------------------------------
    Public ReadOnly Property ShohinCode() As String

        'Getプロパティ
        Get
            Return sCodeValue
        End Get

    End Property

End Class
--------------------------------------------------------------------

クラスClsHanbaiKanriDBIOは、今までは、抽象クラスにしていましたが、以
後、 MustInheritを削除し、具象クラスとします。お手数ですが修正をお願
いします。このクラスに、次の変数メンバー、コンストラクタ、メソッドを
追加します。

--【プログラムソースリスト:ClsHanbaiKanriDBIO.vb】-----------------

Public Class ClsHanbaiKanriDBIO    '【修正】MustInheritを削除

    '--------------------< 変数メンバー >-------------------
    Protected tableNameValue As String   ' 表名
    Protected keyFieldValue As String    ' キー項目
    Protected keyValue As String         ' キー値
    Protected dtValue As DataTable       ' 取得レコード

    '=======================================================
    ' 機能:コンストラクタ
    ' 引数:表名
    ' 引数:キーフィールド
    ' 引数:キー値
    '=======================================================
    Public Sub New(ByVal tableName As String, _
                   ByVal keyField As String, _
                   Optional ByVal keyValue As String = "_")

        ' 最初に基本クラスのコンストラクタを呼び出す
        MyBase.New()

        ' 表からレコード取得
        dtValue = GetKeyData(tableName, keyField, keyValue)
        keyValue = keyValue           ' キー値
        tableNameValue = tableName    ' 表名
        keyFieldValue = keyField      ' キー項目名

    End Sub

    '*******************************************************
    ' 機能:表からレコードを取得するメソッド
    ' 引数:なし
    ' 戻値:表の該当レコード
    '*******************************************************
    Public Function GetRowsData() As DataTable

        Return dtValue

    End Function

    '*******************************************************
    ' 機能:表のキー値のレコードを取得するメソッド
    ' 引数:表名
    ' 引数:キーフィールド名
    ' 引数:主キー値
    ' 戻値:取得したレコード
    '*******************************************************
    Protected Function GetKeyData _
        (ByVal tableName As String, _
         ByVal fieldName As String, _
         ByVal value As String) As DataTable

        Dim retDt As New DataTable()         ' リターン値

        Using con As New SqlConnection
            Using cmd As New SqlCommand
                ' DBを開く
                ClsHanbaiKanriDBIO.OpenDB(con, cmd)

                ' SQL文設定
                cmd.CommandText = _
                    "SELECT * FROM " & tableName & _
                    " WHERE " & fieldName & " = @value"

                ' SQL文の引数設定
                cmd.Parameters.Clear()
                ' 引数の実際のサイズから長さを推論する
                cmd.Parameters.Add _
                    ("@value", SqlDbType.NChar)

                ' SQL文引数に値を設定
                cmd.Parameters("@value").Value = value

                ' 表からレコード取得
                Dim da As New SqlDataAdapter
                da.SelectCommand = cmd
                da.Fill(retDt)

            End Using
        End Using

        ' ◆戻値を設定してリターン
        Return retDt

    End Function

    '--- 以下省略 ---

End Class
--------------------------------------------------------------------

前号でコメントアウトした行(◆◆印)ClsDetailRowBaseクラスの商品コー
ドプロパティを修正します。前号と若干異なります。お手数ですが商品コー
ドプロパティの差替えをお願いします。

--【プログラムソースリスト:ClsJuchuDetail.vb】---------------------

    '-------------------------------------------------------
    ' プロパティ:商品コード
    '-------------------------------------------------------
    Public Property ShohinCode() As String

        ' Getプロパティ
        Get
            Return shohinCodeValue
        End Get

        ' Setプロパティ
        Set(ByVal sCode As String)
            ' 商品インスタンスの生成
            ' 商品コードエラーチェック(エラー時は例外スロー)
            Dim shohin As New ClsShohin(sCode)

            ' 商品コードを変数メンバーにセット
            shohinCodeValue = sCode
            ' 商品名称を変数メンバーにセット
            shohinMeishoValue = shohin.ShohinMeisho
            ' 商品単価を変数メンバーにセット
            juchuTankaValue = shohin.Tanka
        End Set

    End Property
--------------------------------------------------------------------
次号:明細行追加ボタン押下処理と明細行確認ボタン押下処理の実装

本年もご購読ありがとうございました。来年もよろしくお願い申し上げます。

====================================================================
VB.NET データベースプログラミング奮闘記
  発行者:ウェブ実験室(adonet~live.jp ~はあっとマーク)
          http://park5.wakwak.com/~weblab/
--------------------------------------------------------------------
このメールマガジン(マガジンID: 0000128094)は、
インターネットの本屋さん『まぐまぐ』から配信されています。
  http://www.mag2.com/ 

【購読中止の方法】購読の中止は次のホームページからお願い致します。
  http://park5.wakwak.com/~weblab/
  http://www.mag2.com/m/0000128094.htm
--------------------------------------------------------------------
このメールマガジン及び「すぐ使えるADO.NET」「やさしいBV2008 ADO.NET」
などのホームページで公開しているソースプログラム・データの利用により
生じた損害等については、発行者は一切責任を負いません。ソースプログラ
ムの再利用は自由です。著作権は発行者が所有します。
このメールマガジン及び「すぐ使えるADO.NET」「やさしいBV2008 ADO.NET」
などホームページに掲載されている会社名・製品名等は、各社の登録商標ま
たは商標です。
====================================================================