Lie*_*cin 4 excel vba recordset
有以下场景.我有一些表单,基本上有一些dropbox,列表等.我用ms sql db中的记录填充它们.但是,有没有办法只查询一次数据库并在整个应用程序生命周期中将记录存储为类的实例,而不是每次用户打开表单时查询?
连接如下:
Sub connection_test()
Dim Cn As ADODB.Connection
Dim Rs As ADODB.Recordset
Dim stSQL As String
stSQL = "SELECT * FROM dbo.Client"
Set Cn = New ADODB.Connection
With Cn
.CursorLocation = adUseClient
.Open CONNECTION_STRING
.CommandTimeout = 0
Set Rs = .Execute(stSQL)
End With
Rs.Close
Cn.Close
Set Rs = Nothing
Set Cn = Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)
有人可以为我建议一个解决方案吗?我可以看到来自交通繁忙的所有问题,而且大部分是不必要
如果您只想获得记录集,请将变量调整为标准模块中的公共变量
Public Rs As ADODB.Recordset
Sub connection_test()
Dim Cn As ADODB.Connection
Dim sSQL As String
If Rs.State = adStateClosed Then
sSQL = "SELECT * FROM dbo.Client"
Set Cn = New ADODB.Connection
With Cn
.CursorLocation = adUseClient
.Open CONNECTION_STRING
.CommandTimeout = 0
Set Rs = .Execute(sSQL)
End With
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
现在Rs将在项目的任何地方可用.您可以随时运行connection_test,如果它关闭了记录集,它将创建它.如果没有,你很高兴.
通常我的方法是创建自定义类.我将创建一个CClient类,从记录集(或其他地方)填充它,使用业务逻辑操作对象,然后将新值写回数据库.这样,我的业务逻辑都不依赖于我正在使用ado的事实.我可以切换到文本文件或Excel工作表作为数据存储,而不必担心代码中的所有依赖项.
例如,假设我有一个Access表:
ClientID, Autonumber
ContactFirst, String
ContactLast, String
Company, String
CityState, String
Volume, Double
Run Code Online (Sandbox Code Playgroud)
我创建了一个CClient类,其中包含表格中每个字段的属性.我还创建了一个CClients类来保存所有CClient实例.在标准模块中,您可能有这样的东西
Public gclsClients As CClients
Sub Main()
Set gclsClients = New CClients
'Fill the class
gclsClients.FillFromRS
'change some value
gclsClients.Client(1).Volume = 100
'write back to the database
gclsClients.WriteToDB
End Sub
Run Code Online (Sandbox Code Playgroud)
在我改变一个客户端的数量的地方,你会有更多的代码调用你的用户形式等等.基础知识是,加载类,做你需要的任何事情,然后把类数据写回数据库.我不会向你展示所有类代码,但在CClients中
Public Sub FillFromRS()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim clsClient As CClient
Const sSQL As String = "SELECT * FROM tblClient"
Set cn = New ADODB.Connection
cn.Open msCON
Set rs = cn.Execute(sSQL)
If Not rs.BOF And Not rs.EOF Then
rs.MoveFirst
Do While Not rs.EOF
Set clsClient = New CClient
With clsClient
.ClientID = rs.Fields("ClientID").Value
.ContactFirst = rs.Fields("ContactFirst").Value
.ContactLast = rs.Fields("ContactLast").Value
.Company = rs.Fields("Company").Value
.CityState = rs.Fields("CityState").Value
.Volume = rs.Fields("Volume").Value
End With
Me.Add clsClient
rs.MoveNext
Loop
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
此方法从数据库获取数据并填充一堆CClient实例.也在CClients中
Public Sub WriteToDB()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim clsClient As CClient
Dim sSQL As String
Set cn = New ADODB.Connection
cn.Open msCON
For Each clsClient In Me
sSQL = BuildUpdateSQL(clsClient)
cn.Execute sSQL
Next clsClient
End Sub
Private Function BuildUpdateSQL(clsClient As CClient)
Dim sReturn As String
With clsClient
sReturn = "UPDATE tblClient SET ContactFirst = '" & .ContactFirst & "',"
sReturn = sReturn & " ContactLast = '" & .ContactLast & "',"
sReturn = sReturn & " Company = '" & .Company & "',"
sReturn = sReturn & " CityState = '" & .CityState & "',"
sReturn = sReturn & " Volume = " & .Volume
sReturn = sReturn & " WHERE ClientID = " & .ClientID & ";"
End With
BuildUpdateSQL = sReturn
End Function
Run Code Online (Sandbox Code Playgroud)
此方法遍历所有CClient实例,创建UPDATE sql语句并执行它.您将要在CClient中实现某种IsDirty属性,以便您只更新那些更改了某些内容的客户端.CClients和CClient的其余部分是基本的类模块.
你可以调用WriteToDB很多或者一点点.在某些应用程序中,只要有变化,我就会编写它.在其他情况下,我只在工作簿关闭时回写到数据库.这取决于您的应用程序的流程.真正的美妙之处在于,如果您从Access数据库更改为用于数据存储的文本文件,您只需要更改为CClients中的方法.所有其余代码都使用CClients,而不关心数据的存在位置.
您可以在此处查看工作簿和Access数据库http://www.dailydoseofexcel.com/excel/ClientClassExample.zip
归档时间: |
|
查看次数: |
3445 次 |
最近记录: |