根据其他单元格的值将SQL查询的结果粘贴到特定单元格中

时间:2018-04-12 18:38:50

标签: sql excel vba

因此,在我的工作簿主页中,我有一个包含时间的列,上午9:00等。我使用以下代码将从另一个工作簿复制的值粘贴到不同的单元格中,基于它的当天时间:

lPasteRow = Application.Match(CDbl(Time()), sht_Target.Range("A:A"), 1)
sht_Target.Cells(lPasteRow, 3) = rng_data.Value

这完全没问题。但只有部分数据来自另一个工作表。另一半来自SQL查询。查询本身运行完美,它们现在只粘贴到一个单元格中进行测试。我现在需要根据上面的时间将它们粘贴到特定的单元格中,就像上面的代码一样。如果以下是我的SQL查询子:

 Dim Sheet1 As Worksheet
Dim lastRow As Long
lastRow = ActiveSheet.UsedRange.Rows.Count
Set sht_Target = ThisWorkbook.Worksheets("Main Sheet")
Dim path As String

Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim SQLStr As String
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset



 Set Cn = New ADODB.Connection
 Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" &          Database_Name & ""


 rs.Open SQLStr, Cn, adOpenStatic

 With sht_Target.Range("Q2")
    .ClearContents
    .CopyFromRecordset rs
 End With

 rs.Close
 Set rs = Nothing
 Cn.Close
 Set Cn = Nothing

如何根据一天中的时间将结果粘贴到单元格中?

编辑:我应该澄清所有SQL查询都能正常工作并返回一个数字。总数或百分比。我只需要确保如果它是10AM然后结果进入第3行,因为A3表示上午10:00,依此类推。

1 个答案:

答案 0 :(得分:1)

由于您可以使用ADO,请考虑运行两个SQL查询:

  1. 转储到 Temp Sheet 表(预先创建)的SQL Server查询。

  2. 主表临时表匹配的Excel工作簿SQL查询。

  3. 但是,首先,调整聚合SQL查询以添加GROUP BY子句,其中每个 CallDate 出现在单独的行中,假设此字段要在Excel中匹配:

    SELECT CallDate, COUNT(Distinct Agent) AS AgentCount
    FROM dbo.five9calldataextractdaily 
    WHERE CallDate > CAST(GETDATE() AS DATE) AND CallType = 'Outbound'
    GROUP BY CallDate
    

    然后运行ADO连接,实际上考虑ADO功能,因为只有连接字符串和查询字符串发生变化。

    ADO 功能(包括工作表和copyrecordset范围单元格的参数)

    Function ADO_Call(strConn As String, strSQL As String, strWks As String, strCell As String)
    On Error GoTo ErrHandle
        Dim Cn As ADODB.Connection
        Dim Rs As ADODB.Recordset
        Dim i As Long
    
        Set Cn = New ADODB.Connection
        Set Rs = New ADODB.Recordset
    
        Cn.Open strConn
        Rs.Open strSQL, Cn, adOpenStatic
    
        With ThisWorkbook.Worksheets(strWks)            
           ' ROWS
           .Range(strCell).CopyFromRecordset Rs
    
           ' COLUMNS
           If strWks = "TEMP" Then
              For i = 1 To Rs.Fields.Count
                  .Cells(1, i) = Rs.Fields(i - 1).Name
              Next i
           End If
        End With
    
        ThisWorkbook.Save
    
    ExitHandle:
        Rs.Close: Cn.Close
        Set Rs = Nothing: Set Cn = Nothing
        Exit Function
    
    ErrHandle:
        MsgBox Err.Number & " - " & Err.Description, vbCritical
        Resume ExitHandle
    End Function
    

    SQL Server 连接(用于查询结果的临时暂存)

    Sub SQL_Server_Connect()
    On Error GoTo ErrHandle
        Dim Server_Name As String, Database_Name As String
        Dim strConn As String, strSQL As String
    
        Server_Name = "****"
        Database_Name = "****"    
    
        strConn = "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name
    
        strSQL = "SELECT CallDate, COUNT(Distinct Agent) AS AgentCount" _
                    & " FROM dbo.five9calldataextractdaily " _
                    & " WHERE CallDate > CAST(GETDATE() AS DATE) " _
                    & " AND CallType = 'Outbound' " _
                    & " GROUP BY CallDate"
    
        Call ADO_Call(strConn, strSQL, "TEMP", "A2")
    
    ExitHandle:
        Exit Sub
    
    ErrHandle:
        MsgBox Err.Number & " - " & Err.Description, vbCritical
        Resume ExitHandle
    End Sub
    

    Excel 匹配连接

    Sub Excel_Match()
    On Error GoTo ErrHandle
        Dim strConn As String, strSQL As String
    
        strConn = "DRIVER={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _
                    & "DBQ=" & ThisWorkbook.FullName & ";"
    
        strSQL = "SELECT t.AgentCount FROM [MAIN$] m " _
                  & " LEFT JOIN [TEMP$] t ON m.[CallDate] = t.[CallDate]"
    
        Call ADO_Call(strConn, strSQL, "MAIN", "Q2")
    
    ExitHandle:
        Exit Sub
    
    ErrHandle:
        MsgBox Err.Number & " - " & Err.Description, vbCritical
        Resume ExitHandle
    End Sub
    

    备注

    • 此解决方案假设您为可以访问安装了Excel驱动程序的Jet / ACE SQL Engine(Windows .dll文件)的Windows PC计算机运行Excel(检查Odbcad32.exe)。
    • Excel SQL查询取决于连接和选择子句中使用的两个工作表顶部的命名列标题。因此,为什么标题被添加到 TEMP 。根据需要调整名称。
    • 使用
    • LEFT JOIN代替INNER JOIN来保留原始Excel订单以及任何不匹配的行,这些行将返回时缺少 AgentCount 值。

    替代解决方案

    1. 如果Excel查询过于复杂,只需运行SQL Server查询并将结果转储到临时工作表中,然后使用INDEX(... MATCH(...))VLOOKUP()来对齐 CallDates 并检索 AgentCount 值。

    2. 在这两者之间使用介质,即MS Access,您可以在其中导入Excel工作表并在linked table上运行SQL Server查询到 dbo.five9calldataextractdaily ,然后{{1 Access查询中的两个数据源(顺便说一句 - 与Excel查询相同的引擎!)。