excel vba对整个数组

时间:2017-05-15 14:50:26

标签: excel excel-vba vba

我有一个在Excel中循环运行的SQL查询。它在阵列很小的情况下工作。但是阵列现在大约有4000个项目,这会导致excel崩溃。有没有更好的方法来做到这一点,我错过了一些简单的方法来做到这一点

For k = 0 To ubound(sqlarray)

Dim conn As ADODB.Connection
Dim recst As ADODB.Recordset
Dim sqlstring As String

Set conn = New ADODB.Connection
Set recst = New ADODB.Recordset


conn.ConnectionString = "Driver={Client Access ODBC Driver (32-
bit)};System=mysys ;NAM=1;CurrentSchema=myschema;"
conn.Open


Sql = "Select ACCOUNT_NBR, ASSIGNED_TO from prodlib.gr_exp_account where 
account_nbr in ('" & sqlarray(k) & "' )"

Set recst.ActiveConnection = conn

recst.Open Sql, conn
Sheets("recst").Range("A" & k).CopyFromRecordset recst


conn.Close

Application.ScreenUpdating = True
Next k

End Sub

1 个答案:

答案 0 :(得分:0)

如上面的评论中所述,您应该提交单个SQL语句并获取单个结果集。循环遍历每个客户并为其提交SQL是不好的。

考虑以下内容:

Sub whatever(sqlArray as string)

    'initialize these outside your loop next time too
    Dim conn As ADODB.Connection
    Dim recst As ADODB.Recordset
    Dim sqlstring As String

    Set conn = New ADODB.Connection
    Set recst = New ADODB.Recordset


    conn.ConnectionString = "Driver={Client Access ODBC Driver (32-
    bit)};System=mysys ;NAM=1;CurrentSchema=myschema;"
    conn.Open

    'All the accounts in one list in one statement. Use array function 'Join' 
    'to make the array a comma delimited string (or comma with quotes as a delim)
    Sql = "Select ACCOUNT_NBR, ASSIGNED_TO from prodlib.gr_exp_account where 
    account_nbr in ('" & Join(sqlArray, "','") & "' )"

    Set recst.ActiveConnection = conn

    recst.Open Sql, conn

    'Drop the entire recordset in a sheet starting at "A1"
    Sheets("recst").Range("A1").CopyFromRecordset recst


    conn.Close

    Application.ScreenUpdating = True


End Sub

如果JOIN()的数组大小有问题,或者您的数据库抱怨您一次发送的帐户数量,您仍然可以循环,但使用更大的块:

Sub whatever(sqlArray As String)

    'initialize these outside your loop next time too
    Dim conn As ADODB.Connection
    Dim recst As ADODB.Recordset
    Dim sqlstring As String

    Set conn = New ADODB.Connection



    conn.ConnectionString = "Driver={Client Access ODBC Driver (32-bit)};System=mysys ;NAM=1;CurrentSchema=myschema;"
    conn.Open

    Dim k As Integer
    Dim chunk As Integer

    'Set this to how many accout numbers you can squeeze through in a single request safely
    chunk = 400

    For k = 1 To UBound(sqlArray) Step chunk

        'reset this object in the loop
        Set recst = New ADODB.Recordset

        'All the accounts in one list in one statement. Use array function 'Join'
        'to make the array a comma delimited string (or comma with quotes as a delim)
        Sql = "Select ACCOUNT_NBR, ASSIGNED_TO from prodlib.gr_exp_account where account_nbr in ('" & Join_With_Limit(sqlArray, "','", chunk, k) & "' )"

        Set recst.ActiveConnection = conn

        recst.Open Sql, conn

        Sheets("recst").Range("A" & k).CopyFromRecordset recst

        'close this for the next loop
        recst.close


    Next k
    conn.Close
    Application.ScreenUpdating = True


End Sub

Function Join_With_Limit(inArray As Variant, strDelim As String, intLimit As Integer, intOffset As Offset) As String
    Dim i As Integer

    For i = intOffset To intOffset + intLimit
        'make sure we are below the ubound of the array
        if i > uBound(inArray) Then Exit For

        'If this isn't the first thing we are adding, then stick the delimiter
        'before dropping in the value
        If i <> intOffset Then Join_With_Limit = Join_With_Limit + strDelim

        'Add the next item
        Join_With_Limit = Join_With_Limit + inArray(i)
    Next i

End Function