ヘッダーをスキップ
Oracle® Objects for OLE開発者ガイド
11gリリース2 (11.2) for Microsoft Windows
B58887-04
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

6 Visual Basic用クイック・ツアー

このクイック・ツアーは、Visual Basic用Oracle Objects for OLEを開発者が使用開始できるように作成されています。サンプル・アプリケーションである従業員データベース・アプリケーションでは、データ間のナビゲートやレコードの追加、修正、問合せなどの、データベースの基本操作をプログラミングする方法を示します。上級者向けの項では、パラメータ配列およびSQL文オブジェクトを使用したバッチ挿入の実行方法を示します。このクィック・ツアーおよびサンプル・アプリケーションでは、Scott/Tigerスキーマがインストールされていることを前提としています。

このサンプル・アプリケーションの全コードは、ORACLE_BASE\\ORACLE_HOME\OO4O\VB\SAMPLES\QT\ディレクトリに提供されています。

このクイック・ツアーの内容は次のとおりです。

概要

この項では、従業員データベース・アプリケーション、およびそのアプリケーションを使用するためにユーザーが使用する2つのVisual Basicフォームの概要を示します。

従業員データベース・アプリケーションの概要

従業員データベース・アプリケーションでは、ユーザーは次の操作を実行できます。

  • データの参照

  • レコードの追加

  • レコードの更新

  • データベースの問合せ

  • バッチ操作でのレコードの追加

これらの機能を提供するために、例では次のフォームを使用しています。

従業員フォーム

従業員フォームには、データベースEMP表のフィールドが表示され、そこには、ユーザーがレコードを参照、追加、更新および問合せ可能な機能ボタンがあります。

図6-1に、従業員フォームを示します。

図6-1 従業員フォーム

図6-1の説明は次にあります。
「図6-1 従業員フォーム」の説明


関連項目:


バッチ挿入フォーム

バッチ挿入フォームにより、ユーザーは、バッチ操作でレコードを入力できます。


関連項目:

バッチ挿入フォームおよびそのコマンド・コードの詳細は、「バッチ・フォームのプログラミング」を参照してください。

図6-2に、バッチ挿入フォームを示します。

図6-2 バッチ挿入フォーム

図6-2の説明は次にあります。
「図6-2 バッチ挿入フォーム」の説明

開始: Oracleデータへのアクセス手順

