代码之家  ›  专栏  ›  技术社区  ›  David B

Excel存储过程调用中的重复行

  •  0
  • David B  · 技术社区  · 7 年前

    我有一个存储过程调用,它通过Excel复制行,我认为这与我用于从记录集复制的方法有关。运行查询时的数据手动输出正确的数据。

    Private Sub Refresh_Click()
        Dim Conn As ADODB.Connection, RecordSet As ADODB.RecordSet
    
        Dim Command As ADODB.Command
        Dim ConnectionString As String, StoredProcName As String
        Dim StartDate As ADODB.Parameter, EndDate As ADODB.Parameter
    
        Application.ScreenUpdating = False
    
        Set Conn = New ADODB.Connection
        Set RecordSet = New ADODB.RecordSet
        Set Command = New ADODB.Command
    
        ' I blanked out the details here as they are not required as this is working
        ConnectionString = "PROVIDER=SQLOLEDB;DATA SOURCE=xxxx;INITIAL CATALOG=xxxx; User Id=xxxx;Password=xxxx;"
    
        On Error GoTo CloseConnection
    
        Conn.Open ConnectionString
        SellStartDate = Format(Sheets("Sheet1").Range("B2").Value2, "yyyy-mm-dd")
        SellEndDate = Format(Sheets("Sheet1").Range("B3").Value2, "yyyy-mm-dd")
        StoredProcName = "fsp_PLReportByDates"
    
        With Command
            .ActiveConnection = Conn
            .CommandType = adCmdStoredProc
            .CommandText = StoredProcName
        End With
    
        Set StartDate = Command.CreateParameter("@DateFrom", adDBDate, adParamInput, , SellStartDate)
        Set EndDate = Command.CreateParameter("@DateTo", adDBDate, adParamInput, , SellEndDate)
    
        Command.Parameters.Append StartDate
        Command.Parameters.Append EndDate    
        Set RecordSet = Command.Execute    
    
        Sheets("Sheet1").Range("A7").CopyFromRecordset RecordSet
        For intColIndex = 0 To RecordSet.Fields.Count - 1
           Range("A6").Offset(0, intColIndex).Value = RecordSet.Fields(intColIndex).Name
        Next
    
    
        RecordSet.Close
        Conn.Close
        On Error GoTo 0
        Application.ScreenUpdating = True
        Exit Sub
    
        CloseConnection:
         Application.ScreenUpdating = True
         MsgBox "SQL Stored Procedure Did Not Execute Sucessfully!", vbCritical, "SQL Error"
         Conn.Close
    
    End Sub
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   JNevill    7 年前

    假设您的旧记录集/上一次拉取大于新记录集,并且当您将新记录放在旧记录集上时,一些旧记录仍存在于工作表中…

    创建一个随数据动态增长的命名范围。假设您的进程中有10列返回,并且有任意数量的行,那么就创建一个名为 rng_PLReportByDates 设置为:

    =OFFSET(Sheet1!$A$7, 0, 0, COUNTA(Sheet1!$A$7:$A$5000)+1, 10)
    

    这将创建一个命名范围,该范围有10列,最多4993行。我想这对你的记录集来说已经足够了,否则就取消它。 5000 任何有意义的。这个 +1 是否只是为了确保如果范围完全为空(没有值),则此公式将至少返回1行,否则将出错。

    那么……跑步前:

    Sheets("Sheet1").Range("A7").CopyFromRecordset RecordSet
    

    添加此:

    Range("rng_PLReportByDates").ClearContents
    

    你也可以改变 CopyFromRecordset 要使用新的动态大小命名范围:

    Range("rng_PLReportByDates").CopyFromRecordset Recordset
    

    每次将记录集转储到工作表时都使用此方法。我使用相同的公式创建一个动态大小的命名范围,然后 .ClearContents .CopyFromRecordset 对它。

    如果列数发生变化,则可以添加 Counta() 命名范围公式中最后一个参数的公式:

    =OFFSET(Sheet1!$A$7, 0, 0, COUNTA(Sheet1!$A$7:$A$5000)+1, COUNTA(Sheet1!$A$7:$IV$7)+1)
    

    就标题而言,您可能需要调整命名范围,使其位于行之后。 6 . 然后你可以做:

     Range("rng_PLReportByDates").ClearContents
     Range("rng_PLReportByDates").Offset(1).CopyFromRecordset Recordset
    

    然后做同样的范围工作。