使用sql查询填充excel单元花了这么长时间

时间:2016-08-29 04:21:24

标签: sql-server excel vba

我有一个excel工作表,有很多行(比方说约80)。每行有大约30-31个柱子(取决于月份)。 Foreach row和foreach列它运行sql查询,如下所示:

    lastRow = ActiveSheet.Cells(Rows.Count, "D").End(xlUp).Row
    lastColumn = ActiveSheet.UsedRange.Column - 1 + ActiveSheet.UsedRange.Columns.Count

    'Do While Worksheets(2).Cells(12 + 0, 1) <> ""
    For i = 13 To lastRow
        For j = 6 To lastColumn

            kodp = Worksheets(2).Cells(i, 1)

            If Not conn.Execute("SELECT Realization FROm FRM_Raport WHERE EmployeeId=" & kodp & " AND Data=convert(varchar(10), '" & Worksheets(2).Cells(11, j) & "',121 )").EOF Then

                Worksheets(2).Cells(i, j) = Format(conn.Execute("SELECT Realization FROm FRM_RaportWHERE EmployeeId=" & kodp & " AND Data=convert(varchar(10),'" & Worksheets(2).Cells(11, j) & "',121)")!realization/ (60 * 24), "hh:mm")

            End If
        Next j
        i = i + 10
    Next i

问题是,它运行得如此之慢(整个区域大约需要15分钟)。我尝试过Do While循环但是花了更长的时间。我添加了:

Application.Calculation = xlCalculationManual

Application.ScreenUpdating = False

Application.DisplayStatusBar = False

Application.EnableEvents = False

ActiveSheet.DisplayPageBreaks = False

在sub的开头(ofc我在sub结束时将其关闭),但它没有帮助。任何想法如何提高性能?

Excel工作表的可视化:

 empty column |  2016-08-01  | 2016-08-02 | ... | 2016-08-30
 -----------------------------------------------------------
 kodp Emp1    |              |            | ... | 
 -----------------------------------------------------------
 kodp Emp2    |              |            | ... |    
 -----------------------------------------------------------
 kodp Emp3    |              |            | ... |        
      .
      .
      .

编辑!这是工作代码:

lastRow = ActiveSheet.Cells(Rows.Count, "D").End(xlUp).Row
lastColumn = ActiveSheet.UsedRange.Column - 1 + ActiveSheet.UsedRange.Columns.Count
sql = "INSERT INTO temp (colId,rowId,kodp,data) VALUES"
sql3 = "DELETE From temp"
conn.Execute sql3
For i = 13 To lastRow
    kodp = Worksheets(2).Cells(i, 1)
    For j = 6 To lastColumn
        data = Worksheets(2).Cells(11, j)
        sql = sql & "(" & j & "," & i & "," & kodp & ",'" & data & "'),"
    Next
    i = i + 10
Next
sql = Left(sql, Len(sql) - 1)
'MsgBox sql
conn.Execute sql
sql2 = "SELECT t.rowId,t.ColID,Realizacja From Fanar_Raport f INNER JOIN temp t on f.EmployeeId =  t.kodp and f.data=t.data"

Set tmp = conn.Execute(sql2)

Do Until tmp.EOF
    For Each fld In tmp.Fields
        Worksheets(2).Cells(tmp.Fields(0), tmp.Fields(1)) = tmp.Fields(2)
    Next fld
    tmp.MoveNext
Loop

tmp.Close
Set tmp = Nothing

1 个答案:

答案 0 :(得分:0)

您需要为所有相关员工执行一次SQL查询,然后浏览记录集并填充相应的行/列。

更新:(添加更多细节)

  1. 准备sql查询(字符串变量),如:

    插入#temp值((..,..,..,..),('..'..)

  2. 然后,一气呵成,

    1. 使用ColumnID,RowID,EmployeeID,Date
    2. 创建临时表
    3. 运行该脚本以填充临时表
    4. 运行SELECT FROM you table JOINing temp table ON t1.Employee = t2.Employee AND t1.Date = t2.Date
    5. 在SELECT中,您需要指定ColumnID(来自临时表),RowID(来自临时表)和您的实现。

    6. 最后,对于结果集中的每一行,提取列,行号和实现,并填充相应的单元格。

    7. 它应该需要几秒钟,甚至可能更少。