我有一个存储过程调用,该过程通过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
答案 0 :(得分:2)
假设您的旧记录集/上一记录拉取值大于新记录集,并且当您将新记录集/旧记录放在旧记录集上时,某些旧记录仍存在于工作表中...
创建一个随数据动态增长的命名范围。假设您的Proc中有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
然后您的范围也一样。