我是 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的建议进行编辑,现在可以正常工作了。谢谢!
类别: A。创建了一个名为 AdoDbHelper 的类,私有(private)实例化 b.在AdoDbHelper中,将“选项比较数据库”更改为“选项比较文本”
模块: 创建一个像这样的函数。
代码如下:
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
最佳答案
这种类型的事情最好在类里面完成。在“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 中的类进行一些研究。您会注意到,这里仍然有一些必要的生物板代码,但大部分正常工作已在类方法中为您完成。如果您想将数据操作逻辑放入它自己的函数中,您可以将您使用该类创建的 ADODB.Recordset 对象传递给它(这将替换 WITH
block )。
我不建议用这样的逻辑来污染类,因为您希望类处理任何可能的 ADODB 连接的所有通用连接/断开/异常处理。这样您就可以在其他项目中重用它=D。
关于function - 如何编写打开和关闭数据库连接的常用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16282219/