VBA - Использование Typeof ... Является ли ADODB.Recordset приводит к ошибке компиляции

Я создаю функцию с набором вспомогательных подфункций для создания объектов ADOX.Catalog, чтобы помочь мне автоматизировать создание базы данных Access.

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

Моя публичная функция принимает несколько объектов в качестве параметров, но мне нужно убедиться, что они на самом деле являются объектами ADODB.Recordset, прежде чем я начну их обрабатывать. Я сослался на статью msdn по адресу https://msdn.microsoft.com/en-us/library/s4zz68xc.aspx чтобы начать, и я пытаюсь использовать If TypeOf ... Is ADODB.Recordset в соответствии с рекомендацией статьи, но генерирует следующую ошибку:

Compile error:
User-defined type not defined

Вот фрагмент моего кода. Первая оскорбительная строка TypeOf adoRsColumns Is ADODB.Recordset:

Public Function ADOX_Table_Factory( _
ByVal strTblName As String, _
Optional ByVal adoRsColumns As Object, _
Optional ByVal adoRsIndexes As Object, _
Optional ByVal adoRsKeys As Object _
) As Object

'Init objects/variables.
Set ADOX_Table_Factory = CreateObject("ADOX.Table")

'Begin interactions with the new table object.
With ADOX_Table_Factory
    .Name = strTblName

    'Check if we've received an ADO recordset for the column(s).
    If TypeOf adoRsColumns Is ADODB.Recordset Then
        'Check that the recordset contains rows.
        If Not (adoRsColumns.BOF And adoRsColumns.EOF) Then
            'Loop through the column definitions.
            Do
                .Columns.Append ADOX_Column_Factory(adoRsColumns.Fields(0), adoRsColumns.Fields(1), adoRsColumns.Fields(2), adoRsColumns.Fields(3))
            Loop Until adoRsColumns.EOF
        End If
    End If

Мой поиск в Google не дал никаких результатов, которые помогли бы мне обойти эту ошибку. Я подтвердил, что этот код работает, если я установил ссылку на библиотеку ADO. Я также подтвердил, через TypeName функция, что объекты идентифицируются по имени как Recordset, Если я заменю TypeOf adoRsColumns Is ADODB.Recordset с TypeOf adoRsColumns Is Recordsetоднако тогда тест оценивает значение false, а нужный код не выполняется. Я не прибегал к сравнению строк TypeNameвыход, потому что, как указано в статье MSDN, TypeOf ... Is быстрее.

Спасибо заранее за любую помощь!

1 ответ

Решение

Напомним, что без ссылки ADO, включенной в ваш проект, вы получаете ошибку компиляции в этой строке:

If TypeOf adoRsColumns Is ADODB.Recordset Then

Без ссылки VBA не распознает ADODB.Recordset Ситуация в основном такая же, как если бы вы пытались объявить Dim rs As ADODB.Recordset без ссылки. Это объявление вызовет ту же ошибку компиляции.

Там нет способа использовать ADODB.Recordset как распознанный тип без ссылки.

В качестве альтернативного подхода вы можете создать пользовательскую функцию, чтобы проверить, поддерживает ли объект метод или свойство, доступное в ADODB.Recordset но не в DAO.Recordset

Этот проверяет, включает ли набор записей Supports метод. Этот метод доступен в ADODB но нет DAO Recordset,

Public Function IsAdoRecordset(ByRef pObject As Object) As Boolean
    Const adAddNew As Long = 16778240
    Dim lngTmp As Long
    Dim blnReturn As Boolean
    Dim strMsg As String

On Error GoTo ErrorHandler

    blnReturn = False
    If TypeName(pObject) = "Recordset" Then
        lngTmp = pObject.Supports(adAddNew)
        blnReturn = True
    End If

ExitHere:
    On Error GoTo 0
    IsAdoRecordset = blnReturn
    Exit Function

ErrorHandler:
    Select Case Err.Number
    Case 438  ' Object doesn't support this property or method
        ' leave blnReturn = False
    Case Else
        ' notify user about any other error
        strMsg = "Error " & Err.Number & " (" & Err.Description _
            & ") in procedure IsAdoRecordset"
        MsgBox strMsg
    End Select
    Resume ExitHere

End Function
Другие вопросы по тегам