このクイック・ツアーは、Visual Basic用Oracle Objects for OLEを開発者が使用開始できるように作成されています。サンプル・アプリケーションである従業員データベース・アプリケーションでは、データ間のナビゲートやレコードの追加、修正、問合せなどの、データベースの基本操作をプログラミングする方法を示します。上級者向けの項では、パラメータ配列およびSQL文オブジェクトを使用したバッチ挿入の実行方法を示します。このクィック・ツアーおよびサンプル・アプリケーションでは、Scott
/Tiger
スキーマがインストールされていることを前提としています。
このサンプル・アプリケーションの全コードは、ORACLE_BASE\\ORACLE_HOME
\OO4O\VB\SAMPLES\QT\
ディレクトリに提供されています。
このクイック・ツアーの内容は次のとおりです。
この項では、従業員データベース・アプリケーション、およびそのアプリケーションを使用するためにユーザーが使用する2つのVisual Basicフォームの概要を示します。
従業員データベース・アプリケーションでは、ユーザーは次の操作を実行できます。
データの参照
レコードの追加
レコードの更新
データベースの問合せ
バッチ操作でのレコードの追加
これらの機能を提供するために、例では次のフォームを使用しています。
従業員フォームには、データベースEMP
表のフィールドが表示され、そこには、ユーザーがレコードを参照、追加、更新および問合せ可能な機能ボタンがあります。
図6-1に、従業員フォームを示します。
関連項目:
|
サーバー・データを操作する前に、この項で説明する4つの手順をアプリケーションで完了しておく必要があります。この例のサンプル・コードは、「Form_Loadプロシージャの完全サンプル・コード」に示されています。
Oracleインプロセス・オートメーション・サーバーを開始します。
Oracleインプロセス・サーバー(OIP)では、Visual BasicアプリケーションとOracle Database間のインタフェースが提供されています。Oracleインプロセス・サーバーを開始するには、次に示すように、Visual BasicのCreateObject()
ファンクションを使用してOraSession
オブジェクトを作成する必要があります。
Set OraSession = CreateObject("OracleInProcServer.XOraSession")
OraSession
オブジェクトを作成する場合、CreateObject()
ファンクションに指定される引数は、常にOracleInProcServer.XOraSession
である必要があります。引数の左側にはシステムに登録されているアプリケーション名を指定し、この場合はOracleInProcServer
です。右側には作成するオブジェクトのタイプを指定し、この場合はXOraSession
オブジェクトです。このコマンドを実行すると、Oracleインプロセス・サーバーが開始されます。
Oracleデータベースへの接続
OIPサーバーの実行後は、ローカルまたはリモートのOracleデータベースに接続できます。そのためには、次に示すように、OraDatabase
オブジェクトを作成する必要があります。
Set OraDatabase = OraSession.OpenDatabase("Exampledb", "scott/tiger", _ ORADB_DEFAULT)
OraSession.OpenDatabase()
メソッドでは、OraDatabase
オブジェクトが作成されます。メソッド・コールでは、データベース名、接続文字列、およびデータベース・モードを表すビット・フラグを指定する必要があります。定数ORADB_DEFAULT
は、デフォルトのデータベース・モードを表します。Visual Basicがこの行を実行すると、指定されたデータベースへの接続が作成されます。
データを操作するためにグローバル・オブジェクト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
表では列デフォルトが定義されないため、この動作が役立ちます。他のオプションを指定して、レコード追加時にサーバー列デフォルトを設定することも可能です。
ダイナセット・データを使用して従業員フォームをリフレッシュします。
従業員フォームでは、データベース・レコードが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()
プロシージャにより、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
であるため、レコード追加時に常に値が必要です。各フィールドの長さは、それぞれのTextBox
のMaxLength
プロパティを適切な数字に設定することで設定されます。
図6-3に、従業員フォームを示します。
実際のForm_Load
プロシージャの初期化コードは、「Form_Loadプロシージャの完全サンプル・コード」に示されています。
従業員フォームは、Form_Load()
プロシージャにより初期化され、次の機能を含みます。
一般的に、データベース・アプリケーションでは、ユーザーがデータベースのデータを表示できる必要があります。従業員フォームには4つのボタンがあり、ユーザーはデータをスクロールできます。表6-1に、各ボタンとその機能、各ボタンのアクションを有効にするダイナセットの移動メソッド、および詳細情報の参照先を示します。
表6-1 ナビゲーショナル・ボタンおよびダイナセットの移動メソッド
ボタン | アクション | メソッド | 参照先 |
---|---|---|---|
|
最初のレコードへ移動 |
|
|
|
前のレコードへ移動 |
|
|
|
次のレコードへ移動 |
|
|
|
最後のレコードへ移動 |
|
|
従業員データベースのレコード間のナビゲーションを可能にするには、最初に、すべてのレコード(行)を選択するグローバル・ダイナセットを作成する必要があります。その後、ダイナセットの移動メソッドを使用して、ナビゲーショナル・ボタンをプログラミングします。
ダイナセットの最初の行への移動を可能にするには、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」ボタンの無効化。
「Commit」ボタンの有効化。
ユーザーによる新規フィールド値の入力。
次のサンプル・コードは、「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()
メソッドが存在する場合、ユーザーがフィールド値を入力している従業員フォームへ、コントロールが戻ります。
追加をコミットするには、AddNew
メソッドを使用してダイナセットを追加モードにします。その後、新規データをダイナセットのフィールドに割り当て、Update
メソッドを使用してデータベースを更新します。プログラムを堅牢にするために、このソフトウェアでは、一部のフィールドがデータベースへの追加前に検証されます。
Commit_Click()
イベント・プロシージャでは、レコードを追加するために、次の処理を実行する必要があります。
「Employee Number」フィールドと「Department」フィールドがnullでないことの確認。
新規の「Employee Number」が重複入力ではないことの確認。
手順1および手順2は、Commit_Click()
の後に記述するDoValidationChecks()
ファンクションにより実行されます。
AddNew
メソッドによるダイナセットの追加モードへの設定。
Fields().Value
プロパティを使用した、ダイナセット・フィールドへの入力データの割当て。この手順は、UpdateDynasetFields
ファンクションにより実行されます。
Update
メソッドを使用した、新規レコードでのデータベースの更新。
「Commit」ボタンの無効化。
「Add」ボタンの有効化。
Commit
ファンクションのコードは、次のルーチンに分かれます。
次に、レコードを追加する典型的な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
ステップ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
コミット・イベント・プロシージャでは、ダイナセットを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」ボタンのコーディングでは、主キーである「Employee Number」のテキスト・ボックスを無効化して、このフィールドがレコード更新時に変更されないようにします。また、ナビゲーションなどのその他の機能もレコード更新時に無効になるよう、他のボタンも無効化する必要があります。
DoUpdate
ブール式をTRUE
に設定し、コミット・プロシージャが現行プロセスを追加ではなく更新の操作として認識できるようにします。
更新イベント・プロシージャでは、次の処理を実行する必要があります。
「Update」ボタンの無効化。
「Commit」ボタンの有効化。
更新操作時にナビゲーションなどの機能を無効化するための、他のボタンの無効化。
「Employee Number」テキスト・ボックスの無効化。
DoUpdate
フラグのTrue
への設定。
ユーザーによる変更の入力。
次のサンプル・コードは、更新イベント・プロシージャを示しています。
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
更新をコミットするプロシージャは追加をコミットするプロシージャと似ていますが、ダイナセットがEdit
メソッドにより編集モードに設定されて新規ダイナセット値が割り当てられる点が異なります。
追加と更新では、同じコミット・ボタンおよび同じコミット・イベント・プロシージャが使用されるため、追加と更新を区別するために2つのグローバル・フラグDoAdd
とDoUpdate
が追加されます。「Add」および「Update」のクリック・イベント・プロシージャで、これらのフラグが設定されます。
追加と更新のコミット・イベント・プロシージャでは、次の処理を実行する必要があります。
DoValidationChecks()
ファンクションを前述と同様に使用した、入力データの検証。
レコードの追加にはAddNew
、更新にはEdit
の使用。
前述と同様にUpdateDynasetFields()
を使用してFields().Value
プロパティを使用した、ダイナセット・フィールドへの入力データの割当て。
Update
を使用した、新規レコードでのデータベースの更新。
「Commit」ボタンの無効化。
「Add」ボタンおよび「Update」ボタンを含む、他のすべての機能ボタンの再有効化。
DoUpdate
およびDoAdd
フラグのFalse
への設定。
手順5から手順7に示すボタンおよびフラグの状態を変更するコードは、SetAfterCommitFlags()
と呼ばれる新規サブルーチンで提供されます。これにより、最初にCommit
およびAddNew
を有効化したコード行が置き換えられます。
このCommitファンクションのコードは、次のルーチンに分かれます。
DoValidationChecks( )ファンクション。元のCommit
ファンクションでも使用。
UpdateDynasetFields( )ファンクション。元のCommit
ファンクションでも使用。
SetAfterCommitFlags()サブルーチンの例。新規サブルーチン。
次の例は、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
次の例は、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()
イベント・プロシージャでは、次の処理を実行する必要があります。
入力文字列と一致するENAME
列を持つレコードを検索するためのfind句の構築。
FindFirst
メソッドを使用した、検索の実行。
該当するレコードが見つかった場合のレコードの表示。見つからなかった場合のメッセージの表示および現在の行の最初の行への再設定。
次の例は、典型的な検索クリック・イベント・プロシージャを示しています。
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
この項では、バッチ挿入フォームおよび使用されるファンクションについて説明します。
バッチ挿入フォームにより、ユーザーは、バッチ操作で行を挿入(1つのコマンドのみを使用して複数のレコードをデータベースに挿入)できます。この機能は、パラメータ配列およびSQL文を使用して実装されます。
表6-1に、一般的なバッチ挿入フォームを示します。
ユーザーは、従業員フォーム上の「Batch Insert」ボタンをクリックすることにより、バッチ挿入フォームにナビゲートします。バッチ挿入フォームには、入力済データを表示するグリッドと、ユーザーがレコードを入力するフィールド行が設けられています。例では、簡潔にするために、ユーザーには「Employee Number」、「Employee Name」および「Department Number」フィールドへの入力のみが許可されています。
ユーザーは、フィールドにレコードを入力し、「Add to Grid」ボタンをクリックします。プログラムにより、入力したレコードがグリッドに表示されます。バッチ全体をデータベースに挿入するには、ユーザーは「CommitGrid」ボタンをクリックします。
バッチ挿入フォームには、3つのプロシージャが使用されます。Form_Load()
プロシージャは、列ヘッダーでグリッドを初期化します。CmdAddtoGrid_click()
プロシージャは、入力データをフィールドからグリッドにコピーします。CommitGrid_Click()
プロシージャには、バッチ挿入に使用するパラメータ配列およびSQL文が含まれます。
次に、これらのプロシージャを示します。
次の例は、バッチ挿入の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_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()
プロシージャは、グリッドのデータをデータベースに挿入します。これを行うために、このプロシージャでは、グリッドの各列に対応する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()
イベント・プロシージャでは、次の処理を実行する必要があります。
AddTable
メソッドを使用した、各グリッド(データベース)列のパラメータ配列の定義。
ネステッド・ループ内でPut_Value
メソッド使用した、グリッド列要素のパラメータ配列へのコピー。
パラメータ配列要素をEMP
表へ挿入するための、CreateSQL
メソッドを使用したSQL文オブジェクトの作成。
SQL文実行エラーを識別するための、LastServerErrText
およびLastServerErr
プロパティの確認。
新規に挿入されたレコードを反映するための、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