サーバー・データを操作する前に、この項で説明する4つの手順をアプリケーションで完了しておく必要があります。この例のサンプル・コードは、「Form_Loadプロシージャの完全サンプル・コード」に示されています。

  1. Oracleインプロセス・オートメーション・サーバーを開始します。

    Oracleインプロセス・サーバー(OIP)では、Visual BasicアプリケーションとOracle Database間のインタフェースが提供されています。Oracleインプロセス・サーバーを開始するには、次に示すように、Visual BasicのCreateObject()ファンクションを使用してOraSessionオブジェクトを作成する必要があります。

    Set OraSession = CreateObject("OracleInProcServer.XOraSession")
    

    OraSessionオブジェクトを作成する場合、CreateObject()ファンクションに指定される引数は、常にOracleInProcServer.XOraSessionである必要があります。引数の左側にはシステムに登録されているアプリケーション名を指定し、この場合はOracleInProcServerです。右側には作成するオブジェクトのタイプを指定し、この場合はXOraSessionオブジェクトです。このコマンドを実行すると、Oracleインプロセス・サーバーが開始されます。

  2. Oracleデータベースへの接続

    OIPサーバーの実行後は、ローカルまたはリモートのOracleデータベースに接続できます。そのためには、次に示すように、OraDatabaseオブジェクトを作成する必要があります。

    Set OraDatabase = OraSession.OpenDatabase("Exampledb", "scott/tiger", _
           ORADB_DEFAULT)
    

    OraSession.OpenDatabase()メソッドでは、OraDatabaseオブジェクトが作成されます。メソッド・コールでは、データベース名、接続文字列、およびデータベース・モードを表すビット・フラグを指定する必要があります。定数ORADB_DEFAULTは、デフォルトのデータベース・モードを表します。Visual Basicがこの行を実行すると、指定されたデータベースへの接続が作成されます。

  3. データを操作するためにグローバル・オブジェクトOraDynasetを作成します。

    Oracle Objects for OLEでは、ユーザーからのデータの参照および更新用に、ダイナセットと呼ばれるオブジェクトを使用します。

    従業員アプリケーションには、プログラムの残り部分からもアクセス可能な、グローバル・ダイナセットが必要です。OraDatabase.CreateDynaset()メソッドでは、有効なSQL SELECT文を指定してダイナセットを作成します。次に示す例では、SQL文によってemp表からすべての行が選択され、作成されたダイナセットがグローバル変数EmpDynasetに割り当てられます。

    Set EmpDynaset = OraDatabase.CreateDynaset("select * from emp", _ 
         ORADYN_DEFAULT)
    

    CreateDynaset()メソッドでは、SQL SELECT文の結果へのポインタが戻されます。

    ORADYN_DEFAULTパラメータ値は、ダイナセットのデフォルト状態を指定します。Oracle Objects for OLEがデフォルト状態の場合、AddNewメソッドを使用してレコードを追加する際、未指定のフィールドはNULLに設定されます。emp表では列デフォルトが定義されないため、この動作が役立ちます。他のオプションを指定して、レコード追加時にサーバー列デフォルトを設定することも可能です。

  4. ダイナセット・データを使用して従業員フォームをリフレッシュします。

    従業員フォームでは、データベース・レコードが1回に1行ずつ表示されます。別の行へのナビゲートなどによる現在の行の変更は、画面上に反映される必要があります。EmpRefresh()サブルーチンは、ダイナセットの現在の行を使用してフィールドを更新します。フィールド値がNULLの場合は、空の文字列が表示されます。

    次に、EmpRefresh()サブルーチンの例を示します。

      Private Sub EmpRefresh()
     'check if the current dynaset row is valid
     If EmpDynaset.BOF <> True And EmpDynaset.EOF <> True Then
     
      txtEmpno = EmpDynaset.Fields("empno").Value
      
      ' we can't display nulls, so display ""  for NULL fields
      If Not IsNull(EmpDynaset.Fields("ename").Value) Then
        txtEname = EmpDynaset.Fields("ename").Value
        Else
          txtEname = ""
        End If
        
      If Not IsNull(EmpDynaset.Fields("job").Value) Then
        txtJob = EmpDynaset.Fields("job").Value
        Else
          txtJob = ""
        End If
        
      'check if mgr=nul
      If Not IsNull(EmpDynaset.Fields("mgr").Value) Then
       txtMgr = EmpDynaset.Fields("mgr").Value
       Else
         txtMgr = ""
       End If
      
      If Not IsNull(EmpDynaset.Fields("hiredate").Value) Then
        txtHireDate = EmpDynaset.Fields("hiredate").Value
      Else
        txtHireDate = ""
      End If
      
      If Not IsNull(EmpDynaset.Fields("hiredate").Value) Then
        txtSal = EmpDynaset.Fields("sal").Value
      Else
        txtSal = ""
       End If
        
      'check if comm=nul
      If Not IsNull(EmpDynaset.Fields("comm").Value) Then
       txtComm = EmpDynaset.Fields("comm").Value
      Else
       txtComm = ""
      End If
     
      txtDeptno = EmpDynaset.Fields("deptno").Value
     
    'if the current dynaset row is invalid, display nothing
     Else
     
      txtEmpno = ""
      txtEname = ""
      txtJob = ""
      txtMgr = ""
      txtHireDate = ""
      txtSal = ""
      txtComm = ""
      txtDeptno = ""
     
     End If
     
    End Sub
    

Form_Loadプロシージャの完全サンプル・コード

前の項で説明した従業員アプリケーションでは、Form_Load()プロシージャにより、OIPサーバーの作成、データベースへの接続、およびグローバル・ダイナセットの作成を行い、EmpRefreshファンクションをコールして従業員フォームでフィールド値を表示しています。次に、Form_Load()プロシージャの例を示します。

Private Sub Form_Load()
'OraSession and OraDatabase are global
 Set OraSession = CreateObject("OracleInProcServer.XOraSession")
 Set OraDatabase = OraSession.OpenDatabase("Exampledb", "scott/tiger", 0&)
 Set EmpDynaset = OraDatabase.CreateDynaset("select * from emp", 0&) 
 
 Call EmpRefresh
 
End Sub

次の変数は、EMP_QT.BASでは、グローバル変数として定義する必要があります。

Global OraSession As Object
Global OraDatabase As Object
Global EmpDynaset As Object

データ入力フォームのプログラミング

この項では、従業員フォームの詳細、および使用されるファンクションについて説明します。

従業員フォームの概要

従業員フォームには、データベースのEMP表のフィールドが表示され、そこには、ユーザーによるレコードの参照、追加、更新、問合せを可能にする機能ボタンがあります。

各フィールドは、データベースのEMP表の各列に対応しています。「Employee」フィールド(ENAME)は索引付けされた列であり、各レコードに対して必要です。EMP表のフィールドのデータ型とサイズは、次のように定義されています。

