すぐ使えるADO.NET

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

本の紹介

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

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




【第25号】

 第25号(2005.4.25発行)
======================================================================
           ★★ VB.NETデータベースプログラミング奮闘記 ★★
----------------------------------------------------------------------
いつもご購読ありがとうございます。ADO.NETの基本的なプログラミングを中
心に掲載しますので、今後ともよろしくお願い申し上げます。

すぐ使えるADO.NET --> サンプルプログラム満載
                      http://park5.wakwak.com/‾weblab/
======================================================================
         ■■ VB.NETワンポイント:正規表現で文字列チェック ■■

前号では、入力値の数字値チェックに正規表現を使いましたが、今回は、文字
列のエラーチェックを紹介します。RegexクラスのIsMatchメソッドを使います
ので、 Imports System.Text.RegularExpressions 名前空間をインポートして
ください。

◆郵便番号 ---> ^[0-9]{3}¥-?[0-9]{4}$
123-4567または、1234567の入力パターンを正規表現でチェックします。

先頭文字から3桁は0から9なので、^[0-9]{3,3}としますが、{3,3}は{3}と同じ
意味になりますので、^[0-9]{3}とします。4文字目は - があっても無くても
よいので、¥-? とします。- は特殊文字なので、文字の直前に¥を付加します。
? は、その直前の1文字があっても無くてもよいという意味になります。 そし
て、末尾までの4桁数字は、[0-9]{4}$ と表現できます。

これで、パターンのチェックはできますが、存在しない郵便番号もチェックす
るのであれば、郵便番号テーブルを作成して、テーブルに存在するかしないか
のチェックもあったほうが、より良いプログラムになります。

◆全角カタカナ ---> ^[ァ-ー]+$
フリガナチェックをするときに使うと、便利です。

.NET Frameworkでは、正規表現はUnicodeのコード順で決まりますので、
^[ァ-ー]+$ になりますが、ァォィゥェォヰヱヴヵヶー等を除外する場合には、
たとえば、次のように記述すれば、不要なカタカナを除外することができます。
 ^[アイウエオ-ロワン]+$

実際には、コード表で文字を確認しながら、正規表現を作成するほうが、間違
いがないかと思います。

----------------------------------------------------------------------
            ■■ ADO.NETのトランザクション制御 4(完) ■■

トランザクション制御を使って、社員テーブルと権限テーブルに登録するプロ
グラムを作成します。使用するテーブル定義とフォームレイアウトは、第22号
を参照してください。今回は、前号で紹介しなかったDBアクセスクラスのメッ
ソドについて説明します。

◆DBアクセスクラスclsDBIO getAllBumonメソッドは、部門テーブル全レコー
ド取得するメソッドす。dataAdapterオブジェクトのFillメソッドを呼び出し、
全レコードを取得しています。このとき、 DBのオープンとクローズは、内部
で自動的に実行してくれますので、明示的にopenメソッドとcloseメソッドを
呼び出す必要はありません。

◆DBアクセスクラスclsDBIO existKeySyainメソッドは、社員テーブルのキー
値のレコードの有無を調べるメソッドです。キー値のレコード数を調べますの
で、CommandオブジェクトのExecuteScalarメソッドを使います。戻り値がレ
コード件数ですから、その数を調べれて、1であればTrueを、そうでなければ、
Falseを戻り値にセットします。

なお、いずれのメソッドも、エラーが発生すれば、エラーメッセージを引数に
セットして、例外をThrowしています。

それでは、全ソースリストを掲載します。

--【プログラムソースリスト】------------------------------------------

 ■ Form1.vbファイル ■
Public Class Form1
  Inherits System.Windows.Forms.Form

#Region " Windows フォーム デザイナで生成されたコード "
  '自動生成部分省略
