VBA: взаимодействовать с доступом из Outlook - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь создать несколько пользовательских кнопок в Outlook, которые взаимодействуют с таблицей, содержащейся в базе данных Access. Пока у меня есть кнопки, работающие в Outlook, выполняющие код, который создает собственный класс доступа к данным, который, в свою очередь, обрабатывает открытие и закрытие соединения с базой данных. Насколько я могу сказать, это много работает.

Однако из этого класса я даже не могу выполнить простой запрос выбора. Может кто-нибудь помочь мне понять, почему приведенный ниже код может не работать? Я всегда получаю набор записей, в котором нет строк, но если я запускаю тот же sql с помощью конструктора запросов Access, он работает нормально.

Public Function GetJobID(ByVal xEmailID As String) As Integer
'Returns the JobID associated with a given EmailID from the email link table.
'Returns a fail constant if no link exists.
    Dim rs As ADODB.Recordset
    Dim sql As String

    'Exit if not connected.
    'Cast to boolean because VBA doesn't recognise connection state integer as boolean.
    If Not CBool(mConn.State) Then
        GetJobID = RESULT_FAIL_INTEGER
        Exit Function
    End If

    sql = "SELECT [JobID] FROM [EMAIL_LINK_TABLE] WHERE [EmailID]='xEmailID'"
    sql = Replace(sql, "EMAIL_LINK_TABLE", EMAIL_LINK_TABLE)
    sql = Replace(sql, "xEmailID", xEmailID)

    On Error Resume Next
    Set rs = mConn.Execute(sql)

    If rs.RecordCount > 0 Then
        GetJobID = rs(1).Value
    Else
        GetJobID = RESULT_FAIL_INTEGER
    End If

End Function

1 Ответ

0 голосов
/ 12 ноября 2018

Я вижу, что вы отследили проблему до .RecordCount, возвращая -1.

Это стандартное поведение для динамических курсоров, начиная с документа :

Тип курсора объекта Recordset влияет на возможность определения количества записей. Свойство RecordCount вернет -1 для прямого курсора; фактическое количество для статического или клавишного курсора; и либо -1, либо фактическое число для динамического курсора, в зависимости от источника данных.

Конечно, вы можете изменить свой код для использования статического курсора, но это повлияет на производительность. Вместо этого, чтобы проверить, есть ли записи в вашем наборе записей, используйте .EOF (метод, возвращающий логическое значение, чтобы указать, находится ли набор записей в конце файла). Это избавит ваш код от необходимости загружать все записи, когда требуется только загрузка первой:

Public Function GetJobID(ByVal xEmailID As String) As Integer
'Returns the JobID associated with a given EmailID from the email link table.
'Returns a fail constant if no link exists.
    Dim rs As ADODB.Recordset
    Dim sql As String

    'Exit if not connected.
    'Cast to boolean because VBA doesn't recognise connection state integer as boolean.
    If Not CBool(mConn.State) Then
        GetJobID = RESULT_FAIL_INTEGER
        Exit Function
    End If

    sql = "SELECT [JobID] FROM [EMAIL_LINK_TABLE] WHERE [EmailID]='xEmailID'"
    sql = Replace(sql, "EMAIL_LINK_TABLE", EMAIL_LINK_TABLE)
    sql = Replace(sql, "xEmailID", xEmailID)

    On Error Resume Next 
    Set rs = mConn.Execute(sql)

    If Not rs.EOF Then
        GetJobID = rs(0).Value
    Else
        GetJobID = RESULT_FAIL_INTEGER
    End If

End Function
...