Name                     Null?       Type
-----------------------   ----------  --------------------------
EMPNO                     NOT NULL    NUMBER(4)
ENAME                                 VARCHAR2(10)
JOB                                   VARCHAR2(9)
MGR                                   NUMBER(4)
HIREDATE                              DATE
SAL                                   NUMBER(7,2)
COMM                                  NUMBER(7,2)
DEPTNO                    NOT NULL    NUMBER(2)

「Employee Number」(EMPNO)と「Department」(DEPTNO)の列はNOT NULLであるため、レコード追加時に常に値が必要です。各フィールドの長さは、それぞれのTextBoxMaxLengthプロパティを適切な数字に設定することで設定されます。

図6-3に、従業員フォームを示します。

図6-3 従業員フォーム

図6-3の説明は次にあります。
「図6-3 従業員フォーム」の説明

実際のForm_Loadプロシージャの初期化コードは、「Form_Loadプロシージャの完全サンプル・コード」に示されています。

従業員フォームは、Form_Load()プロシージャにより初期化され、次の機能を含みます。

データ間のナビゲート

一般的に、データベース・アプリケーションでは、ユーザーがデータベースのデータを表示できる必要があります。従業員フォームには4つのボタンがあり、ユーザーはデータをスクロールできます。表6-1に、各ボタンとその機能、各ボタンのアクションを有効にするダイナセットの移動メソッド、および詳細情報の参照先を示します。

表6-1 ナビゲーショナル・ボタンおよびダイナセットの移動メソッド

ボタン アクション メソッド 参照先

|<


最初のレコードへ移動

MoveFirst

最初または最後の行への移動


<


前のレコードへ移動

MovePrevious

前の行への移動


>

次のレコードへ移動

MoveNext

次の行への移動


>|

最後のレコードへ移動

MoveLast

最初または最後の行への移動



従業員データベースのレコード間のナビゲーションを可能にするには、最初に、すべてのレコード(行)を選択するグローバル・ダイナセットを作成する必要があります。その後、ダイナセットの移動メソッドを使用して、ナビゲーショナル・ボタンをプログラミングします。

最初または最後の行への移動

ダイナセットの最初の行への移動を可能にするには、MoveFirstメソッドを使用します。その後、従業員フォームのデータをリフレッシュするEmpRefresh()ルーチンをコールします。

次のサンプル・コードは、サンプル従業員レコードの最初の行へのクリック・イベントのプロシージャを示しています。

Private Sub cmdFirst_Click() 
 EmpDynaset.MoveFirst
 Call EmpRefresh
 
End Sub

最後の行への移動には、MoveLastメソッドを使用します。その後、従業員フォームのデータをリフレッシュするEmpRefresh()ルーチンをコールします。

次のサンプル・コードは、サンプル従業員レコードの最後の行へのクリック・イベントのプロシージャを示しています。

Private Sub cmdLast_Click()
 
 EmpDynaset.MoveLast
 Call EmpRefresh
 
End Sub

前の行への移動

ダイナセットでは、任意の行へナビゲーションが可能です。ユーザーがダイナセットの中間(つまり現在の行が最初の行ではない)を参照している場合、MovePreviousメソッドで前の行へナビゲーションできます。

ただし、ユーザーが最初の行を参照している場合(現在の行が最初の行の場合)にMovePreviousメソッドを実行すると、BOF(ファイルの先頭)条件がTRUEに設定され、現在の行が無効になります。この場合、MoveFirstメソッドを使用して、現在の行を最初の行にリセットする必要があります。

次のサンプル・コードは、前の行へのボタン・クリック・イベントのプロシージャを示しています。

Private Sub cmdPrevious_Click()
 
 If EmpDynaset.BOF <> True Then
  EmpDynaset.DbMovePrevious
  If EmpDynaset.BOF = True Then
   MsgBox WarnFirstEmp$
   EmpDynaset.DbMoveFirst
  End If
 End If

次の行への移動

ユーザーがダイナセットの中間(つまり現在の行が最後の行ではない)を参照している場合、MoveNextメソッドで次の行へナビゲーションできます。

ただし、ユーザーが最後の行を参照している場合(現在の行が最後の行の場合)にMoveNextメソッドを実行すると、EOF(ファイルの最後)条件がTRUEに設定され、現在の行が無効になります。この場合、MoveLastメソッドを使用して、現在の行を最後の行にリセットする必要があります。

次のサンプル・コードは、次の行へのボタン・クリック・イベントのプロシージャを示しています。

Private Sub cmdNext_Click()
 
 If EmpDynaset.EOF <> True Then
  EmpDynaset.DbMoveNext
  If EmpDynaset.EOF = True Then
   MsgBox WarnLastEmp$
   EmpDynaset.DbMoveLast
  End If
 End If

レコードの追加

このサンプル・アプリケーションでは、ユーザーは次のボタンでデータベースに従業員レコードを追加できます。

  • Add

  • Commit