#End Region

  '----------<< フォームロード処理 >>----------
  Private Sub Form1_Load _
  (ByVal sender As System.Object, ByVal e As System.EventArgs) _
  Handles MyBase.Load

    Try
      Dim oDBIO As New clsDBIO()
      Dim oDataTable As DataTable

      '部門テーブルの全レコードを取得する
      oDataTable = oDBIO.getAllBumon()
      'コンボボックスに部門名を表示できるようにする
      Me.cmbBumonMei.DisplayMember = "部門名"
      '部門名に対応した部門コードを SelectdValueで取得できるようにする
      Me.cmbBumonMei.ValueMember = "部門コード"
      'コンボボックスに部門テーブルデータを連結する
      Me.cmbBumonMei.DataSource = oDataTable

    Catch oExcept As Exception
      '例外が発生した時の処理
      MessageBox.Show(oExcept.ToString, "フォームロード例外発生")

    End Try

  End Sub

  '----------<< コンボボックスの選択値が変更された場合 >>----------
  Private Sub cmbBumonMei_SelectedIndexChanged _
  (ByVal sender As System.Object, ByVal e As System.EventArgs) _
  Handles cmbBumonMei.SelectedIndexChanged

    '選択した部門コードをラベルに表示
    If Me.cmbBumonMei.SelectedIndex <> -1 Then
      Me.lblBumonCode.Text = CStr(Me.cmbBumonMei.SelectedValue)
    End If

  End Sub

  '----------<< クリアボタン処理 >>----------
  Private Sub btnClear_Click _
  (ByVal sender As System.Object, ByVal e As System.EventArgs) _
  Handles btnClear.Click

    Me.txtSyainCode.Text = ""
    Me.txtSyainSimei.Text = ""
    Me.txtSyainKana.Text = ""
    Me.txtPassWord.Text = ""
    Me.cmbBumonMei.SelectedIndex = 0
    Me.txtSyainCode.Focus()

  End Sub

  '-----<< 登録ボタン処理(社員テーブルにレコード追加) >>-----
  Private Sub btnInsert_Click _
  (ByVal sender As System.Object, ByVal e As System.EventArgs) _
  Handles btnInsert.Click

    Try
      Dim oDBIO As New clsDBIO()
      Dim oSyain As New clsSyainToroku()

      '入力項目のエラーチェック
      oSyain.p社員コード = Me.txtSyainCode.Text
      oSyain.p社員氏名 = Me.txtSyainSimei.Text
      oSyain.p社員カナ = Me.txtSyainKana.Text
      oSyain.p部門コード = Me.lblBumonCode.Text
      oSyain.pパスワード = Me.txtPassWord.Text

      '社員テーブルにレコード追加
      Dim recCount As Integer

      recCount = oDBIO.addSyainKengen(oSyain)
      If recCount = 1 Then
        MessageBox.Show("登録しました", "登録完了")
      Else
        MessageBox.Show("登録に失敗しました", "登録失敗")
      End If

    Catch oExcept As clsException
      '例外が発生した時の処理
      MessageBox.Show(oExcept.Message, "エラー発生")

    Catch oExcept As Exception
      '例外が発生した時の処理
      MessageBox.Show(oExcept.ToString, "例外発生")

    End Try

  End Sub

End Class

 ■ clsSyainToroku.vbファイル ■
Imports System.Text.RegularExpressions

Public Class clsSyainToroku

  '---------------<< 変数 >>---------------
  Private m社員コード As String
  Private m社員氏名 As String
  Private m社員カナ As String
  Private m部門コード As String
  Private mパスワード As String
  Private mDBIO As clsDBIO

  '---------------<< コンストラクタ >>---------------
  Public Sub New()

    '必ず1行目に記述(コンストラクタに引数のない場合は省略可能)
    MyBase.New()

    Try
      'DBアクセスオブジェクト生成
      mDBIO = New clsDBIO()

    Catch oExcept As Exception
      Throw New Exception _
      ("clsDBIOのコンストラクタで例外発生. " + oExcept.ToString)

    End Try

  End Sub

  '---------------<< プロパティ >>---------------
  '◆社員コードプロパティ
  Public Property p社員コード() As String

    '◇Getプロパティ
    Get
      Return m社員コード
    End Get

    '◇Setプロパティ
    Set(ByVal Value As String)
      '********** 入力値エラーチェック **********
      '数字以外はエラー
      If Not Regex.IsMatch(Value, "^[0-9]+$") Then
        Throw New clsException("社員コードは数字で入力してください")
      End If

      '5桁以外はエラー
      If Not Value.Length = 5 Then
        Throw New clsException("社員コードは5桁で入力してください")
      End If

      '社員マスタにあればエラー
      If mDBIO.existKeySyain(Value) = True Then
        Throw New clsException("この社員コードは登録済です")
      End If

      m社員コード = Value
    End Set

  End Property

  '◆社員氏名プロパティ
  Public Property p社員氏名() As String

    '◇Getプロパティ
    Get
      Return m社員氏名
    End Get

    '◇Setプロパティ
    Set(ByVal Value As String)
      '********** 入力値エラーチェック **********
      '未入力はエラー
      If Value = "" Then
        Throw New clsException("社員氏名を入力してください")
      End If

      m社員氏名 = Value
    End Set

  End Property

  '◆社員カナプロパティ
  Public Property p社員カナ() As String

    '◇Getプロパティ
    Get
      Return m社員カナ
    End Get

    '◇Setプロパティ
    Set(ByVal Value As String)
      '********** 入力値エラーチェック **********
      '全角カタカナチェック
      If Not Regex.IsMatch(Value, "^[ァ-ー]+$") Then
        Throw New clsException _
        ("社員カナを全角カタカナで入力してください")
      End If

      m社員カナ = Value
    End Set

  End Property

  '◆部門コードプロパティ
  Public Property p部門コード() As String

    '◇Getプロパティ
    Get
      Return m部門コード
    End Get

    '◇Setプロパティ
    Set(ByVal Value As String)
      'コンボボックスから選んだ部門コードをセット
      m部門コード = Value
    End Set

  End Property

  '◆パスワードプロパティ
  Public Property pパスワード() As String

    '◇Getプロパティ
    Get
      Return mパスワード
    End Get

    '◇Setプロパティ
    Set(ByVal Value As String)
      '********** 入力値エラーチェック **********
      '英数字以外はエラー
      If Not Regex.IsMatch(Value, "^[0-9A-Za-z]+$") Then
        Throw New clsException("パスワードは英数字で入力してください")
      End If
      '5桁未満または15桁超はエラー
      If Value.Length < 5 Or Value.Length > 15 Then
        Throw New clsException("パスワードの文字数が範囲外です")
      End If

      mパスワード = Value
    End Set

  End Property

