VBA:将ODBC查询结果存储在代码中,而不是显示它

时间:2019-05-09 14:16:37

标签: excel vba odbc

我有以下宏,它接受一个字符串参数code(它是一个SQL查询),并在我的Teradata服务器上执行它并显示结果。

Dim dest As Range
Set dest = ActiveCell

Dim timestamp As String
timestamp = Format(Now, "yyyyMMdd_h:mm:ss_AM/PM")

Dim queryName As String
queryName = "Query_" & timestamp

ActiveWorkbook.Queries.Add Name:=queryName, formula:= _
    "let" & Chr(13) & "" & Chr(10) & " Source = Odbc.Query(""dsn=my-server-name"", " _
    & Chr(34) & code & Chr(34) & ")" & Chr(13) & "" & Chr(10) & "in" & Chr(13) _
    & "" & Chr(10) & " Source"

With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
    "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" _
    & queryName & ";Extended Properties=""""" _
    , Destination:=Range(dest.Address)).QueryTable

    .CommandType = xlCmdSql
    .CommandText = Array("SELECT * FROM [" & queryName & "]")
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .BackgroundQuery = True
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .PreserveColumnInfo = False
    .Refresh BackgroundQuery:=False
End With

对于我要自动执行的报告,第一步是从数据库中查询特定的时间戳记,并确保在继续其余报告之前,它显示了今天的日期。我想要一个宏来做,但是让它只是返回时间戳值,而不是显示-这样我就可以将其写入If语句中以有条件地运行报告的后续步骤。

有没有一种方法可以执行查询并将返回的时间戳存储在变量中,而不是在任何地方显示?否则,我想我会把它显示在某个地方,询问该值,然后再删除它,因为我不需要显示它。

1 个答案:

答案 0 :(得分:1)

ADODB解决方案

要从查询中获取数据到变量中,我将使用ADODB连接和记录集。记录集具有称为 GetRows 的方法,该方法从查询结果中返回数据。

以下是可用于查询数据的函数。这将使用您的 ConnectionString 和您的 SQL代码,并以二维数组的形式返回数据。

  

为便于说明,我将此功能设置为后期绑定。要进行早期绑定,请设置对 Microsoft ActiveX数据对象x.x库的引用。

Private Function QueryDatabase(ByVal ConnectionString As String, ByVal Sql As String) As Variant

    On Error GoTo Catch


    'OPEN CONNECTION TO DATABASE
    Dim Connection As Object
    Set Connection = CreateObject("ADODB.Connection")
    Connection.ConnectionString = ConnectionString
    Connection.Open
    On Error GoTo CloseConnection 'MAKE SURE TO CLOSE CONNECTION ON ERRORS

    'OPEN DATA AND GET RECORDSET
    Dim Rs As Object
    Set Rs = CreateObject("ADODB.Recordset")
    With Rs
        .ActiveConnection = Connection
        .Source = Sql
        .LockType = 1 'adLockReadOnly - MAKES CONNECTION READ ONLY
        .CursorType = 0 'adOpenForwardOnly - FREQUENCY OF CHECKING DATABASE - SET TO ONCE
        .Open
        On Error GoTo CloseRecordset
    End With

    'RETURN QUERY RESULTS BACK INTO A TWO DIM ARRAY (DOES NOT INCLUDE HEADERS)
    QueryDatabase = Rs.GetRows

CloseRecordset:
    Rs.Close

CloseConnection:
    Connection.Close

    'CHECK IF ERROR OCCURED
    If Err.Number <> 0 Then
        GoTo Catch
    End If

    Exit Function
Catch:
    'HANDLE ERRORS HERE...

End Function

时间戳验证

为了验证您的时间戳,我会将其抽象为自己的公式,并返回一个布尔值。不能完全确定数据的结构或要实现的方式,但是下面是您可以尝试做的事情的蓝图。

Private Function TimestampValid() As Boolean

    Dim QueryName As String
    QueryName = "Query_" & timestamp

    Dim Connection As String
    Connection = "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & QueryName & ";Extended Properties="""""

    Dim Sql As String
    Sql = "SELECT * FROM [" & QueryName & "]"

    'DATA IS A TWO DIM ARRAY (MINUS THE HEADERS)
    Dim Data As Variant
    Data = QueryDatabase(Connection, Sql)

    'DO YOUR VALIDATION HERE...
    '(NOT SURE WHAT YOU ARE RETURNING SO I CAN'T DO IT FOR YOU)...

End Function