レコードを追加するには、ユーザーは、「Add」ボタンをクリックして、テキスト・ボックスに新規フィールドを入力した後、「Commit」ボタンをクリックしてデータベースにデータを保存します。

「Add」ボタンのコーディング

追加イベント・プロシージャでは、次の手順を実行する必要があります。

  1. フォーム上のフィールドの消去。

  2. 「Add」ボタンの無効化。

  3. 「Commit」ボタンの有効化。

  4. ユーザーによる新規フィールド値の入力。

次のサンプル・コードは、「Add」ボタンのための追加イベント・プロシージャを示しています。

Private Sub AddNew_Click()
'Blank out the fields
  txtEmpno = ""
  txtEname = ""
  txtJob = ""
  txtMgr = ""
  txtHireDate = ""
  txtSal = ""
  txtComm = ""
  txtDeptno = ""
    
'Disable the Add button and enable the commit button
  AddNew.Enabled = False
  Commit.Enabled = True
'Disable the navigation buttons
  DisableNavButtons
'Set doadd to true for commit procedure
  DoAdd = True
End Sub

AddNew_Click()メソッドが存在する場合、ユーザーがフィールド値を入力している従業員フォームへ、コントロールが戻ります。

「Commit」ボタンのコーディング(追加)

追加をコミットするには、AddNewメソッドを使用してダイナセットを追加モードにします。その後、新規データをダイナセットのフィールドに割り当て、Updateメソッドを使用してデータベースを更新します。プログラムを堅牢にするために、このソフトウェアでは、一部のフィールドがデータベースへの追加前に検証されます。

Commit_Click()イベント・プロシージャでは、レコードを追加するために、次の処理を実行する必要があります。

  1. 「Employee Number」フィールドと「Department」フィールドがnullでないことの確認。

  2. 新規の「Employee Number」が重複入力ではないことの確認。

    手順1および手順2は、Commit_Click()の後に記述するDoValidationChecks()ファンクションにより実行されます。

  3. AddNewメソッドによるダイナセットの追加モードへの設定。

  4. Fields().Valueプロパティを使用した、ダイナセット・フィールドへの入力データの割当て。この手順は、UpdateDynasetFieldsファンクションにより実行されます。

  5. Updateメソッドを使用した、新規レコードでのデータベースの更新。

  6. 「Commit」ボタンの無効化。

  7. 「Add」ボタンの有効化。

Commitファンクションのコードは、次のルーチンに分かれます。

Commit_Clickイベント・プロシージャ(追加)

次に、レコードを追加する典型的なCommit_Click()イベント・プロシージャを示します。

Private Sub Commit_Click()
 
On Error GoTo err_commit
 
ErrMsg = ""
'Do validation checks on entered data
If DoValidationChecks Then 'If validation checks have passed
    
'Add the new record to dynaset
EmpDynaset.AddNew
 
'Update the dynaset fields and then update database if there is no error.
If UpdateDynasetFields Then

'Update the database
  EmpDynaset.Update
 
Commit.Enabled = False
AddNew.Enabled = True
 
Exit Sub
 
err_commit:
    If ErrMsg <> "" Then
        MsgBox ErrMsg
    Else
        MsgBox Error$
    End If
 
End Sub
DoValidationChecks( )ファンクション

ステップ2で推奨するように重複入力を確認するには、入力された「Employee Number」フィールドに一致する行をカウントするSQL文を使用し、NOCACHEオプションを指定してローカル・ダイナセットを作成する必要があります。一致が見つかった(行カウントが0より大きい)場合、入力された従業員番号は重複入力で、エラーが表示されます。この場合、SQL SELECT文は数のみを戻すため、サーバーによる重複入力の検出よりも、キャッシュなしでダイナセットを作成する方が効率的なエラー・チェックとなります。

DoValidationChecks()は、入力データが有効な場合はTrueを戻します。そうでない場合は、Falseを戻します。

Function DoValidationChecks() As Boolean
 
Dim DupDyn As Object
Dim DupDynQry As String
 
On Error GoTo err_ValidationCheck
 
ErrMsg = ""
'Empno cannot be changed while in Update mode, so we can skip over validation
If DoAdd Then
    If txtEmpno = "" Then
        ErrMsg = "You must enter a value for Employee Number"
        Error 1
    End If
End If
 
If txtHireDate <> "" And Not IsDate(txtHireDate) Then
    ErrMsg = "Enter date as dd-mmm-yy."
    Error 2
End If
 
If txtDeptno = "" Then
    ErrMsg = "You must enter a value for Department Number"
    Error 3
End If
 