End Class

 ■ clsDBIO.vbファイル ■
Imports System.Data.OleDb

Public Class clsDBIO
  '--------------------< メンバ:変数 >--------------------
  'コネクション
  Private mConn As OleDbConnection
  'コマンド
  Private mCommand As OleDbCommand

  '=========================================================
  ' 機能:コンストラクタ
  ' 引数:なし
  '=========================================================
  Public Sub New()

    Try
      'DB接続文字列の設定
      mConn = New OleDbConnection()
      mConn.ConnectionString = _
      "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" _
      & Application.StartupPath & "¥sample.mdb"

      'コネクションオブジェクトの設定
      mCommand = New OleDbCommand()
      mCommand.Connection = mConn

    Catch oExcept As Exception
      Throw New Exception _
      ("clsDBIOのコンストラクタで例外発生. " + oExcept.ToString)

    End Try

  End Sub

  '=========================================================
  ' 機能:部門テーブル全レコード取得メソッド
  ' 引数:なし
  ' 戻値:DataTable型 取得したテーブルレコード行コレクション
  '=========================================================
  Public Function getAllBumon() As DataTable

    Dim retDataTable As New DataTable()         'リターン値
    Dim dataAdapter As New OleDbDataAdapter()

    Try
      'SQL文設定
      mCommand.CommandText = _
      "SELECT 部門コード, 部門名 FROM 部門テーブル"

      'テーブルからレコード取得
      dataAdapter.SelectCommand = mCommand
      dataAdapter.Fill(retDataTable)

    Catch oExcept As Exception
      Throw New Exception _
      ("clsTableSyainのgetAllRecで例外発生. " + oExcept.ToString)

    End Try

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

  End Function

  '=========================================================
  ' 機能:社員テーブルのキー値レコードの有無を調べるメソッド
  ' 引数:キー値
  ' 戻値:ある-->True、ない-->False
  '=========================================================
  Public Function existKeySyain(ByVal parKey As String) As Boolean

    Dim retBool As Boolean                      'リターン値

    Try
      'SQL文設定
      mCommand.CommandText = _
      "SELECT COUNT(*) FROM 社員テーブル WHERE 社員コード = @Key"

      '***** SQL文の引数設定 *****
      mCommand.Parameters.Clear()
      mCommand.Parameters.Add( _
      New OleDbParameter("@key", OleDbType.Char, 5))

      '----------< コマンドパラメータに値を設定 >----------
      mCommand.Parameters("@key").Value = parKey   'キー値の設定

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

      'レコード件数取得
      Dim Count As Integer = mCommand.ExecuteScalar()

      '----------< 戻値を設定 >----------
      If Count = 1 Then
        retBool = True
      Else
        retBool = False
      End If

    Catch oExcept As Exception
      Throw New Exception _
      ("clsTableSyainのexistKeyRecで例外発生. " + oExcept.ToString)

    Finally
      'DB接続を閉じる
      If Not mConn Is Nothing Then
        If mConn.State = ConnectionState.Open Then
          mConn.Close()
        End If
      End If

    End Try

    '◆リターン
    Return retBool

  End Function

  '=========================================================
  ' 機能:社員テーブルと権限テーブルに1レコードを追加する
  ' 引数:社員登録クラスのオブジェクト
  ' 戻値:Integer型 正常にレコードが追加された時 ---> 1
  ' 備考:レコードを追加できなかった時は、例外をスロー
  '=========================================================
  Public Function addSyainKengen(ByVal parSyain As clsSyainToroku) _
  As Integer

    Dim retInt As Integer = 0             'リターン値:追加レコード数
    Dim oTrans As OleDbTransaction

    Try
      '----------<< 1.社員テーブルに1レコードを追加 >>----------
      '***** SQL文の設定 *****
      mCommand.CommandText = _
      "INSERT INTO " & _
      "社員テーブル(社員コード, 社員氏名, 社員カナ, 部門コード, 更新日時) " & _
      "VALUES(@sCode, @sSimei, @sKana, @bumonCode, @kosinDate)"

      '***** SQL文の引数設定 *****
      mCommand.Parameters.Clear()
      mCommand.Parameters.Add _
      (New OleDbParameter("@sCode", OleDbType.Char, 5))
      mCommand.Parameters.Add _
      (New OleDbParameter("@sSimei", OleDbType.Char, 20))
      mCommand.Parameters.Add _
      (New OleDbParameter("@sKana", OleDbType.Char, 40))
      mCommand.Parameters.Add _
      (New OleDbParameter("@bumonCode", OleDbType.Char, 3))
      mCommand.Parameters.Add _
      (New OleDbParameter("@kosinDate", OleDbType.Date))

      '***** 引数に値を設定 *****
      mCommand.Parameters("@sCode").Value = parSyain.p社員コード
      mCommand.Parameters("@sSimei").Value = parSyain.p社員氏名
      mCommand.Parameters("@sKana").Value = parSyain.p社員カナ
      mCommand.Parameters("@bumonCode").Value = parSyain.p部門コード
      mCommand.Parameters("@kosinDate").Value = Now()

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

      '***** トランザクション開始 *****
      oTrans = mConn.BeginTransaction
      mCommand.Transaction = oTrans

      '***** データベースの更新を実行  *****
      retInt = mCommand.ExecuteNonQuery()

      '◆レコード追加に失敗したらロールバックして例外スロー
      If Not retInt = 1 Then
        Throw New clsException _
        ("社員テーブル:レコード追加処理が失敗しました。")
      End If

      '----------<< 2.権限テーブルに1レコードを追加 >>----------
      '***** SQL文の設定 *****
      mCommand.CommandText = _
      "INSERT INTO 権限テーブル(社員コード, パスワード, 更新日時) " & _
      "VALUES(@sCode, @passWord, @kosinDate)"

      '***** SQL文の引数設定 *****
      mCommand.Parameters.Clear()
      mCommand.Parameters.Add _
      (New OleDbParameter("@sCode", OleDbType.Char, 5))
      mCommand.Parameters.Add _
      (New OleDbParameter("@passWord", OleDbType.Char, 15))
      mCommand.Parameters.Add _
      (New OleDbParameter("@kosinDate", OleDbType.Date))

      '***** 引数に値を設定 *****
      mCommand.Parameters("@sCode").Value = parSyain.p社員コード
      mCommand.Parameters("@passWord").Value = parSyain.pパスワード
      mCommand.Parameters("@kosinDate").Value = Now()

      '***** データベースの更新を実行  *****
      retInt = mCommand.ExecuteNonQuery()

      '◆レコード追加に失敗したらロールバックして例外スロー
      If Not retInt = 1 Then
        Throw New clsException _
        ("社員テーブル:レコード追加処理が失敗しました。")
      End If

      '***** トランザクション完了 *****
      oTrans.Commit()

    Catch oExcept As clsException
      '◆レコード追加に失敗したらロールバックして例外スロー
      oTrans.Rollback()
      Throw New clsException(oExcept.Message)

    Catch oExcept As Exception
      '◆レコード追加に失敗したらロールバックして例外スロー
      oTrans.Rollback()
      Throw New Exception _
      ("clsTableSyainのaddRecで例外発生. " + oExcept.ToString)

    Finally
      'DB接続を閉じる
      If Not mConn Is Nothing Then
        If mConn.State = ConnectionState.Open Then
          mConn.Close()
        End If
      End If

    End Try

    '◆正常終了リターン
    Return retInt

  End Function

End Class

 ■ clsException.vbファイル ■
Public Class clsException
  Inherits ApplicationException

  Public Sub New(ByVal errorMessage As String)
    MyBase.New(errorMessage)
  End Sub

End Class

----------------------------------------------------------------------
               ■■ 次号予告 第26号(5月18日発行予定) ■■
1. VB.NETワンポイント
2. ADO.NET:テキストボックスをDBテーブルのレコードにバインドする
======================================================================
VB.NET データベースプログラミング奮闘記
          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.