慢速运行的循环。寻找找到每次执行多个记录的方法

时间:2019-07-10 14:54:01

标签: sql excel vba loops

我有一本Excel工作簿,其中包含约5,000行数据。我有两个按钮映射到宏。一个按钮将删除表中的所有数据,然后将其从Excel Workbook重新插入,另一个按钮将仅基于唯一ID插入“新”行。

我发现这两个按钮都需要很长时间才能运行。 〜10-15分钟。现在,它正在为每一行执行插入操作,但是我希望将其合并。

基本上,我想遍历约100个左右的行,然后插入。然后遍历下一百行并插入。

任何建议将不胜感激。 VBA /编码通常不是我的强项,我在这上面拉了一堵墙。

谢谢!

Sub Rebuild_Click()

' ***********************
' ** Declare Variables **
' ***********************
    Dim conn As New ADODB.Connection
    Dim iRowNo As Integer
    Dim sSTATUS, sCHANNEL, sISSUE, sLOB, sDESC, sIN, sJN, sIS, sPRIME, sIU, sTR, sAU As String
    Dim answer, sQTY, sRRSC, sOA, sMeetings, sOutages As Integer
    Dim sDATE As Date
    With Sheets("OASYS ADMIN TRACKER")

' ****************************
' ** Show Information Popup **
' ****************************
        answer = MsgBox("You are about to update the database with ~5,000 records." & vbCrLf & "" & vbCrLf & "This will take approximately 5 minutes." & vbCrLf & "" & vbCrLf & "If you wish to continue, please press Yes. Otherwise, Press No" & vbCrLf & "" & vbCrLf & "----------" & vbCrLf & "EXCEL IS NOT FROZEN." & vbCrLf & "" & vbCrLf & "****DO NOT CLOSE EXCEL ****", vbYesNo + vbQuestion, "Update Database")

' ***********************
' ** Open IF Statement **
' ***********************
        If answer = vbYes Then

            ' ***********************
            ' ** Connection String **
            ' ***********************
                conn.Open "Provider=SQLNCLI11;Password=XXXXX;User ID=XXXXX;Initial Catalog=SupportAdmin;Data Source=tcp:XXXXX;"

            ' *************************
            ' ** Purge Existing Data **
            ' *************************
                conn.Execute "Delete FROM dbo.TestDB"

            ' *********************
            ' ** Skip Leader Row **
            ' *********************
                iRowNo = 4

            ' ************************
            ' ** Begin Dataset Loop **
            ' ************************
                Do Until .Cells(iRowNo, 3) = ""
                    sID = .Cells(iRowNo, 1)
                    sSTATUS = .Cells(iRowNo, 2)
                    sDATE = .Cells(iRowNo, 3)
                    sCHANNEL = .Cells(iRowNo, 4)
                    sISSUE = .Cells(iRowNo, 5)
                    sQTY = .Cells(iRowNo, 6)
                    sLOB = .Cells(iRowNo, 7)
                    sDESC = .Cells(iRowNo, 8)
                    sIN = .Cells(iRowNo, 9)
                    sJN = .Cells(iRowNo, 10)
                    sIS = .Cells(iRowNo, 11)
                    sPRIME = .Cells(iRowNo, 12)
                    sIU = .Cells(iRowNo, 13)
                    sTR = .Cells(iRowNo, 14)
                    sAU = .Cells(iRowNo, 15)
                    sRRSC = .Cells(iRowNo, 16)
                    sOA = .Cells(iRowNo, 17)
                    sOutages = .Cells(iRowNo, 18)
                    sMeetings = .Cells(iRowNo, 19)

            ' ***********************
            ' ** Replace ' in Data **
            ' ***********************
                sDESC = Replace(sDESC, "'", "''")
                sIS = Replace(sIS, "'", "''")
                sIU = Replace(sIU, "'", "''")

            ' *****************
            ' ** Execute SQL **
            ' *****************
                conn.Execute "insert into dbo.TestDB (ID,STATUS,DATE,CHANNEL,ISSUE,QTY,LOB,[DESC],[IN],JN,[IS],PRIME,IU,TR,AU,RRSC,OA,OUTAGES,MEETINGS) " & _
                             "values ('" & sID & "','" & sSTATUS & "', '" & sDATE & "','" & sCHANNEL & "', '" & sISSUE & "', '" & sQTY & "', '" & sLOB & "', '" & sDESC & "', '" & sIN & "', '" & sJN & "', '" & sIS & "', '" & sPRIME & "', '" & sIU & "', '" & sTR & "', '" & sAU & "', '" & sRRSC & "', '" & sOA & "', '" & sOutages & "', '" & sMeetings & "')"

                iRowNo = iRowNo + 1
             Loop

