バックナンバー:VB.NETデータベースプログラミング
ADO.NETの基本的なプログラミングを中心に、すぐ使えるサンプルプログラム満載です。
【第70号】
第70号(2009.3.2発行) ==================================================================== ★★ -- VB.NETデータベースプログラミング奮闘記 -- ★★ (VB 2008 Express & SQL Server 2005 Express) -------------------------------------------------------------------- いつもご購読ありがとうございます。ADO.NETの基本的なプログラミングを 中心に掲載します。今後ともよろしくお願い申し上げます。 すぐ使えるADO.NET --> http://park5.wakwak.com/‾weblab/ -------------------------------------------------------------------- 【お知らせ】マスター保守修正版が完了したら、注文伝票入力を始めます。 注文伝票入力では、ヘッダーとデータグリッドビューを使った明細行の入力 、注文テーブル(ヘッダーデータ)と注文明細テーブルへの登録などを予定 しています。 ==================================================================== ■■ マスターテーブル保守改良版 テーブルに追加 ■■ マスター保守のプログラムは現在見直し中です。今回はマスターテーブルレ コード追加【修正版】のソースリストを掲載します。 主な修正点は、フォームクラスでの開発負担を軽減するために、フォームク ラスから、テーブルアクセスクラスのメンバーを呼び出さないようにした点 です。 【注意点】部署コード処理は省略しました。 -------------------------------------------------------------------- ■■ 社員テーブルに追加する ■■ 社員コード、社員氏名、カナ名、部署コードを入力し、追加ボタンをクリッ クすると、入力したデータのエラーチェックをして、エラーが無ければ、社 員テーブルに 1レコード追加します。 【社員テーブル】 --------------------------------------------- key 列 名 データ型 nullを許容 --------------------------------------------- ○ 社員コード nchar(5) 許容しない − 社員氏名 nvarchar(20) 許容しない − 社員カナ nvarchar(40) 許容しない − 更新日時 datetime 許容しない --------------------------------------------- ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ 社員テーブル追加 _□×┃ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ Label1 TxtShainCode ┃┌―――――┐ ┌―――――┐ ┃│社員コード│ │ │ ┃└―――――┘ └―――――┘ ┃ Label2 TxtShainShimei ┃┌―――――┐ ┌――――――――┐ ┃│社員氏名 │ │ │ ┃└―――――┘ └――――――――┘ ┃ Label3 TxtShainKana ┃┌―――――┐ ┌――――――――――――――┐ ┃│社員カナ │ │ │ ┃└―――――┘ └――――――――――――――┘ ┃ BtnInsert BtnClear ┃┌――――┐ ┌―――――┐ ┃│ 追加 │ │ クリア │ ┃└――――┘ └―――――┘ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛ 接続文字列は、app.configに登録しておきます。 <connectionStrings> <add name="AdoNet.My.MySettings.sampleDBConStr" .......... /> </connectionStrings> ==================================================================== 【画面クラスの主な改良修正点】 画面クラスからは、社員テーブルアクセスクラスのメンバーを呼び出さない ように修正しました。 --【プログラムソースリスト(FormInsert.vb)】----------------------- Option Strict On '////////// 社員テーブル追加画面クラス ////////// Public Class FormInsert '----------<< 追加ボタン押下処理 >>---------- Private Sub BtnInsert_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles BtnInsert.Click Try Dim shain As New ClsInsertShain ' 社員テーブルのデータ行生成 Dim row As DataRow row = shain.CreateDataRow() ' 画面からの入力データのセット row("社員コード") = Me.TxtShainCode.Text row("社員氏名") = Me.TxtShainShimei.Text row("社員カナ") = Me.TxtShainKana.Text ' 社員テーブルに1レコードを追加 shain.InsertRecord(row) ' 画面初期設定 Me.ClearForm() ' 正常終了メッセージ MessageBox.Show("正常に追加されました", "追加処理") Me.TxtShainCode.Focus() Catch ex As myShainCodeException ' 社員コードエラー MessageBox.Show(ex.Message, "社員コード入力エラー") Me.TxtShainCode.Focus() Catch ex As myShainShimeiException ' 社員氏名エラー MessageBox.Show(ex.Message, "社員氏名入力エラー") Me.TxtShainShimei.Focus() Catch ex As myShainKanaException ' 社員カナエラー MessageBox.Show(ex.Message, "社員カナ入力エラー") Me.TxtShainKana.Focus() Catch ex As myDBIOException ' DBアクセスクラス独自例外発生時 MessageBox.Show(ex.Message, "DBIO例外発生") Catch ex As Exception ' その他例外発生時 MessageBox.Show(ex.ToString, "例外発生") End Try End Sub '----------<< クリアボタン押下処理 >>---------- Private Sub BtnClear_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles BtnClear.Click ' フォーム初期設定 Me.ClearForm() End Sub '----------<< フォーム初期設定処理 >>---------- Private Sub ClearForm() Me.TxtShainCode.Text = Nothing Me.TxtShainShimei.Text = Nothing Me.TxtShainKana.Text = Nothing Me.TxtShainCode.Focus() End Sub End Class ==================================================================== 【社員データ基本クラスの主な改良修正点】 外部から値をセットする必要のない更新日時プロパティをReadOnlyにして、 Setプロパティを削除しました。 サブクラスでのアクセス方法が異なるため、社員コードプロパティ宣言は削 除して、各サブクラスで実装することにしました。 --【プログラムソースリスト(ClsShain.vb)】------------------------- Option Strict On Imports System.Text.RegularExpressions '////////// 基本クラス:社員データクラス ////////// Public MustInherit Class ClsShainBase '----------<< メンバ:変数 >>---------- Protected shainCodeValue As String Private shainShimeiValue As String Private shainKanaValue As String Protected koushinNichijiValue As DateTime '======================================================== ' 機能:コンストラクタ ' 引数:なし '======================================================== Protected Sub New() MyBase.New() ' 基本クラスのコンストラクタを呼び出す End Sub '-------------------------------------------------------- ' プロパティ:社員氏名 '-------------------------------------------------------- Public Property ShainShimei() As String ' Getプロパティ Get Return shainShimeiValue End Get ' Setプロパティ Set(ByVal value As String) ' 【エラーチェック】 If value.Length = 0 Then ' 未入力はエラー Throw New myShainShimeiException _ ("社員氏名を入力してください") Else shainShimeiValue = value End If End Set End Property '-------------------------------------------------------- ' プロパティ:社員カナ '-------------------------------------------------------- Public Property ShainKana() As String ' Getプロパティ Get Return shainKanaValue End Get ' Setプロパティ Set(ByVal value As String) ' 【エラーチェック】 If value.Length = 0 Then ' 未入力はエラー Throw New myShainKanaException _ ("社員カナを入力してください") Else ' 全角カタカナ以外はエラー If Regex.IsMatch(Value, "^[ァ-ー]+$") Then shainKanaValue = value Else Throw New myShainKanaException _ ("全角カタカナのみで入力してください") End If End If End Set End Property '-------------------------------------------------------- ' プロパティ:更新日時 '-------------------------------------------------------- Public ReadOnly Property KoushinNichiji() As DateTime ' Getプロパティ Get Return koushinNichijiValue End Get End Property End Class ==================================================================== 【社員データ追加クラスの主な改良修正点】 コンストラクタの引数を指定しないように変更しました。レコード追加メ ソッドを新たに追加しました。 --【プログラムソースリスト(ClsShain.vb)】------------------------- '////////// 派生クラス:社員データレコード追加クラス ////////// Public Class ClsInsertShain Inherits ClsShainBase '======================================================= ' 機能:コンストラクタ ' 引数:なし '======================================================= Public Sub New() MyBase.New() End Sub '------------------------------------------------------- ' プロパティ:社員コード '------------------------------------------------------- Public Property ShainCode() As String ' Getプロパティ Get Return shainCodeValue End Get ' Setプロパティ Set(ByVal value As String) ' 【エラーチェック】 If value.Length = 0 Then ' 未入力はエラー Throw New myShainCodeException _ ("社員コードを入力してください") Else ' 数字以外はエラー If Not Regex.IsMatch(value, "^[0-9]+$") Then Throw New myShainCodeException _ ("社員コードに数字以外があります") Else ' 社員テーブルにアクセス Dim dbIO As New ClsShainTableIO ' 社員コードが社員マスタにあればエラー If dbIO.ExistKeyData(value) = True Then Throw New myShainCodeException _ ("社員コードは登録済みです") Else shainCodeValue = value End If End If End If End Set End Property '********************************************************** ' 機能:社員テーブルに1レコードを追加するメソッド ' 引数:行データ ' 戻値:追加したレコード数 '******1*********2*********3*********4*********5**********6 Public Function InsertRecord _ (ByVal shain As DataRow) As Integer Dim retInsertCount As Integer ' リターン値 Dim dbIO As New ClsShainTableIO() ' エラーチェックとデータセット Me.ShainCode = CStr(shain("社員コード")) MyBase.ShainShimei = CStr(shain("社員氏名")) MyBase.ShainKana = CStr(shain("社員カナ")) MyBase.koushinNichijiValue = DateTime.Now ' レコードの追加 retInsertCount = dbIO.InsertRecord(Me) Return retInsertCount End Function End Class ==================================================================== 【sampleDBアクセスクラスの改良修正点】 Try … Catch … End Try をはずして、エラー発生時はそのまま例外をス ローするように修正しました。 --【プログラムソースリスト(ClsSampleDBIO.vb)】-------------------- Option Strict On Imports System.Configuration ' [参照の追加]から追加 Imports System.Data.SqlClient Imports System.Transactions ' [参照の追加]から追加 '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ' インターフェイス定義 '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Public Interface IDBIO Function InsertRecord(ByVal shain As ClsInsertShain) As Integer End Interface '////////// 基本クラス:sampleDBアクセスクラス ////////// Public MustInherit Class ClsSampleDBIO '========================================================== ' 機能:コンストラクタ ' 引数:なし '========================================================== Public Sub New() MyBase.New() End Sub '********************************************************** ' 機能:テーブルキー値のレコードの有無を調べるメソッド ' 引数:テーブル名 ' 引数:キーフィールド名 ' 引数:主キー値 ' 戻値:レコードあり-->True、レコードなし-->False ' 補足:主キーフィールドはNChar型とする '******1*********2*********3*********4*********5**********6 Public Function ExistKeyData(ByVal tableName As String, _ ByVal keyField As String, _ ByVal keyCode As String) _ As Boolean Dim retExist As Boolean ' リターン値 Using con As New SqlConnection Using cmd As New SqlCommand ' 接続関連プロパティ設定 Me.SetConnection(con, cmd) ' SQL文設定 cmd.CommandText = "SELECT COUNT(*) FROM " & _ tableName & _ " WHERE " & keyField & " = @KeyCode" ' SQL文の引数設定 cmd.Parameters.Clear() ' パラメータの実際のサイズからデータ長を推論 cmd.Parameters.Add("@KeyCode", SqlDbType.NChar) ' コマンド引数に値を設定 cmd.Parameters("@KeyCode").Value = keyCode ' DB接続を開く con.Open() ' レコード件数取得 Dim count As Integer = CInt(cmd.ExecuteScalar()) If count = 1 Then ' レコードが1件あれば、Trueを返す retExist = True Else ' そうでなければ、Falseを返す retExist = False End If End Using End Using ' ◆戻値を設定してリターン Return retExist End Function '********************************************************** ' 機能:引数に指定したテーブルのキー値のレコードを取得する ' 引数:テーブル名 ' 引数:キーフィールド名 ' 引数:主キー値 ' 戻値:取得したレコード ' 補足:テーブル名の主キーフィールドはNChar型とする '******1*********2*********3*********4*********5**********6 Public Function GetKeyData(ByVal tableName As String, _ ByVal keyField As String, _ ByVal keyCode As String) _ As DataTable Dim retDt As New DataTable 'リターン値 '----------<< テーブルからレコード取得 >>---------- Using con As New SqlConnection Using cmd As New SqlCommand ' 接続関連プロパティ設定 Me.SetConnection(con, cmd) ' SQL文設定 cmd.CommandText = "SELECT * FROM " & _ tableName & _ " WHERE " & keyField & " = @keyCode" ' SQL文の引数設定 cmd.Parameters.Clear() ' パラメータの実際のサイズからデータ長を推論 cmd.Parameters.Add("@keyCode", SqlDbType.NChar) ' コマンド引数に値を設定 cmd.Parameters("@KeyCode").Value = keyCode ' レコード取得 Dim da As New SqlDataAdapter da.SelectCommand = cmd da.Fill(retDt) End Using End Using ' ◆戻値を設定してリターン Return retDt End Function '********************************************************** ' 機能:社員テーブルの行データ生成 ' 引数:テーブル名 ' 引数:キーフィールド名 ' 戻値:生成した行データ '******1*********2*********3*********4*********5**********6 Public Function CreateDataRow(ByVal tableName As String, _ ByVal keyField As String) _ As DataRow Dim retRow As DataRow ' リターン値 Dim dt As New DataTable ' 列情報を取込むために、レコードを取得するが ' 取得できなくてもよいので、第三引数のキー値は何でも良い dt = Me.GetKeyData(tableName, keyField, "_") retRow = dt.NewRow Return retRow End Function '********************************************************** ' 機能:接続関連プロパティ設定 ' 引数:参照 SqlConnectionオブジェクト ' 引数:参照 SqlCommandオブジェクト ' 戻値:なし '******1*********2*********3*********4*********5**********6 Public Sub SetConnection(ByRef con As SqlConnection, _ ByRef cmd As SqlCommand) Dim settings As ConnectionStringSettings ' 接続文字列をapp.configファイルから取得 settings = _ ConfigurationManager.ConnectionStrings _ ("AdoNet.My.MySettings.sampleDBConStr") If settings Is Nothing Then ' 接続文字列取得エラー Throw New Exception _ ("接続文字列がapp.configに未登録") Else ' 接続文字列の設定 con.ConnectionString = settings.ConnectionString ' SqlCommand.Connectionプロパティの設定 cmd.Connection = con End If End Sub End Class ==================================================================== 【社員テーブルアクセスクラスの改良修正点】 このクラスも、Try … Catch … End Try をはずして、エラー発生時はそ のまま例外をスローするように修正しました。 --【プログラムソースリスト(ClsShainTableIO.vb)】------------------ Option Strict On Imports System.Data.SqlClient Imports System.Text.RegularExpressions Imports System.Transactions ' [参照の追加]で追加 '////////// 基本クラス:社員データ基本クラス ////////// Public Class ClsShainTableIO Inherits ClsSampleDBIO Implements IDBIO '========================================================== ' 機能:コンストラクタ ' 引数:なし '========================================================== Public Sub New() MyBase.New() End Sub '********************************************************** ' 機能:社員テーブルキー値のレコードの有無を調べるメソッド ' 引数:社員コード ' 戻値:レコードあり-->True、レコードなし-->False ' 補足:主キーフィールドはNChar型とする '******1*********2*********3*********4*********5**********6 Public Overloads Function _ ExistKeyData(ByVal keyCode As String) As Boolean Dim retExist As Boolean ' リターン値 ' 引数の空文字列チェック If keyCode.Length = 0 Then Throw New myShainCodeException _ ("社員コードが未入力") End If ' キー値文字チェック(キー値は数字のみで構成されている) If Not Regex.IsMatch(keyCode, "^[0-9]+$") Then ' 数字以外はエラー Throw New myShainCodeException _ ("社員コードに数字以外の文字があります") End If ' キー値長さチェック(社員コードは5桁) If Not keyCode.Length = 5 Then ' 5桁以外はエラー Throw New myShainCodeException _ ("社員コードの桁数が正しくない") End If ' 引数コードのレコードの有無をチェックする retExist = _ MyBase.ExistKeyData("社員テーブル", "社員コード", keyCode) ' ◆戻値を設定してリターン Return retExist End Function '********************************************************** ' 機能:社員テーブルに1レコードを追加するメソッド ' 引数:追加する1レコード分の行データ ' 戻値:integer型:追加したレコード数 '******1*********2*********3*********4*********5**********6 Public Function _ InsertRecord(ByVal shain As ClsInsertShain) As Integer _ Implements IDBIO.InsertRecord Dim retInsertCount As Integer ' リターン値 ' 引数の未設定チェック If shain Is Nothing Then ' 引数が未設定だったら例外をスロー Throw New myDBIOException _ ("ClsShainTableIO.InsertRecord:引数が未設定") End If ' トランザクション開始 Using tran As New TransactionScope Using con As New SqlConnection Using cmd As New SqlCommand ' 接続関連プロパティ設定 MyBase.SetConnection(con, cmd) ' SQL文の作成 cmd.CommandText = _ "INSERT INTO " & _ "社員テーブル(社員コード, 社員氏名, 社員カナ, " & _ "更新日時) " & _ "VALUES(@code, @shimei, @kana, @kousin)" ' SQL文引数に値を設定 cmd.Parameters.Clear() cmd.Parameters.Add("@code", SqlDbType.NChar, 5) cmd.Parameters.Add("@shimei", SqlDbType.NVarChar, 20) cmd.Parameters.Add("@kana", SqlDbType.NVarChar, 40) cmd.Parameters.Add("@kousin", SqlDbType.DateTime) cmd.Parameters("@code").Value = Shain.ShainCode cmd.Parameters("@shimei").Value = Shain.ShainShimei cmd.Parameters("@kana").Value = Shain.ShainKana cmd.Parameters("@kousin").Value = DateTime.Now ' DB接続を開く con.Open() ' データベースの追加実行 retInsertCount = cmd.ExecuteNonQuery() End Using End Using ' 1レコード追加なら正常(通常これしかありえない) If retInsertCount = 1 Then ' トランザクション完了(コミット) tran.Complete() Else ' 1レコード追加以外なら例外をスロー ' コミットしなければ、自動的にロールバックされる Throw New myDBIOException _ ("ClsShainTableIO.InsertRecord:レコード追加失敗") End If End Using ' ◆戻値を設定してリターン Return retInsertCount End Function End Class -------------------------------------------------------------------- 次号は、マスター保守(社員テーブル更新)の修正版です。 ==================================================================== VB.NET データベースプログラミング奮闘記 発行者:ウェブ実験室([email protected]) 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」 などホームページに掲載されている会社名・製品名等は、各社の登録商標ま たは商標です。 ====================================================================
▲このページ先頭へ | すぐ使えるADO.NET ホームへ
Copyright© すぐ使えるADO.NET. All rights reserved.