4

Excel VBA初心者ですが、よろしくお願いします。

コーディングの重複を避けるために、オープンとデータベース接続に共通の関数と、それを閉じる別の関数を作成する方法を教えてください。


これが私のコードです。先に進む方法に困っています...

Const connection_string As String = "Provider=SQLOLEDB.1;Password=XXX;Persist Security              `Info=True;User ID=sa;Initial Catalog=TESTDB;Data Source=XXXX;"

Sub DuplicateDBConnection()

'Declare variables
Set cn1 = New ADODB.Connection
Set cmd1 = New ADODB.Command
Set rs1 = New ADODB.Recordset

'Open Connection
cn1.ConnectionString = connection_string
cn1.Open

'Set and Excecute SQL Command
Set cmd1.ActiveConnection = cn1
cmd1.CommandText = "Select stock_code, name, sector_id from stock_master"
cmd1.CommandType = adCmdText
cmd1.Execute

'Open Recordset
Set rs1.ActiveConnection = cn1
rs1.Open cmd1

'Copy Data to Excel
ActiveSheet.Range("A1").CopyFromRecordset (rs1)

'Close Connection
rs1.Close
cn1.Close

'Throw Object
Set rs1 = Nothing
Set cn1 = Nothing

End Sub

私の願いは、接続して接続を閉じるためにコードを書き続ける必要がないように、一般的な関数を書くことです。

Sub ConnectDB()
    'Codes to connect DB
End Sub

Sub CloseConnnection()
    'Codes to close connection
End Sub

Sub ExecuteCode()
    ConnectDB
    'Execute SQL command to manipulate data on excel and SQL database 
    CloseConnection
End Sub 

Kittoe の提案に基づいて編集し、適切に動作するようになりました。ありがとう!

  1. クラス: A. a. AdoDbHelper と呼ばれるクラス、Private Instancing を作成しました。AdoDbHelper で、「Option Compare Database」を「Option Compare Text」に変更します。

  2. モジュール: このような関数を作成します。

以下のコード:

Const connection_string As String = "Provider=SQLOLEDB.1;Password=XXX;Persist Security              `Info=True;User ID=sa;Initial Catalog=TESTDB;Data Source=XXXX;"

Sub Test()

Dim sourceDb As New AdoDbHelper
Dim sourceRs As New ADODB.Recordset

sourceDb.Connect (connection_string)

Set sourceRs = sourceDb.OpenRecordset("Select stock_code, name, sector_id from     stock_master")

With sourceRs
    'Do stuff!

     ActiveSheet.Range("A1").CopyFromRecordset sourceRs

    .Close
End With

sourceDb.Disconnect

Set sourceRs = Nothing
Set sourceDb = Nothing

End Sub
4

2 に答える 2

6

この種のことは、クラスで行うのが最適です。「IDE」で VBA プロジェクトを右クリックし、[挿入] -> [クラス モジュール] に移動します。クラスに clsAdoHelper (ハンガリー記法が好きな場合)、AdoDbHelper などの意味のある名前を付けます。以下は、このクラスに入れるコードの例です。

Option Compare Database
Option Explicit

Private WithEvents conn As ADODB.Connection
Private WithEvents rs As ADODB.Recordset

Public Sub Connect(ConnectionString As String)
    If Not conn Is Nothing Then
        Debug.Print "A connection is already open."
        Exit Sub
    End If

    If ConnectionString = CurrentProject.Connection.ConnectionString Then
        Set conn = CurrentProject.Connection
    Else
        Set conn = New ADODB.Connection
        conn.Open ConnectionString
    End If
End Sub

Public Sub Disconnect()
    If Not conn Is Nothing Then
        If conn.State <> 0 Then
            conn.Close
        End If

        Set conn = Nothing
    End If
End Sub

Public Sub Execute(SQL As String)
    If conn Is Nothing Then
        Debug.Print "No connection open."
        Exit Sub
    End If

    conn.Execute (SQL)
End Sub

