3

MS Access VBA (2007) で、DAO レコードセットを切断されたインメモリ ADO レコードセットに変換する関数を以下に記述しました。問題は、DAO dbDecimal フィールドでデータ型変換の問題が発生していることです。DAO レコードセットから新しく作成された ADO レコードセットにデータを挿入しようとすると、問題が発生します。タイプ DAO dbDecimal (ADO adNumeric) の列に到達すると、次のエラーが発生します。

Error -2147217887 (80040e21): 
Multiple-step operation generated errors. Check each status value.

私が見たところ、この列に到達するたびにエラーが発生します。この列に含まれるデータは、25、44、60 などの単純な数字です。

以下に示すように、NumericScale と Precision をハードコーディングしましたが、これは何の役にも立たないようです。

Public Function ConvertDAORStoADORS(ByRef r1 As DAO.Recordset) As ADODb.Recordset

    If Not r1 Is Nothing Then

        Dim ra As ADODb.Recordset
        Set ra = New ADODb.Recordset

        Dim f1 As DAO.Field, fa As ADODb.Field

        For Each f1 In r1.Fields
            Select Case f1.Type
                Case dbText
                    ra.Fields.Append f1.Name, adVarWChar, f1.Size, adFldIsNullable
                Case dbMemo
                    ra.Fields.Append f1.Name, adLongVarWChar, 10000, adFldIsNullable

                'Here's the problematic one
                Case dbDecimal
                    ra.Fields.Append f1.Name, adNumeric, , adFldIsNullable
                    Set fa = ra.Fields(f1.Name)
                    fa.NumericScale = 19
                    fa.Precision = 4

                Case 9, dbLongBinary, dbAttachment, dbComplexByte, dbComplexInteger, dbComplexLong, dbComplexText, dbComplexSingle, dbComplexDouble, dbComplexGUID, dbComplexDecimal
                    'Unsupported types
                Case Else
                    Debug.Print f1.Name & " " & f1.Type
                    ra.Fields.Append f1.Name, GetADOFieldType(f1.Type), , adFldIsNullable

            End Select
        Next f1
        ra.LockType = adLockPessimistic
        ra.Open
        'On Error Resume Next
        If Not (r1.EOF And r1.BOF) Then
            r1.MoveFirst
            Do Until r1.EOF = True
                ra.AddNew
                For Each f1 In r1.Fields
                    'Error -2147217887 (80040e21) Multiple-step operation generated errors. Check each status value.
                    'Error only occurs on dbDecimal/adNumeric fields
                    ra(f1.Name).value = r1(f1.Name).value
                Next f1
                ra.Update
                r1.MoveNext
            Loop
        End If

        Set ConvertDAORStoADORS = ra
    End If

End Function

Private Function GetADOFieldType(daofieldtype As Integer) As Long
    Select Case daofieldtype
        'Fixed width adWChar does not exist
        Case dbText: GetADOFieldType = adVarWChar
        Case dbMemo: GetADOFieldType = adLongVarWChar
        Case dbByte: GetADOFieldType = adUnsignedTinyInt
        Case dbInteger: GetADOFieldType = adSmallInt
        Case dbLong: GetADOFieldType = adInteger
        Case dbSingle: GetADOFieldType = adSingle
        Case dbDouble: GetADOFieldType = adDouble
        Case dbGUID: GetADOFieldType = adGUID
        Case dbDecimal: GetADOFieldType = adNumeric
        Case dbDate: GetADOFieldType = adDate
        Case dbCurrency: GetADOFieldType = adCurrency
        Case dbBoolean: GetADOFieldType = adBoolean
        Case dbLongBinary: GetADOFieldType = adLongVarBinary
        Case dbBinary: GetADOFieldType = adVarBinary
        Case Else: GetADOFieldType = adVarWChar
    End Select
End Function

MS SQL Server 2008 にリンクされている ODBC リンク テーブルから DAO レコードセットを取得しています。フィールドは実際には SQL Server Decimal(19,4) データ型です。

この問題を回避する方法はありますか?

4

1 に答える 1

1

これは私にとってはうまくいきますが、テーブルから ADODB レコードセットを作成して切断するだけではない理由がわかりません。

  Case dbDecimal
      ra.Fields.Append f1.Name, adDecimal, , adFldIsNullable
      Set fa = ra.Fields(f1.Name)
      fa.NumericScale = 19
      fa.Precision = 4

また、なぜですか

    Dim ra As New ADODb.Recordset
    ''Set ra = New ADODb.Recordset
于 2012-05-20T08:55:33.340 に答える