2

好的,所以我有一个电子表格,可以产生相当多的记录(~3500)

我有以下脚本将它们插入我的访问数据库:

Sub putinDB()
Dim Cn As ADODB.Connection, Rs As ADODB.Recordset
Dim MyConn, sSQL As String

Dim Rw As Long, c As Long
Dim MyField, Result
Dim x As Integer
Dim accName As String, AccNum As String, sector As String, holding As String,  holdingvalue As Double, holdingdate As Date
theend = lastRow("Holdings", 1) - 1
'Set source
MyConn = "S:\Docs\Harry\Engine Client\Engine3.accdb"
'Create query
Set r = Sheets("Holdings").Range("a2")
x = 0
Do
Application.StatusBar = "Inserting record " & x + 1 & " of " & theend
accName = r.Offset(x, 0)
AccNum = r.Offset(x, 4)
sector = r.Offset(x, 2)
holding = r.Offset(x, 1)
holdingvalue = r.Offset(x, 3)
holdingdate = r.Offset(x, 5)

sSQL = "INSERT INTO Holdings (AccName, AccNum, Sector, Holding, HoldingValue, HoldingDate)"
sSQL = sSQL & " VALUES ('" & Replace(accName, "'", "''") & "', '" & AccNum & "', '" & sector & "', '" & Replace(holding, "'", "''") & "', '" & holdingvalue & "', #" & holdingdate & "#)"
Debug.Print (sSQL)
 'Create RecordSet
Set Cn = New ADODB.Connection
With Cn
    .Provider = "Microsoft.ACE.OLEDB.12.0"
    .CursorLocation = adUseClient
    .Open MyConn
    Set Rs = .Execute(sSQL)
End With
x = x + 1
Loop While r.Offset(x, 0) <> "" Or x < 15
Application.StatusBar = False
End Sub

问题是,它逐个循环遍历每条记录,每次都重建并执行查询,这导致执行速度非常慢(我的 PC 上每秒大约 2-3 条记录)

有没有办法让vba一次性将整个范围插入数据库而不必循环?谢谢

4

2 回答 2

7

您提供的答案应该会稍微改善一些事情,因为您只需要打开一次连接,但代码仍然效率低下。您真的只想将所有数据写入您的记录集一次,而不是像这样。我总是更喜欢从 Access 端工作以从 Excel 中提取信息,而不是从 Excel 推入 Access,但我相信我们可以在这种情况下使用任何一种。

在这种情况下,您最好使用 DAO 而不是 ADO 并使用Transacation ,本质上您仍然循环遍历记录集,但写入数据的实际行为直到最后Commit才会发生,因此速度要快得多。

这是访问端的一个非常基本的示例,供您尝试:

Private Sub TestTrans()

Dim wksp    As DAO.Workspace
Dim rs      As DAO.Recordset

    Set wksp = DBEngine.Workspaces(0) 'The current database

    wksp.BeginTrans 'Start the transaction buffer

    Set rs = CurrentDb.OpenRecordset("Table1", dbOpenDynaset)

    Do 'Begin your loop here

    With rs
        .AddNew
            !Field = "Sample Data"
        .Update
    End With

    Loop 'End it here

    wksp.CommitTrans 'Commit the transaction to dataset

End Sub
于 2012-10-17T09:35:08.153 回答
4

好吧,我傻了。经过一番修修补补,事实证明,把

Set Cn = New ADODB.Connection
With Cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.CursorLocation = adUseClient
.Open MyConn
End With

循环外的位使其更快。

于 2012-10-17T09:07:53.117 回答