' ****************************
' ** Show Information Popup **
' ****************************
        MsgBox "Database Update Complete!"

' *****************************
' ** Close Connection String **
' *****************************
        conn.Close
        Set conn = Nothing

' ****************************
' ** Close IF Statement **
' ****************************
        Else
           ' do nothing
     End If

    End With

End Sub

1 个答案:

答案 0 :(得分:0)

在本地SQL Server 2005中使用临时表对代码进行了尝试,发现仅花费10秒即可处理大约5000条记录。对于您而言,延迟可能是由于数据库大小,网络速度等引起的。

但是,尝试使用代码一次插入100条记录之后,该时间减少到仅1个奇数秒。

Sub test2()
Dim conn As New ADODB.Connection
Dim LastRow As Long, LastCol As Long, iRowNo As Long, DataArr As Variant
Dim SqStr As String, ValStr As String, Rw As Long, Cl As Long
Dim Ws As Worksheet, tm As Double
tm = Timer

conn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;;Initial Catalog=test;Data Source=USER-PC\SQLEXPRESS"
conn.Execute "Delete FROM dbo.Test"

Set Ws = ThisWorkbook.Worksheets("Sheet1")
iRowNo = 4
LastRow = Ws.Range("C" & Rows.Count).End(xlUp).Row
DataArr = Ws.Range("A" & iRowNo & ":S" & LastRow)
LastCol = UBound(DataArr, 2)

SqStr = "insert into dbo.Test (ID,STATUS,DATE,CHANNEL,ISSUE,QTY,LOB,[DESC],[IN],JN,[IS],PRIME,IU,TR,AU,RRSC,OA,OUTAGES,MEETINGS) "
'Sqlstr=Sqlstr & " Values "  'May use for Sql Server 2008 and above

    For Rw = 1 To UBound(DataArr, 1)
    DataArr(Rw, 1) = Replace(DataArr(Rw, 1), "'", "''")
    DataArr(Rw, 8) = Replace(DataArr(Rw, 8), "'", "''")
    DataArr(Rw, 13) = Replace(DataArr(Rw, 13), "'", "''")
    'ValStr = ValStr & "('"   'May use for Sql Server 2008 and above
    ValStr = ValStr & "Select '"
        For Cl = 1 To UBound(DataArr, 2)
        'ValStr = ValStr & DataArr(Rw, Cl) & IIf(Cl < LastCol, "','", "')")  'May use for Sql Server 2008 and above
        ValStr = ValStr & DataArr(Rw, Cl) & IIf(Cl < LastCol, "','", "'")   ' Used for test in Sql Server 2005
        Next Cl

        If Rw Mod 100 = 0 Then  ' exceute at 100 records
        ValStr = SqStr & ValStr
        conn.Execute ValStr
        DoEvents
        ValStr = ""
        Debug.Print Rw, Timer - tm
        Else
            If Rw < UBound(DataArr, 1) Then
            'ValStr = ValStr & ", "  'Modify Comma / Space between datasets of two rows according Sql version Syntax
            ValStr = ValStr & " UNION ALL "  'Used for test with Sql Server 2005.
            End If
        End If
    Next Rw

    If Rw Mod 100 > 0 Then
    ValStr = SqStr & ValStr
    conn.Execute ValStr
    DoEvents
    ValStr = ""
    Debug.Print Rw, Timer - tm
    End If


Debug.Print "Total Seconds Taken: " & Timer - tm
End Sub

请根据您使用的类型和版本以及@Raymond Nijland注释中的建议,修改INSERT SQl语法以及连接字符串等。