大数据上传到服务器,更好的块?

我已经inheritance了一组excel VBAmacros,它们从电子表格中抓取数据并将数据上传到数据库(SQL DB)。 问题是数据“大”(特定表单上的46列* 10,500行)所花的时间太长了。 在我看来,将数据分块到数据库会更好,但这是正确的吗? 如果是的话,最好的办法是什么呢? 我目前正在试图封装下面的代码在一个for循环,把它分成500行,但它不是优雅的,因为VBA是我的特长。

Sub Upload_Claims() Dim SubmissionNumber As Integer Dim LoopVar As Integer, row As Integer Set cnnConn = New ADODB.Connection cnnConn.ConnectionString = "driver={SQL Server};server=" & Server & ";database=happyfunserver" cnnConn.Open SubmissionNumber = Sheets("Quality Check").Range("SubID").Value 'Upload HPL - PPL Set cmdCommand = New ADODB.Command Set cmdCommand.ActiveConnection = cnnConn With cmdCommand .CommandText = "Select * from losses where submission_id = " & SubmissionNumber .CommandType = adCmdText .Execute End With ' Open the recordset. Set rstRecordset = New ADODB.Recordset Set rstRecordset.ActiveConnection = cnnConn rstRecordset.Open cmdCommand, , adOpenStatic, adLockBatchOptimistic 'upload ' Sheets("PL").Select row = 8 Do While Range("C" & row).Value <> vbNullString With rstRecordset .AddNew .Fields("submission_id") = SubmissionNumber If Range("A" & row).Value <> vbNullString Then .Fields("tag_id") = Range("A" & row).Value End If If Range("B" & row).Value <> vbNullString Then .Fields("batch_tag_id") = Range("B" & row).Value End If If Range("C" & row).Value <> vbNullString Then .Fields("source") = Left(Range("C" & row).Value, 250) End If If IsDate(Range("D" & row).Value) Then .Fields("evaluation_date") = Range("D" & row).Value End If If Range("E" & row).Value <> vbNullString Then If Range("E" & row).Value = "HPL" Then .Fields("coverage_type_id") = 22 ElseIf Range("E" & row).Value = "PL" Then .Fields("coverage_type_id").Value = 2 End If End If '--------------' If Range("F" & row).Value <> vbNullString Then .Fields("claim_no") = Left(Range("F" & row).Value, 250) End If If Range("G" & row).Value <> vbNullString Then .Fields("claimant") = Left(Range("G" & row).Value, 200) End If 'upload layer' If Range("H" & row).Value <> vbNullString Then If UCase(Range("H" & row).Value) = "UNKNOWN" Then .Fields("layer_id") = 0 ElseIf UCase(Range("H" & row).Value) = "AAA" Then .Fields("layer_id") = 1 ElseIf UCase(Range("H" & row).Value) = "BBBBBB" Then .Fields("layer_id") = 2 ElseIf UCase(Range("H" & row).Value) = "CCCCC" Then .Fields("layer_id") = 3 ElseIf UCase(Range("H" & row).Value) = "DDDDDDDD" Then .Fields("layer_id") = 4 ElseIf UCase(Range("H" & row).Value) = "EEE" Then .Fields("layer_id") = 5 End If End If '-------------------' If Range("I" & row).Value <> vbNullString Then .Fields("aaaaaaaa_name") = Left(Range("I" & row).Value, 100) End If If IsNumeric(Range("J" & row).Value) And Range("J" & row).Value <> 0 Then .Fields("bbb_id") = Left(Range("J" & row).Value, 7) End If If Not IsError(Range("K" & row).Value) Then .Fields("ccc_id_verified") = Range("K" & row).Value End If If Not IsError(Range("L" & row).Value) Then If Range("L" & row).Value <> vbNullString And Range("L" & row).Value <> 0 Then .Fields("dddddddd_city") = Left(Range("L" & row).Value, 80) End If End If If Range("M" & row).Value <> vbNullString And Range("M" & row).Value <> 0 Then .Fields("eeeeeeee_fips") = Left(Range("M" & row).Value, 5) End If If Not IsError(Range("N" & row).Value) Then If Range("N" & row).Value <> vbNullString And Range("N" & row).Value <> 0 Then .Fields("ffffffff_stateabbr") = Left(Range("N" & row).Value, 2) End If End If If IsDate(Range("O" & row).Value) Then .Fields("gggggggg_date") = Range("O" & row).Value End If If IsDate(Range("P" & row).Value) Then .Fields("hhhhhh_date") = Range("P" & row).Value End If If IsNumeric(Range("Q" & row).Value) Or Range("Q" & row).Value = 0 Then .Fields("iiiiiiiii_paid") = Range("Q" & row).Value End If If IsNumeric(Range("R" & row).Value) Or Range("R" & row).Value = 0 Then .Fields("jjjjjjjjj_reserve") = Range("R" & row).Value End If If IsNumeric(Range("S" & row).Value) Or Range("S" & row).Value = 0 Then .Fields("kkkk_paid") = Range("S" & row).Value End If If IsNumeric(Range("T" & row).Value) Or Range("T" & row).Value = 0 Then .Fields("llll_reserve") = Range("T" & row).Value End If 'upload claim status' If Range("U" & row).Value <> vbNullString Then If UCase(Range("U" & row).Value) = "CLOSED" Then .Fields("status_id") = 1 ElseIf UCase(Range("U" & row).Value) = "OPEN" Then .Fields("status_id") = 0 ElseIf UCase(Range("U" & row).Value) = "REOPEN" Then .Fields("status_id") = 2 End If End If '---------------------------' If IsDate(Range("V" & row).Value) Then .Fields("closed_date") = Range("V" & row).Value End If If Range("W" & row).Value <> vbNullString Then .Fields("description") = Range("W" & row).Value End If If IsNumeric(Range("AN" & row).Value) Then .Fields("manual") = Range("AN" & row).Value End If If IsNumeric(Range("AB" & row).Value) Then .Fields("11111") = Range("AB" & row).Value End If If IsNumeric(Range("AC" & row).Value) Then .Fields("2222222") = Range("AC" & row).Value End If If IsNumeric(Range("AD" & row).Value) Then .Fields("33333333333") = Range("AD" & row).Value End If If IsNumeric(Range("AE" & row).Value) Then .Fields("444444444") = Range("AE" & row).Value End If If IsNumeric(Range("AF" & row).Value) Then .Fields("55555555") = Range("AF" & row).Value End If If IsNumeric(Range("AG" & row).Value) Then .Fields("666666666") = Range("AG" & row).Value End If If IsNumeric(Range("AH" & row).Value) Then .Fields("7777777777777") = Range("AH" & row).Value End If If IsNumeric(Range("AI" & row).Value) Then .Fields("other") = Range("AI" & row).Value End If If IsNumeric(Range("AJ" & row).Value) Then .Fields("88") = Range("AJ" & row).Value End If If IsNumeric(Range("AK" & row).Value) Then .Fields("cause") = Range("AK" & row).Value End If If IsNumeric(Range("AL" & row).Value) Then .Fields("dept") = Range("AL" & row).Value End If If IsNumeric(Range("AM" & row).Value) Then .Fields("outcome") = Range("AM" & row).Value End If If IsNumeric(Range("AS" & row).Value) Then .Fields("report_lag") = Range("AS" & row).Value End If If IsNumeric(Range("AT" & row).Value) Then .Fields("closed_lag") = Range("AT" & row).Value End If .Update End With row = row + 1 If row Mod 25 = 0 Then Application.StatusBar = "PL" & " - " & row DoEvents End If Loop Application.StatusBar = "Performing " & "PL" & " Batch Update..." rstRecordset.UpdateBatch '(Similar loop repeats for 5 different pieces) End Sub 

