すぐ使えるADO.NET

【Visual BasicによるADO.NETデータベースプログラミング】

本の紹介

バックナンバー:VB.NETデータベースプログラミング

ADO.NETの基本的なプログラミングを中心に、すぐ使えるサンプルプログラム満載です。




【第14号】

 第14号(2004.9.13発行)
======================================================================
           ★★ VB.NETデータベースプログラミング奮闘記 ★★

----------------------------------------------------------------------
ADO.NETの基本的なプログラミングを中心に掲載します。
末永くご購読の程よろしくお願い申し上げます。

すぐ使えるADO.NET --> サンプルプログラム満載
                      http://park5.wakwak.com/‾weblab/
======================================================================
                        -----【目次】-----

1. VB.NETワンポイント:For Each … Next
2. 部門単位で自動連番を生成するクラスの作成 5(完) 全ソースリスト掲載

----------------------------------------------------------------------
           ■■ VB.NETワンポイント:For Each … Next ■■

今回は、For Each … Nextを紹介します。For Each … Nextを使えば、前号
で紹介したハッシュテーブル(連想配列)の値をすべて取得することができます。

ハッシュテーブルへ項目を追加します。

  Dim htblGengo As New Hashtable()
  htblGengo.Add("M", "明治")
  htblGengo.Add("T", "大正")
  htblGengo.Add("S", "昭和")
  htblGengo.Add("H", "平成")