'If adding a record, check for Duplicate empno value by
'attempting to count rows with same value
'Build Query:
If DoAdd Then
    DupDynQry = "select count(*) from emp where empno = " & txtEmpno
    Set DupDyn = OraDatabase.CreateDynaset(DupDynQry, ORADYN_NOCACHE)
 
    If DupDyn.Fields(0).Value <> 0 Then
        ErrNum = DUPLICATE_KEY
        ErrMsg = "Employee Number already exists."
        Error ErrNum
    End If
End If
'Succesful validation with no errors returns True
DoValidationChecks = True
Exit Function
 
err_ValidationCheck:
    If ErrMsg <> "" Then
        MsgBox ErrMsg
    Else
        MsgBox Error$
    End If
    'Validation returns false on failure
    DoValidationChecks = False
    
End Function
UpdateDynasetFields( )ファンクション

コミット・イベント・プロシージャでは、ダイナセットをEditまたはAddNewモードにした後、このファンクションをコールします。UpdateDynasetFields()ファンクションは、テキスト・ボックスに入力された値をダイナセットのフィールドに設定します。ファンクションが正常に完了した場合はTRUEを戻し、エラーがある場合はFALSEを戻します。

 Function UpdateDynasetFields() As Integer
'This function sets the dynaset field value to those entered in the text boxes. 
'The function returns true on success, false on error.
 
ErrMsg = ""
 
On Error GoTo err_updatedynasetfields
 
EmpDynaset.Fields("empno").Value = txtEmpno
EmpDynaset.Fields("ename").Value = txtEname
EmpDynaset.Fields("job").Value = txtJob
EmpDynaset.Fields("mgr").Value = txtManager
EmpDynaset.Fields("hiredate").Value = txtHireDate
EmpDynaset.Fields("sal").Value = txtSal
EmpDynaset.Fields("comm").Value = txtComm
EmpDynaset.Fields("deptno").Value = txtDeptno
 
UpdateDynasetFields = True
 
Exit Function
 
err_updatedynasetfields:
    If ErrMsg <> "" Then
        MsgBox ErrMsg
    Else
        MsgBox Error$
    End If
    UpdateDynasetFields = False

レコードの更新

ユーザーがデータベース内にある既存レコードを更新できるようにするには、従業員フォームに「Update」ボタンを含める必要があります。ユーザーは特定のレコードにナビゲートし、「Update」ボタンをクリックして変更を行った後、「Commit」ボタンをクリックします。

更新モードになっている間、アプリケーションでは次の制約が課されます。

  • ユーザーは、他のレコードへのナビゲートも他の機能の実行もできません。

  • 従業員番号は主キーであるため、ユーザーによる変更はできません。

Updateファンクションをプログラミングするには、「Update」ボタンのイベント・プロシージャを記述し、コミット・プロシージャを、レコードの更新と追加の両方を処理できるように修正します。

「Update」ボタンのコーディング

「Update」ボタンのコーディングでは、主キーである「Employee Number」のテキスト・ボックスを無効化して、このフィールドがレコード更新時に変更されないようにします。また、ナビゲーションなどのその他の機能もレコード更新時に無効になるよう、他のボタンも無効化する必要があります。

DoUpdateブール式をTRUEに設定し、コミット・プロシージャが現行プロセスを追加ではなく更新の操作として認識できるようにします。

更新イベント・プロシージャでは、次の処理を実行する必要があります。

  1. 「Update」ボタンの無効化。

  2. 「Commit」ボタンの有効化。

  3. 更新操作時にナビゲーションなどの機能を無効化するための、他のボタンの無効化。

  4. 「Employee Number」テキスト・ボックスの無効化。

  5. DoUpdateフラグのTrueへの設定。

  6. ユーザーによる変更の入力。

次のサンプル・コードは、更新イベント・プロシージャを示しています。

Private Sub cmdUpdate_Click()
'Disable the Update button and enable the commit button
  cmdUpdate.Enabled = False
  Commit.Enabled = True
'Disable all other buttons
  DisableNavButtons
  
  txtEmpno.Enabled = False
  DoUpdate = True
End Sub

更新および追加のイベント・プロシージャでは、追加または更新の操作中にナビゲーションおよびその他の機能を無効にするために、DisableNavButtons()サブルーチンをコールします。

Private Sub DisableNavButtons()
'disable all buttons while adding and updating
cmdFirst.Enabled = False
cmdPrevious.Enabled = False
cmdNext.Enabled = False
cmdLast.Enabled = False
cmdFind.Enabled = False
cmdUpdate.Enabled = False
AddNew.Enabled = False
 
End Sub

レコードを追加および更新する「Commit」ボタンのコーディング

更新をコミットするプロシージャは追加をコミットするプロシージャと似ていますが、ダイナセットがEditメソッドにより編集モードに設定されて新規ダイナセット値が割り当てられる点が異なります。

