すぐ使えるADO.NET

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

本の紹介

バックナンバー【第60号】

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




【第60号】

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

すぐ使えるADO.NET --> http://park5.wakwak.com/‾weblab/
======================================================================
                  ■■ 社員テーブルに追加する 3 ■■

社員コード、社員氏名、カナ名、部署コードを入力して、追加ボタンをクリッ
クすると、入力したデータのエラーチェックをして、エラーが無ければ、社員
テーブルに1レコード追加します。接続文字列は、app.configに登録しておき
ます。

【sampleデータベースの社員テーブル】
----------------------------------------------------------------------
key  列 名   データ型    nullを許容  備 考
----------------------------------------------------------------------
○ 社員コード  nchar(5)    許容しない 英数字のみ
− 社員氏名   nvarchar(20)  許容しない
− 社員カナ   nvarchar(40)  許容しない
− 部署コード  nchar(4)    許容しない
− 更新日時   datetime    許容しない
----------------------------------------------------------------------

【sampleデータベースの部署テーブル】
----------------------------------------------------------------------
key  列 名   データ型    nullを許容  備 考
----------------------------------------------------------------------
○ 部署コード  nchar(4)    許容しない 英数字のみ
− 部署名    nvarchar(20)  許容しない
− 更新日時   datetime    許容しない
----------------------------------------------------------------------

コンボボックスのDropDownStyleプロパティは、DropDownListを選択して、テ
キストボックス部分を入力できないように設定します。
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ 社員テーブル追加                _□×┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃  Label1    TxtShainCode
┃┌―――――┐ ┌―――――┐
┃│社員コード│ │     │
┃└―――――┘ └―――――┘
┃  Label2    TxtShainShimei
┃┌―――――┐ ┌――――――――┐
┃│社員氏名 │ │        │
┃└―――――┘ └――――――――┘
┃  Label3    TxtShainKana
┃┌―――――┐ ┌――――――――――――――┐
┃│社員カナ │ │              │
┃└―――――┘ └――――――――――――――┘
┃  Label4    CboBusho
┃┌―――――┐ ┌――――――――┐
┃│部署コード│ │      │▼│
┃└―――――┘ └――――――――┘
┃ BtnInsert    BtnClear
┃┌――――┐  ┌―――――┐
┃│ 追加 │  │ クリア │
┃└――――┘  └―――――┘
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

----------------------------------------------------------------------
                     ■■ フォームロード処理 ■■

この処理では、部署名をコンボボックスに表示して、選択した部署名に対応す
る部署コードを取得できるようにします。

前号のClsBushoTableIOクラスの全レコードを取得する GetAllDataメソッドを
呼出して、その返値を、CboBushoコンボボックスのDataSourceにセット後、取
得した部署テーブルデータと連結します。

次に、表示したい列名を、DisplayMemberプロパティに、取得したい部署コー
ドの列名を、ValueMemberプロパティにセットします。部署コードは、
SelectdValueプロパティから取得できます。

--【プログラムソースリスト(ファイル名:FormInsert59.vb)】--------
  Private Sub FormInsert59_Load _
  (ByVal sender As System.Object, ByVal e As System.EventArgs) _
  Handles MyBase.Load

    Try
      Dim bushoTableIO As New ClsBushoTableIO
      Dim dt As DataTable

      '部署テーブルの全レコードを取得する
      dt = bushoTableIO.GetAllData _
      (New String() {"部署コード", "部署名"}, "部署コード", True)
      'コンボボックスに部署名を表示できるようにする
      Me.CboBushoMei.DisplayMember = "部署名"
      '部署名に対応した部署コードを SelectdValueで取得できるようにする
      Me.CboBushoMei.ValueMember = "部署コード"
      'コンボボックスに部署テーブルデータを連結する
      Me.CboBushoMei.DataSource = dt

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

    End Try

  End Sub

----------------------------------------------------------------------
                   ■■ 追加ボタンクリック処理 ■■

主に画面制御処理に専念し、エラーチェックやデータベースアクセスは、ク
ラスメソッドを呼び出す構造にします。

まず、社員テーブルの列情報を取込んだ1行分を生成するcreateDataRow
メソッドを呼出して、返値のDataRowインスタンスに入力値をセットします。

次に、この DataRowインスタンスを引数に指定して、clsInsertShainインス
タンスを生成します。clsInsertShainクラスでは、入力値をエラーチェック
して、その値を保存します。

もしエラーがあれば、独自の例外をスローします。この例外をフォームクラ
スでキャッチし、エラーメッセージやフォーカス処理などをできるようにし
ます。

エラーがなければ、ClsInsertShainインスタンスを引数に指定して、
ClsShainTableIOクラスの insertRecordメソッドを呼出して、社員テーブル
に1レコードを追加します。

