Excel单元格值作为动态查询值

时间:2019-06-13 14:14:44

标签: excel vba sql-server-2008

在我的Excel工作表中,我有一个按钮,该按钮运行SQL查询并返回与时钟交互的结果。我有两个名为attachToDocument: trueStartDate的单元格,它们被格式化为输入单元格。我希望该语句查看ActionDate列,并且仅返回那些单元格范围内的结果。

EndDate

我在 Private Sub CommandButton1_Click() Dim cnn As New ADODB.Connection Dim rst As New ADODB.Recordset Dim ConnectionString As String Dim StrQuery As String Dim StartDate As Date Dim EndDate As Date StartDate = Sheets("Sheet1").Range("B5").Value EndDate = Sheets("Sheet1").Range("B6").Value cnn.Open ConnectionString cnn.CommandTimeout = 900 StrQuery = "SELECT Employees.EmployeeID, Employees.First_Name, Employees.Last_Name, EmployeeTimeCardActions.ActionTime, EmployeeTimeCardActions.ActionDate, EmployeeTimeCardActions.ShiftStart, EmployeeTimeCardActions.ActionType FROM Employees LEFT OUTER JOIN EmployeeTimeCardActions ON Employees.EmployeeID=EmployeeTimeCardActions.EmployeeID WHERE ActionDate >StartDate AND ActionDate < EndDate ;" rst.Open StrQuery, cnn**** Sheets(1).Range("D3").CopyFromRecordset rst End Sub 上遇到语法错误,已标记为****。

2 个答案:

答案 0 :(得分:0)

更改查询字符串,以便您实际上在引用变量:

StrQuery = "SELECT Employees.EmployeeID, Employees.First_Name, 
 Employees.Last_Name, EmployeeTimeCardActions.ActionTime, 
 EmployeeTimeCardActions.ActionDate, EmployeeTimeCardActions.ShiftStart, 
 EmployeeTimeCardActions.ActionType FROM Employees LEFT OUTER JOIN 
 EmployeeTimeCardActions ON 
 Employees.EmployeeID=EmployeeTimeCardActions.EmployeeID WHERE ActionDate 
 > '" & StartDate & "' AND ActionDate < '" & EndDate & "';"

根据查询的数据库,您可能还需要将日期包装在'#中。

顺便说一句,通常最好对查询字符串进行参数设置,以避免sql注入的可能性。特别是因为您的输入机制是Excel范围。 Example

答案 1 :(得分:0)

仅通过ADO Command对象使用参数化,从而避免了连接或标点数据的需要。具体来说,将qmarks ?放在准备好的无数据SQL语句中,然后将其与包含您的 StartDate EndDate 值的参数绑定。请注意,使用这种方法,记录集是从Command.Execute(而不是Recordset.Open)调用中创建的。

Private Sub CommandButton1_Click()    
    Dim cnn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim cmd As New ADODB.Command                       ' NEW VARIABLE
    Dim ConnectionString As String, StrQuery As String
    Dim StartDate As Date, EndDate As Date    

    StartDate = Sheets("Sheet1").Range("B5").Value  
    EndDate = Sheets("Sheet1").Range("B6").Value    
    cnn.Open ConnectionString
    cnn.CommandTimeout = 900

    StrQuery = "SELECT e.EmployeeID, e.First_Name, e.Last_Name, " _
               & "     t.ActionTime, t.ActionDate, t.ShiftStart, t.ActionType " _
               & " FROM Employees e " _
               & " LEFT OUTER JOIN EmployeeTimeCardActions t " _
               & "       ON e.EmployeeID = t.EmployeeID " _
               & " WHERE ActionDate > ?  AND ActionDate < ?;"

    With cmd
        .ActiveConnection = cnn
        .CommandText = StrQuery
        .CommandType = adCmdText
        .Parameters.Append .CreateParameter("str_param", adDate, adParamInput, , StartDate)
        .Parameters.Append .CreateParameter("end_param", adDate, adParamInput, , EndDate)

        Set rst = .Execute                           ' CREATES RECORDSET
    End With

    Sheets(1).Range("D3").CopyFromRecordset rst

    rst.Close: cnn.Close
    Set rst = Nothing: Set cmd = Nothing: Set cnn = Nothing
End Sub