追加と更新では、同じコミット・ボタンおよび同じコミット・イベント・プロシージャが使用されるため、追加と更新を区別するために2つのグローバル・フラグDoAddDoUpdateが追加されます。「Add」および「Update」のクリック・イベント・プロシージャで、これらのフラグが設定されます。

追加と更新のコミット・イベント・プロシージャでは、次の処理を実行する必要があります。

  1. DoValidationChecks()ファンクションを前述と同様に使用した、入力データの検証。

  2. レコードの追加にはAddNew、更新にはEditの使用。

  3. 前述と同様にUpdateDynasetFields()を使用してFields().Valueプロパティを使用した、ダイナセット・フィールドへの入力データの割当て。

  4. Updateを使用した、新規レコードでのデータベースの更新。

  5. 「Commit」ボタンの無効化。

  6. 「Add」ボタンおよび「Update」ボタンを含む、他のすべての機能ボタンの再有効化。

  7. DoUpdateおよびDoAddフラグのFalseへの設定。

手順5から手順7に示すボタンおよびフラグの状態を変更するコードは、SetAfterCommitFlags()と呼ばれる新規サブルーチンで提供されます。これにより、最初にCommitおよびAddNewを有効化したコード行が置き換えられます。

このCommitファンクションのコードは、次のルーチンに分かれます。

Commit_Click( )イベント・プロシージャの例

次の例は、Commit_Clickイベント・プロシージャを示しています。

Private Sub Commit_Click()
 
On Error GoTo err_commit 
 
ErrMsg = ""
'Do validation checks on entered data
If DoValidationChecks Then 'If validation checks have passed
   
    'If we are adding a record use AddNew
    If DoAdd = True Then
        EmpDynaset.AddNew
    End If
    'If we are updating a record use Edit
    If DoUpdate = True Then
       EmpDynaset.Edit
    End If
    'Update the dynaset fields and then update database if there is no error.
    If UpdateDynasetFields Then
        EmpDynaset.Update
    End If
 
    SetAfterCommitFlags
 
End If 'Endif for DoValidationChecks
 
Exit Sub
 
err_commit:
    If ErrMsg <> "" Then
        MsgBox ErrMsg
    Else
        MsgBox Error$
    End If
 
End Sub
SetAfterCommitFlags()サブルーチンの例

次の例は、SetAfterCommitFlag()サブルーチンを示しています。

SetAfterCommitFlags()サブルーチンは、コミット・イベント・プロシージャの最後にコールされます。SetAfterCommitFlags()サブルーチンは、無効化されたボタンおよびテキスト・ボックスを再度有効化し、DoUpdateおよびDoAddフラグをFalseに設定します。

Sub SetAfterCommitFlags()
'disable commit and re-enable add and update buttons
Commit.Enabled = False
AddNew.Enabled = True
cmdUpdate.Enabled = True
 
'enable the other buttons
cmdFirst.Enabled = True
cmdPrevious.Enabled = True
cmdNext.Enabled = True
cmdLast.Enabled = True
cmdFind.Enabled = True
cmdUpdate.Enabled = True
AddNew.Enabled = True
 
DoUpdate = False
DoAdd = False
 
txtEmpno.Enabled = True
 
End Sub

レコードの削除

ユーザーは、特定のレコードにナビゲートして「Delete」ボタンをクリックすることで、レコードを削除できます。削除を確認するメッセージがアプリケーションから表示され、次にDeleteメソッドを使用してレコードが削除されます。次に、画面がリフレッシュされて、次のレコードまたは(ダイナセットの最後のレコードを削除した場合は)前のレコードが表示されます。

次の例は、削除クリック・イベント・プロシージャを示しています。

Private Sub cmdDelete_Click()
'prompt user
Response = MsgBox("Do you really want to Delete?", vbYesNo + vbExclamation)
    
If Response = vbYes Then
    EmpDynaset.Delete
    'attempt to move to next record
    EmpDynaset.MoveNext
    If EmpDynaset.EOF Then 'If deleted last record
        EmpDynaset.MovePrevious
    End If
    Call EmpRefresh
End If
End Sub

データベースの問合せ

従業員アプリケーションは、ユーザーがデータベース内で特定のレコードを検索できるように構成できます。デモ用に、従業員名のみを問い合せることができる「Find」ボタンが付いています。ユーザーはいつでも「Employee Name」フィールドに問合せを入力して、「Find」ボタンをクリックできます。その後、アプリケーションによって結果が表示されるか、名前が見つからなかった場合はメッセージが表示されます。

レコードの検索には、FindFirstメソッドを使用します。検索操作が正常に終了した場合、レコードが表示されます。検索に失敗した場合は、メッセージが表示されます。失敗するとダイナセットがBOF(ファイルの先頭)となるため、現在の行が最初の行に再設定され、現在の行は実質的に無効となります。

