VBA: хранить результат запроса ODBC в коде, а не отображать его - PullRequest
0 голосов
/ 09 мая 2019

У меня есть следующий макрос, который принимает строковый аргумент 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

Для одного отчета япытаясь автоматизировать, первым шагом является запрос определенной метки времени из базы данных и убедитесь, что она показывает сегодняшнюю дату, прежде чем приступить к остальной части отчета.Я хочу, чтобы макрос делал это, но он просто возвращает значение временной метки, а не отображает it-- таким образом я могу записать его в оператор If для условного запуска следующегошаги отчета.

Есть ли способ выполнить запрос и сохранить возвращенную метку времени в переменной, а не отображать ее где-нибудь?В противном случае, я думаю, я просто покажу его где-нибудь, запросу значение, а затем удалю, потому что оно мне не нужно отображать.

1 Ответ

1 голос
/ 09 мая 2019

Решение ADODB

Чтобы получить данные из запроса в переменную, я бы использовал соединение ADODB и набор записей.Наборы записей имеют метод с именем GetRows , который возвращает данные из результатов запроса.

Ниже приведена функция, которую можно использовать для запроса ваших данных.Это берет ваш ConnectionString и ваш SQL-код и возвращает ваши данные в виде двумерного массива.

Для простоты объяснения ясделал эту функцию поздним связыванием.Чтобы установить раннее связывание, установите ссылку на объекты данных Microsoft ActiveX xx Library .

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

Проверка метки времени

Для проверки метки времени Iбудет абстрагировать это в свою формулу, возвращая логическое значение.Не совсем точно, как структурированы ваши данные или как вы хотите этого добиться, но ниже приведен пример того, что вы могли бы попытаться сделать.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...