Public Function OpenRecordset(SQL As String, Optional CursorLocation As ADODB.CursorLocationEnum = adUseClient, Optional CursorType As ADODB.CursorTypeEnum = adOpenForwardOnly, Optional LockType As ADODB.LockTypeEnum = adLockReadOnly) As ADODB.Recordset
    If conn Is Nothing Then
        Debug.Print "No connection open."
        Exit Function
    End If

    If Not rs Is Nothing Then
        Debug.Print "A recordset is already open."
        Exit Function
    End If

    Set rs = New ADODB.Recordset

    With rs
        .CursorLocation = CursorLocation
        .CursorType = CursorType
        .LockType = LockType
        .Open SQL, conn
    End With

    Set OpenRecordset = rs
End Function

Public Sub BeginTransaction()
    conn.BeginTrans
End Sub

Public Sub CommitTransaction()
    conn.CommitTrans
End Sub

Public Sub RollbackTransaction()
    conn.RollbackTrans
End Sub

Private Sub conn_BeginTransComplete(ByVal TransactionLevel As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
    Debug.Print "Transaction started."
End Sub

Private Sub conn_CommitTransComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
    Debug.Print "Transaction committed."
End Sub

Private Sub conn_ConnectComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)

End Sub

Private Sub conn_Disconnect(adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)

End Sub

Private Sub conn_ExecuteComplete(ByVal RecordsAffected As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
    Debug.Print "SQL execution complete."
End Sub

Private Sub conn_RollbackTransComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
    Debug.Print "Transaction rolled back."
End Sub

新しいクラスを使用する:

Dim sourceDb As New AdoDbHelper
Dim sourceRs as New ADODB.Recordset

sourceDb.Connect (<insert connection string here>)

Set sourceRs = sourceDb.OpenRecordSet(<insert SQL string here>)

With sourceRs
    'Do stuff!

    .Close
End With

sourceDb.Disconnect

Set sourceRs = Nothing
Set sourceDb = Nothing

これは私が今まで書いた中で最高のコードというわけではありませんが、まずまずのスタートを切れるはずです。クラスの仕組みがよくわからない場合は、OOP と VBA のクラスについて少し調べることをお勧めします。ここには必要な biolerplate コードがまだ少し残っていますが、通常の作業の大部分はクラス メソッドで処理されています。データ操作ロジックを独自の関数に入れたい場合は、クラスを使用して作成した ADODB.Recordset オブジェクトを渡すことができます (これによりWITHブロックが置き換えられます)。

クラスが可能なADODB接続の一般的な接続/切断/例外処理のすべてを処理するように、そのようなロジックでクラスを汚染することはお勧めしません。そうすれば、他のプロジェクトで再利用できます = D.

于 2013-04-29T16:54:45.037 に答える
1

Microsoft ActiveX データ オブジェクト ライブラリ xx を使用します。

VBA ウィンドウで、[ツール] > [参照設定] > [Microsoft ActiveX Data Objects Library xx] に移動します。

私は通常、下位互換性のために 2.7 を使用します。ADODB オブジェクトを作成して、接続を開き、クエリ (選択/更新/削除/...) を実行し、クエリ結果 (レコード セットと呼ばれる) を Excel の残りの部分、テーブル、特定のセルに使用できるようになりました。

常に同じ接続を確実に使用するには、Public 接続オブジェクトを作成し、すべてのサブルーチンでそれを参照します。conn各サブルーチンで、最初に (私のADODB.Connectionオブジェクトである)によって既に設定されているかどうかを確認します。

If conn = Nothing Then Call Setup_Connection

サブルーチン Setup_Connection は次のようになります。

Private Sub Setup_Connection
    Dim strConnection as String

    If conn = Nothing Then
        'Choose your own database connection details
        strConnection = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _
                "Persist Security Info=False;" & _
                "Initial Catalog=DatabaseName;" & _
                "Data Source=DATABASESERVER"
        Set conn = New ADODB.Connection
        With conn
            .Open strConnection
            .CommandTimeout = 30
        End With
    End If
End Sub  
于 2013-04-29T15:18:32.853 に答える