Find_Click()イベント・プロシージャでは、次の処理を実行する必要があります。

  1. 入力文字列と一致するENAME列を持つレコードを検索するためのfind句の構築。

  2. FindFirstメソッドを使用した、検索の実行。

  3. 該当するレコードが見つかった場合のレコードの表示。見つからなかった場合のメッセージの表示および現在の行の最初の行への再設定。

次の例は、典型的な検索クリック・イベント・プロシージャを示しています。

Private Sub cmdFind_Click()
Dim FindClause As String
Dim SingleQuote As String
 
ErrMsg = ""
SingleQuote = "'"
 
On Error GoTo err_find
'build the find clause:
'Can make our query case insensitive by converting the names to upper case
'FindClause = "UPPER(ename) = " & SingleQuote & UCase(txtEname) & SingleQuote
FindClause = "ename = " & SingleQuote & txtEname & SingleQuote
   
EmpDynaset.DbFindFirst FindClause
 
If EmpDynaset.NoMatch Then
    MsgBox "Could not find record matching Employee Name " & txtEname
    EmpDynaset.DbMoveFirst
End If
 
Call EmpRefresh
 
Exit Sub

バッチ挿入の使用

バッチ挿入フォームをロードする典型的なコマンドは次のとおりです。

Private Sub BInsert_Click()
  Load BatchInsert
  BatchInsert.Show
End Sub

バッチ・フォームのプログラミング

この項では、バッチ挿入フォームおよび使用されるファンクションについて説明します。

バッチ挿入フォームの概要

バッチ挿入フォームにより、ユーザーは、バッチ操作で行を挿入(1つのコマンドのみを使用して複数のレコードをデータベースに挿入)できます。この機能は、パラメータ配列およびSQL文を使用して実装されます。

表6-1に、一般的なバッチ挿入フォームを示します。

図6-4 バッチ挿入フォーム

図6-4の説明は次にあります。
「図6-4 バッチ挿入フォーム」の説明

ユーザーは、従業員フォーム上の「Batch Insert」ボタンをクリックすることにより、バッチ挿入フォームにナビゲートします。バッチ挿入フォームには、入力済データを表示するグリッドと、ユーザーがレコードを入力するフィールド行が設けられています。例では、簡潔にするために、ユーザーには「Employee Number」、「Employee Name」および「Department Number」フィールドへの入力のみが許可されています。

ユーザーは、フィールドにレコードを入力し、「Add to Grid」ボタンをクリックします。プログラムにより、入力したレコードがグリッドに表示されます。バッチ全体をデータベースに挿入するには、ユーザーは「CommitGrid」ボタンをクリックします。

バッチ挿入フォームには、3つのプロシージャが使用されます。Form_Load()プロシージャは、列ヘッダーでグリッドを初期化します。CmdAddtoGrid_click()プロシージャは、入力データをフィールドからグリッドにコピーします。CommitGrid_Click()プロシージャには、バッチ挿入に使用するパラメータ配列およびSQL文が含まれます。

次に、これらのプロシージャを示します。

バッチ挿入のForm_Load( )プロシージャのコーディング

次の例は、バッチ挿入のForm_Load()プロシージャがグリッドの列ヘッダーを設定する方法を示しています。

Private Sub Form_Load()
Grid1.Enabled = True
CurrRow = 0  'Top row
ReadRow = 0
ReadCol = 0
    
'Set column headings
 
Grid1.Row = CurrRow
Grid1.Col = 0
Grid1.Text = "Employee Number"
 
Grid1.Col = 1
Grid1.Text = "Employee Name"
 
Grid1.Col = 2
Grid1.Text = "Department Number"
 
NoOfCols = 3
 
CurrRow = CurrRow + 1
    
End Sub

CmdAddtoGrid( )プロシージャのコーディング

CmdAddtoGrid_Click()プロシージャは、フィールドに入力されたデータを、グリッドの次の空行にコピーします。グローバル変数CurrRowは、常に、グリッドの最初の空行を指します。

次の例は、CmdAddtoGrid_Click()を示しています。

Private Sub CmdAddtoGrid_Click()
 
'Update the grid
'Update Empno column
Grid1.Row = CurrRow
Grid1.Col = 0
Grid1.Text = txtEmpno
'Update Ename column
Grid1.Row = CurrRow
Grid1.Col = 1
Grid1.Text = txtEname
'Update Deptno column
Grid1.Row = CurrRow
Grid1.Col = 2
Grid1.Text = txtDeptno
 
'Increment CurrCol
CurrRow = CurrRow + 1
 
NoOfRows = CurrRow - 1
 
End Sub

CommitGrid_Click( )プロシージャのコーディング

