我有一个在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
答案 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