キーが既存であれば、前号で紹介したように、CStr(htblGengo("M")とすれば、
個別に、値を取得することができます。
For Each … Nextを使えば、1つずつエレメントにアクセスしなくても、すべ
てのキーと値を取得することができます。

ハッシュテーブル内の各要素はSystem.Collections.DictionaryEntryオブジェ
クトとして取り扱われますので、キーと値は、パブリックプロパティのkeyと
valueでアクセスすることができます。ただし期待した順にアクセスできる保証
はありません。実際にテストした結果は、大正、平成、昭和、明治の順でした。

  Dim colGengo As System.Collections.DictionaryEntry
  Dim strKey As String
  Dim strValue As String

  For Each colGengo In htblGengo
    strKey = CStr(colGengo.Key)
    strValue = CStr(colGengo.Value)
    Console.WriteLine("キー= " + strKey)     '結果確認
    Console.WriteLine("値 = " + strValue)   '結果確認
  Next colGengo

もうひとつ配列へのアクセス(変更は不可)を紹介します。For Each … Next
で配列を反復処理し、値の合計を求めています。

  Dim iAry() As Integer = {1, 4, 5, 8, 10, 12, 15}
  Dim iNum As Integer
  Dim iSum As Integer = 0

  For Each iNum In iAry
    iSum += iNum
  Next iNum

  Console.WriteLine("合計= " + CStr(iSum))   '結果確認

----------------------------------------------------------------------
       ■■ 部門単位で自動連番を生成するクラスの作成 5(完) ■■

前号からの続きで、自動連番を生成するクラスclsSequenceNumを構築します。
今回で完成します。なお、連番生成テーブルは次のように定義しています。

key フィールド名   データ型    サイズ  値要求  空文字列の許可
----------------------------------------------------------------
◎ 部門コード  テキスト型    3 はい  いいえ
− 連番     数値型    整数型 はい  −
− 更新日時   日付/時刻型   − はい  −

今回は、連番の初期値を自由に設定できるように改良します。

今までのコンストラクタは、部門コードのみを引数に指定し、連番の開始値を、
1に固定していましたが、引数に連番の初期値を指定できるコンストラクタを
追加して、開始番号を自由に設定できるようにします。

まず、クラスに内部変数mRenbanを追加します。既定の初期値として1を設定
しておきます。こうしておけば、引数に連番の初期値を指定していない時は、
新規登録した部門の連番開始値は、自動的に1になります。

  Private mRenban As Integer = 1

追加するコンストラクタは、初期値が0以上100000未満のチェックをして、
範囲外ならば、例外をスローします。未登録の部門であれば、引数の部門コー
ドと連番を使って、createSequenceNumメソッドで、連番生成テーブルに1レ
コード追加します。登録済の部門コードに連番初期値を引数に指定した場合は、
引数の連番初期値で上書きせず、例外をスローします。

  If parRenban >= 0 And parRenban < 100000 Then
    '部門コードのレコードがなければ、1レコード追加
    If Me.existBumon = False Then
      Me.createSequenceNum()
    Else
     '部門コードのレコードがあれば、例外をスロー
     Throw New Exception(".....")
    End If
  Else
    '初期値が範囲外ならば、例外をスロー
    Throw New Exception(".....")
  End If

今回の見直しで、修正したメソッドがありますので説明します。修正箇所には
ソースリストにコメントとして、★印をつけました。

getSequenceNumメソッド
1:桁数チェックを追加し、連番が6桁になったら例外をスローするように修正
2:部門コードと5桁連番を連結し、8桁文字列作成時に使う連番の値を、
   renban +1 から renban に変更

createSequenceNumメソッド
1:SQL文パラメータ@bumonCodeに、mBumonCodeを設定するように修正
    oCommand.Parameters("@bumonCode").Value = mBumonCode

長くなりますが、連番生成クラスの全ソースリストを掲載します。
--【プログラムソースリスト】------------------------------------------
Imports System.Data.OleDb  '★漏れていました。申し訳ありませんでした。

Public Class clsSequenceNum

  '部門コード
  Private mBumonCode As String
  '連番
  Private mRenban As Integer = 1   '★追加

  '------------------------------------------------------------
  ' 機能:コンストラクタ
  ' 引数:in 部門コード
  '------------------------------------------------------------
  Sub New(ByVal parBumonCode As String)

    MyBase.New()
    Me.mBumonCode = parBumonCode

    '部門コードのレコードがなければ、1レコード追加
    If Me.existBumon = False Then
      Me.createSequenceNum()
    End If

  End Sub

  '★追加コンストラクタ
  '------------------------------------------------------------
  ' 機能:コンストラクタ
  ' 引数:in 部門コード
  ' 引数:in 初期設定の連番5桁
  '------------------------------------------------------------
  Sub New(ByVal parBumonCode As String, ByVal parRenban As Integer)

    MyBase.New()
    Me.mBumonCode = parBumonCode
    Me.mRenban = parRenban

    If parRenban >= 0 And parRenban < 100000 Then
      '部門コードのレコードがなければ、1レコード追加
      If Me.existBumon = False Then
        Me.createSequenceNum()
      Else
        '部門コードのレコードがあれば、例外をスロー
        Throw New Exception("部門コード" + mBumonCode + _
        "の連番は設定されています")
      End If
    Else
      '初期値が範囲外ならば、例外をスロー
      Throw New Exception("部門コード" + mBumonCode + _
      "連番初期値は0-99999を設定してください")
    End If

  End Sub

  '------------------------------------------------------------
  ' 機能:連番生成テーブルから連番を取得する関数
  ' 引数:なし
  ' 戻値:8桁文字列ならば、取得成功
  '       ""(長さ0の文字列)ならば、取得失敗
  '------------------------------------------------------------
  Public Function getSequenceNum() As String

    Dim oConn As New OleDbConnection()
    Dim oCommand As New OleDbCommand()
    Dim oDataReader As OleDbDataReader
    Dim renban As Integer

    Try
      'DB接続文字列の設定
      '注:プロジェクトファイルホルダの下にあるbinホルダにMDBを置く
      oConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + _
      " Data Source=" + Application.StartupPath + "¥sample.mdb"

      'コネクションの設定
      oCommand.Connection = oConn

      'DB接続を開く
      oConn.Open()

      'SQL文の設定
      Const strSelect As String = _
      "SELECT 連番 FROM 連番生成テーブル WHERE 部門コード = @bumonCode"
      oCommand.CommandText = strSelect

      'SQL文パラメータの設定
      oCommand.Parameters.Add _
      (New OleDbParameter("@bumonCode", OleDbType.Char, 3))
      oCommand.Parameters("@bumonCode").Value = mBumonCode

      '取得するレコードが1件の時は、
      'パラメータにCommandBehavior.SingleRowをセット
      oDataReader = oCommand.ExecuteReader(CommandBehavior.SingleRow)
      If oDataReader.Read() Then
        '---------- レコードが取得できた時の処理 ---------
        '連番セット
        renban = CInt(oDataReader("連番"))

        'データリーダを閉じる
        If Not oDataReader Is Nothing Then
          oDataReader.Close()
        End If

        '8桁連番生成処理
        If renban < 100000 Then    '★連番の範囲チェック追加
          '連番を+1してレコードを更新
          Const strUpdate As String = "UPDATE 連番生成テーブル " + _
          "SET 連番=@nextNum " + _
          "WHERE 部門コード = @bumonCode AND 連番=@nowNum"

          'SQL文の設定
          oCommand.CommandText = strUpdate

          'SQL文パラメータの設定
          oCommand.Parameters.Clear()
          oCommand.Parameters.Add _
            (New OleDbParameter("@nextNum", OleDbType.Integer))
          oCommand.Parameters("@nextNum").Value = renban + 1
          oCommand.Parameters.Add _
            (New OleDbParameter("@bumonCode", OleDbType.Char, 3))
          oCommand.Parameters("@bumonCode").Value = mBumonCode
          oCommand.Parameters.Add _
            (New OleDbParameter("@nowNum", OleDbType.Integer))
          oCommand.Parameters("@nowNum").Value = renban

          '連番生成テーブル更新SQL文実行
          Dim count As Integer
          count = oCommand.ExecuteNonQuery()

          If count = 1 Then
            '連番が6桁になったら、例外をスロー
            If renban < 100000 Then
              '部門コードと5桁連番を連結した8桁文字列を作成
              '★ renban +1 --> renban に修正
              Dim strNum As String = _
                String.Format("{0,3:000}", mBumonCode) + _
                String.Format("{0,5:00000}", renban)  '★
              '戻り値に作成した8桁文字列をセットしてリターン
              Return strNum
            Else
              Throw New Exception("連番が100000に達しました")
            End If
          Else
            '---------- 更新処理エラー時 ----------
            '戻り値に""をセットしてリターン
            Return ""
          End If
        Else
          '★連番が6桁になったら、例外をスロー
          Throw New Exception("連番が100000に達しました")  '★
        End If
      Else
        '----- レコードが取得できなかった時の処理 -----
        '戻り値に""をセットしてリターン
        Return ""
      End If

    Catch oExcept As Exception
      '例外が発生した時の処理
      Throw New Exception(oExcept.ToString)

    Finally
      'DB接続を閉じる
      If Not oConn Is Nothing Then
        oConn.Close()
      End If
    End Try

  End Function

  '------------------------------------------------------------
  ' 機能:プロパティの部門コードのレコードが連番生成テーブルに
  '       存在するか否かを調べるメソッド
  ' 引数:なし
  ' 戻値:True  --> 存在する.  False --> 存在しない
  '------------------------------------------------------------
  Private Function existBumon() As Boolean

    Dim oConn As New OleDbConnection()
    Dim oCommand As New OleDbCommand()

    Try
      'DB接続文字列の設定
      '注:プロジェクトファイルホルダの下にあるbinホルダにMDBを置く
      oConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + _
      " Data Source=" + Application.StartupPath + "¥sample.mdb"

      'コネクションの設定
      oCommand.Connection = oConn

      'DB接続を開く
      oConn.Open()

      'SQL文の設定
      Const strSelect As String = _
      "SELECT COUNT(*) FROM 連番生成テーブル " + _
      "WHERE 部門コード = @bumonCode"
      oCommand.CommandText = strSelect

      'SQL文パラメータの設定
      oCommand.Parameters.Add( _
      New OleDbParameter("@bumonCode", OleDbType.Char, 3))
      oCommand.Parameters("@bumonCode").Value = Me.mBumonCode

      '連番生成テーブルから該当部門コードのレコード数読込
      Dim recCount As Integer
      recCount = CInt(oCommand.ExecuteScalar())
      If recCount = 1 Then
        'レコードが存在する時の処理
        Return True
      Else
        'レコードが存在しない時の処理
        Return False
      End If

    Catch oExcept As Exception
      '例外が発生した時の処理
      Throw New clsDBIOException(oExcept.ToString)

    Finally
      'DB接続を閉じる
      If Not oConn Is Nothing Then
        oConn.Close()
      End If
    End Try

  End Function

  '------------------------------------------------------------
  ' 機能:連番生成テーブルに1レコードを登録するメソッド
  ' 引数:なし
  ' 戻値:True  --> 登録成功.  False --> 登録失敗
  '------------------------------------------------------------
  Private Function createSequenceNum() As Boolean

    Const strInsertSyain As String = _
    "INSERT INTO 連番生成テーブル (部門コード, 連番, 更新日時) " + _
    "VALUES(@bumonCode, @renban, @kosinNitizi)"

    Dim oConn As New OleDbConnection()
    Dim oCommand As New OleDbCommand()

    Try
      oConn = New OleDbConnection()
      'DB接続文字列の設定
      '注:プロジェクトファイルホルダの下にあるbinホルダにMDBを置く
      oConn.ConnectionString = _
      "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + _
      Application.StartupPath + "¥sample.mdb"

      'コネクションの設定
      oCommand.Connection = oConn

      'DB接続を開く
      oConn.Open()

      'SQL文の設定
      oCommand.CommandText = strInsertSyain

      'パラメータの設定
      oCommand.Parameters.Add( _
      New OleDbParameter("@bumonCode", OleDbType.Char, 3))
      oCommand.Parameters("@bumonCode").Value = Me.mBumonCode

      oCommand.Parameters.Add( _
      New OleDbParameter("@renban", OleDbType.Integer))
      '★パラメータに設定する値を 0 --> Me.mRenban に修正
      oCommand.Parameters("@renban").Value = Me.mRenban   '★

      oCommand.Parameters.Add( _
      New OleDbParameter("@kosinNitizi", OleDbType.Date))
      oCommand.Parameters("@kosinNitizi").Value = Now()

      '自動連番生成テーブルレコード追加処理実行
      Dim count As Integer = oCommand.ExecuteNonQuery()
      If count = 1 Then
        '追加成功:戻り値にTrueを設定してリターン
        Return True
      Else
        '追加失敗:戻り値にFalseを設定してリターン
        Return False
      End If

    Catch oExcept As Exception
      '例外が発生した時の処理
      Throw New clsDBIOException(oExcept.ToString)

    Finally
      'DB接続を閉じる
      If Not oConn Is Nothing Then
        oConn.Close()
      End If

    End Try

  End Function

End Class

----------------------------------------------------------------------
            ■■ 次号予告 第15号(9月30日頃発行予定) ■■

1. VB.NETワンポイント
2. EXCELファイルを読み込んで、ラベルコントロールに表示する

======================================================================
VB.NET データベースプログラミング奮闘記    第14号(2004.9.13)
          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」ホームページで公開してい
るソースプログラム・データの利用により生じた損害等については、発行者は
一切責任を負いません。
ソースプログラムの再利用は自由です。著作権は発行者が所有します。
このメールマガジン及び、「すぐ使えるADO.NET」ホームページに掲載されて
いる会社名・製品名等は、各社の登録商標または商標です。
======================================================================

Copyright© すぐ使えるADO.NET. All rights reserved.