CommitGrid_Click()プロシージャは、グリッドのデータをデータベースに挿入します。これを行うために、このプロシージャでは、グリッドの各列に対応するEMP表の各列に対して、パラメータ配列オブジェクトを作成します。OraParameters.AddTable()メソッドでは、各パラメータ配列を定義します。たとえば、EMPNO_ARRというパラメータ配列では「Employee Number」列要素を保持する、などです。

パラメータ配列を定義した後、Put_Valueメソッドで各配列にグリッド列要素を移入します。

パラメータ配列要素をデータベースにコミットするために、このプロシージャでは、CreateSQL()メソッドを、パラメータ配列を含むSQL INSERT文とともに使用します。CreateSQL()メソッドでは、SQL文オブジェクトを作成するとともにSQL INSERT文も実行するため、この1つの文ですべての列要素(パラメータ配列要素)がEMP表に挿入されます。

パラメータ配列を含むSQL INSERT文の実行時にエラーが発生した場合も、SQL文オブジェクトは明示的なエラーとはならずに作成されます。このようなエラーを識別するには、CreateSQLメソッドの実行直後に、必ず、OraDatabase.LastServerErrおよびOraDatabase.LastServerErrTextプロパティをチェックします。

CreateSQLメソッドは、データベースを直接更新し、ダイナセットには影響しません。EmpDynaset.Refreshメソッドを使用してこのダイナセットをリフレッシュし、新しく挿入されたレコードがそれに反映されるようにする必要があります。

CommitGrid_Click()イベント・プロシージャでは、次の処理を実行する必要があります。

  1. AddTableメソッドを使用した、各グリッド(データベース)列のパラメータ配列の定義。

  2. ネステッド・ループ内でPut_Valueメソッド使用した、グリッド列要素のパラメータ配列へのコピー。

  3. パラメータ配列要素をEMP表へ挿入するための、CreateSQLメソッドを使用したSQL文オブジェクトの作成。

  4. SQL文実行エラーを識別するための、LastServerErrTextおよびLastServerErrプロパティの確認。

  5. 新規に挿入されたレコードを反映するための、Refreshメソッドを使用したグローバル・ダイナセットのリフレッシュ。

次の例は、典型的なcmdCommitGrid_Click()プロシージャを示しています。

Private Sub cmdCommitGrid_Click()
Dim OraSqlStmt As Object
Dim OraPArray(2) As Object
 
On Error GoTo err_CommitGrid
ErrMsg = ""
 
'Define parameter arrays, one for each column
OraDatabase.Parameters.AddTable "EMPNO_ARR", ORAPARM_INPUT, ORATYPE_NUMBER, _
            NoOfRows
OraDatabase.Parameters.AddTable "ENAME_ARR", ORAPARM_INPUT, ORATYPE_VARCHAR2, _ 
            NoOfRows, 10
OraDatabase.Parameters.AddTable "DEPTNO_ARR", ORAPARM_INPUT, ORATYPE_NUMBER, _
            NoOfRows
If OraDatabase.LastServerErr <> 0 Or OraDatabase.LastServerErrText <> "" Then
Error 1
End If
 
'Initialize local array to hold parameter arrays
Set OraPArray(0) = OraDatabase.Parameters("EMPNO_ARR")
Set OraPArray(1) = OraDatabase.Parameters("ENAME_ARR")
Set OraPArray(2) = OraDatabase.Parameters("DEPTNO_ARR")
 
'Init the param array variables. Add loop to read thru grid ROWS
For ReadRow = 0 To (NoOfRows - 1)
Grid1.Row = ReadRow + 1
'Loop to read thru grid CELLS
    For ReadCol = 0 To NoOfCols - 1
        Grid1.Col = ReadCol
        OraPArray(ReadCol).Put_Value Grid1.Text, ReadRow
    Next ReadCol
Next ReadRow
 
'create a sqlstmt to insert array values into table
Set OraSqlStmt = OraDatabase.CreateSql("insert into emp(empno,ename,deptno)" & _
        "values(:EMPNO_ARR,:ENAME_ARR,:DEPTNO_ARR)", 0&)
If OraDatabase.LastServerErr <> 0 Or OraDatabase.LastServerErrText <> "" Then
  ErrMsg = OraDatabase.LastServerErrText
  Error 1
End If
 
'Refresh the Dynaset
EmpDynaset.Refresh

OraDatabase.Parameters.Remove "EMPNO_ARR"
OraDatabase.Parameters.Remove "ENAME_ARR"
OraDatabase.Parameters.Remove "DEPTNO_ARR" 

Exit Sub
 
err_CommitGrid:
    If ErrMsg <> "" Then
        MsgBox ErrMsg
    Else
        MsgBox Error$
    End If
 
End Sub