【问题标题】:Creating Excel file with info from database使用数据库中的信息创建 Excel 文件
【发布时间】:2019-05-06 14:11:58
【问题描述】:

我有一个查询返回如下内容:

1    2    3    4    5    6    7
A.   B.   C.   D.   E.   F.   G.
Etc...
Etc...
N rows

我将查询存储在数据集上。然后我使用这样的东西创建 Excel 文件:

Sql=“select * from table”
Dim cmd As New SqlDataAdapter(Sql, con)
Dim ds As New DataSet
cmd.Fill(ds)

For i=0 To Tables(0).Rows.Count - 1
    For x=0 To ds.Tables(0).Columns.Count - 1
        ExcelFile.Cells(i+1;x+1)=ds.Tables(0).Rows(i).Item(j)
    Next
Next

代码工作正常,除了我还需要编写列标题名称(1、2、3、4 等)。我的第一个问题是如何添加标题?

主要问题...查询有时会返回超过 80k 的结果,因此按照 for 循环逻辑,我的代码将为每列运行 80k 次(在本例中为 7 次),这将给我一个缓慢的结果。

还有另一种快速填充 Excel 文件的方法吗?或者这是最好的方法?

【问题讨论】:

    标签: excel vb.net for-loop


    【解决方案1】:

    我使用以下:

    Dim sSql As String
    Dim tbl As ListObject
    
    'Declare a Connection object
    Dim cnDB As New ADODB.Connection
    
    'Declare a Recordset Object
    Dim rs As ADODB.Recordset
    
    ' Housekeeping, set the connection strings
    Set cnn = New ADODB.Connection
    cnn.Provider = "MSDASQL"
    cnn.CommandTimeout = 100
    
    Set tbl = ActiveSheet.ListObjects("Lookup")
    With tbl.DataBodyRange
        If .Rows.Count > 1 Then
            .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count).Rows.Delete
        End If
    End With
    
    ' Connect to the database and paste new data
    cnn.ConnectionString = "driver={};server={};uid={};pwd={};database={}"
    sSql = "SELECT BLAH BLAH "
    cnn.Open
    Set rs = cnn.Execute(sSql)
    
    ThisWorkbook.Worksheets("Lookup").Range("A2").CopyFromRecordset rs
    cnn.Close
    

    【讨论】:

      【解决方案2】:

      您可以访问DataTable 中每个ColumnColumnName 属性。例如,要在尽可能少地修改代码的情况下添加标题,您可以这样做:

      'Write ColumnName to the corresponding cell in row 1
      For x=0 To ds.Tables(0).Columns.Count - 1
          ExcelFile.Cells(1, x+1) = ds.Tables(0).Columns(x).ColumnName
      Next
      
      'Modded to start at the second row and fix index variable
      For i=1 To Tables(0).Rows.Count - 1
          For x=0 To ds.Tables(0).Columns.Count - 1
              ExcelFile.Cells(i+1, x+1) = ds.Tables(0).Rows(i).Item(x)
          Next
      Next
      

      不过,您担心它的性能是对的。 Excel 自动化的第一条规则是尽可能少地与 Excel 进行实际交互,因为每次交互都非常昂贵。

      假设您使用的是常规 Office Interop,您应该构建一个二维数组来表示查询中的值。然后,您在工作表中找到等效大小范围,并将该范围的值设置为数组。通过这种方式,您可以将数千次交互减少为一次。

      Dim rowCount = ds.Tables(0).Rows.Count
      Dim colCount = ds.Tables(0).Columns.Count
      
      Dim ws = ExcelFile
      
      Dim valueSet(,) As Object
      ReDim valueSet(rowCount - 1, colCount - 1)
      
      For row = 0 To rowCount - 1
          For col = 0 To colCount - 1
              valueSet(row, col) = ds.Tables(0).Rows(row).Item(col)
          Next
      Next
      
      'Set the entire set of values in a single operation
      ws.Range(ws.Cells(1, 0), ws.Cells(rowCount, colCount).Value = valueSet
      

      另外,如果您实际上使用 Excel 互操作或类似 NetOffice 的包装器,您应该查看 EPPlus 并查看它是否满足您的需求。它是一个与 OfficeOpenXML 一起使用的帮助程序库,甚至不需要安装 Excel。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-29
        • 2020-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-13
        • 1970-01-01
        相关资源
        最近更新 更多