--【プログラムソースリスト(ファイル名:FormInsert59.vb)】--------

    '----------<< 追加ボタンクリック処理 >>----------
    Private Sub BtnInsert_Click(ByVal sender As System.Object, _
                                ByVal e As System.EventArgs) _
                                Handles BtnInsert.Click

        Try

            Dim shain As DataRow
            Dim dbIO As New ClsShainTableIO()

            shain = dbIO.createDataRow()

            shain("社員コード") = Me.TxtShainCode.Text
            shain("社員氏名") = Me.TxtShainShimei.Text
            shain("社員カナ") = Me.TxtShainKana.Text
            shain("部署コード") = Me.CboBushoMei.SelectedValue

            dbIO.insertRecord(New ClsInsertShain(shain))

            'フォーム初期設定
            Me.ClearForm()

        Catch oExcept As myShainCodeException
            '社員コード例外が発生した時の処理
            MessageBox.Show(oExcept.Message, "社員コード入力エラー")
            Me.TxtShainCode.Focus()

        Catch oExcept As myShainSimeiException
            '社員氏名例外が発生した時の処理
            MessageBox.Show(oExcept.Message, "社員氏名入力エラー")
            Me.TxtShainShimei.Focus()

        Catch oExcept As myShainKanaException
            '社員カナ例外が発生した時の処理
            MessageBox.Show(oExcept.Message, "社員カナ入力エラー")
            Me.TxtShainKana.Focus()

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

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

        End Try

    End Sub

    '----------<< フォーム初期設定処理 >>----------
    Private Sub ClearForm()

        Me.TxtShainCode.Text = ""
        Me.TxtShainShimei.Text = ""
        Me.TxtShainKana.Text = ""
        Me.CboBushoMei.SelectedIndex = 0
        Me.TxtShainCode.Focus()

    End Sub

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

        'フォーム初期設定
        Me.ClearForm()

    End Sub


--【プログラムソースリスト(ファイル名:ClsShainTableIO.vb)】--------
  '*******************************************************************
  ' 機能:社員テーブル対応の1行を生成するメソッド
  ' 引数:なし
  ' 返値:DataRow型:生成した1行分
  '******1*********2*********3*********4*********5**********6*********
  Public Overloads Function createDataRow() As DataRow

    Dim retDataRow As DataRow                 'リターン値

    Try
      retDataRow = MyBase.createDataRow("社員テーブル", "社員コード")

    Catch ex As Exception
      '例外が発生したら、例外をスロー
      Throw New Exception("例外発生:" & ex.ToString)

    End Try

    '◆リターン
    Return retDataRow

  End Function


--【プログラムソースリスト(ファイル名:ClsSampleDBIO.vb)】----------
  '*******************************************************************
  ' 機能:テーブル対応の1行を生成するメソッド
  ' 引数:String型:テーブル名
  ' 引数:String型:キーの列名
  ' 返値:DataRow型:生成した1行分
  '******1*********2*********3*********4*********5**********6*********
  Public Function createDataRow(ByVal TableName As String, _
                                ByVal KeyField As String) As DataRow

    Dim retDataRow As DataRow                 'リターン値

    Try

      Dim dt As DataTable

      'データテーブルに列情報を取込むために、レコードを取得するが、
      '取得できなくても問題ないので、第三引数のキー値は何でも良い
      '便宜的にアンダースコアを設定
      dt = Me.GetKeyData(TableName, KeyField, "_")
      retDataRow = dt.NewRow

    Catch ex As Exception
      '例外が発生したら、例外をスロー
      Throw New Exception("例外発生:" & ex.ToString)

    End Try

    '◆リターン
    Return retDataRow

  End Function

----------------------------------------------------------------------
insertRecordメソッドとclsInsertSyainクラスは、次号以降で作成します。

----------------------------------------------------------------------
                ■■ プログラムソース修正のお願い ■■

Public Class ClsSampleDBIO を、
Public MustInherit Class ClsSampleDBIO と、
インスタンスを生成できないように変更しました。お手数ですが修正をお願
いします。

前号の基本クラスClsSampleDBIOのGetAllDataメソッドに誤りがありました。
申し訳ありません。こちらも修正をお願いします。

  '★修正前
  For i As Integer = 0 To dtTableName.Rows.Count - 1
    'テーブル名存在チェック
    If TableName = dtColumns.Rows(i)("TABLE_NAME").ToString Then
                   ^^^^^^^^^
      existFlg = True
      Exit For
    End If
  Next i

  '★修正後
  For i As Integer = 0 To dtTableName.Rows.Count - 1
    'テーブル名存在チェック
    If TableName = dtTableName.Rows(i)("TABLE_NAME").ToString Then
                   ^^^^^^^^^^^
      existFlg = True
      Exit For
    End If
  Next i

修正後のソースリストを掲載します。

--【プログラムソースリスト(ファイル名:ClsSampleDBIO.vb)】----------