任何意见表示赞赏。 我尽量保持简短,但是当你不知道自己在做什么或者要走什么方向时很难。

根据我们的对话以及我认为你的代码是如何工作的,这里有一个未经testing的解决scheme,可以尝试通过将大量处理移动到SQL来加快速度。 不幸的是,你必须跳过你已有的logging集处理方法。 根据谷歌,你不能使用一个ADO.Recordset作为SQL查询的来源(他们在内存的不同部分,并没有看到对方)。 所以,你可以试试这个:

  1. 在您的SQL Server上创build一个临时表。 我们称之为TblStaging,因为为什么不。 这个登台表的数据types将只是大string字段,所以它可以容纳任何东西,包括错误。

  2. 在声明连接string之后,尝试使用JosiePbuild议的Insert语句将数据加载到TblStaging。 之后将所有的VBA注释掉。

  3. 制作一个.sql文件,根据VBA中的规则validation您的数据,然后将其移至您的永久性SQL表中。 (我假设你知道足够的SQL能够做到这一点。)因为这是所有现在在SQL而不是VBA,它应该更快。

  4. 这个SQL文件将不得不以某种方式运行。 如果您不想每次都手动执行此操作,则有两个选项(假设您已经足够使用SQL Server):
    4A。 找出如何从命令行运行.sql并运行从VBA调用该命令行的batch file。
    4B。 将其设置为定期经常性代理。