Public MustInherit Class ClsSampleDBIO '★ MustInheritを追加

  '(中略)

  '*******************************************************************
  ' 機能:引数に指定したテーブルの全レコードを取得する
  ' 引数:必須 ByVal テーブル名(String型)
  ' 引数:必須 ByVal 取得する列名(String型配列)
  ' 引数:任意 ByVal 整列する列名(String型)
  ' 引数:任意 ByVal 昇順ならTrue、降順ならFalse(Boolean型)
  ' 返値:引数に指定したテーブルの全レコード(DataTble型)
  '******1*********2*********3*********4*********5**********6*********
  Public Function GetAllData _
                  (ByVal TableName As String, _
                   ByVal Columns() As String, _
                   Optional ByVal SortKey As String = Nothing, _
                   Optional ByVal Sorted As Boolean = True _
                  ) As DataTable

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

    Try
      Using con As New SqlConnection
        Using cmd As New SqlCommand

          '----------< 引数が未設定だったら例外をスロー >----------
          If TableName = Nothing Then
            Throw New myDBIOException("引数エラー:TableNameが未設定")
          End If

          If Columns.Length = 0 Then
            Throw New myDBIOException("引数エラー:Columnsが未設定")
          End If

          '----------< テーブル名取得、列名取得 >----------
          Dim dtTableName As DataTable
          Dim dtColumns As DataTable

          '接続関連プロパティ設定
          Me.SetConnection(con, cmd)

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

          'テーブル名を取得
          dtTableName = con.GetSchema("Tables")

          '列名を取得
          dtColumns = con.GetSchema _
          ("Columns", New String() {Nothing, Nothing, TableName, Nothing})

          'DB接続を閉じる
          con.Close()

          '----------< SQL文の生成 >----------
          Dim existFlg As Boolean = False

          cmd.Parameters.Clear()
          cmd.CommandText = "SELECT "

          '列名の設定
          If Columns(0) = "*" Then
            '全列名指定の場合
             cmd.CommandText &= Columns(0) & " "

          Else
            '特定列名指定の場合
            For i As Integer = 0 To Columns.Length - 1
              '列名存在チェック
              For j As Integer = 0 To dtColumns.Rows.Count - 1
                If Columns(i) = dtColumns.Rows(j)("COLUMN_NAME").ToString Then
                  existFlg = True
                  Exit For
                End If
              Next j

              '列名が存在すれば、SQL文に連結
              If existFlg = True Then
                cmd.CommandText &= Columns(i)
                '最後の列名以外「,」を連結
                If i < Columns.Length - 1 Then
                  cmd.CommandText &= ","
                End If
                existFlg = False

              Else
                '列名が存在しなければ、例外をスロー
                Throw New myDBIOException _
                ("エラー:" & Columns(i) & "の列名は存在しない")
              End If

            Next i

          End If

          'テーブル名の設定
          For i As Integer = 0 To dtTableName.Rows.Count - 1
            '★テーブル名存在チェック(修正前)
            'If TableName = dtColumns.Rows(i)("TABLE_NAME").ToString Then
            '  existFlg = True
            '  Exit For
            'End If
            '★テーブル名存在チェック(修正後)
            If TableName = dtTableName.Rows(i)("TABLE_NAME").ToString Then
              existFlg = True
              Exit For
            End If
          Next i

          'テーブル名が存在すれば、テーブル名をSQL文に連結
          If existFlg = True Then
            cmd.CommandText &= " FROM " & TableName
          Else
            'テーブル名が存在しなければ、例外をスロー
            Throw New myDBIOException _
            ("エラー:" & TableName & "は存在しない")
          End If

          '整列の設定
          If Not SortKey = Nothing Then
            For i As Integer = 0 To Columns.Length - 1
              '整列キーの列名存在チェック
              If SortKey = dtColumns.Rows(i)("COLUMN_NAME").ToString Then
                existFlg = True
                Exit For
              End If
            Next i

            '整列キーの列名が存在すれば、列名をSQL文に連結
            If existFlg = True Then
              cmd.CommandText &= " ORDER BY " & SortKey
              '整列キーの昇順または降順をSQL文に連結
              If Sorted = True Then
                cmd.CommandText &= " ASC"
              Else
                cmd.CommandText &= " DESC"
              End If
            Else
              '整列キーの列名が存在しなければ、例外をスロー
              Throw New myDBIOException _
              ("エラー:" & SortKey & "の列名は存在しない")
            End If

          End If

          '----------< テーブルから全レコード取得 >----------
          Dim da As New SqlDataAdapter
          da.SelectCommand = cmd
          da.Fill(retDt)

        End Using

      End Using

    Catch ex As Exception
      '例外が発生したら、例外をスロー
      Throw New Exception("例外発生:" & ex.ToString)

    End Try

    '----------< ◆返値を設定してリターン >----------
    Return retDt

  End Function

======================================================================
VB.NET データベースプログラミング奮闘記
  発行者:ウェブ実験室(weblab アット マーク ca.wakwak.com)
          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.