Vb6 救命啊!将数据从一列复制到类似记录集中的同一列时出错

Vb6 救命啊!将数据从一列复制到类似记录集中的同一列时出错,vb6,copy,adodb,recordset,Vb6,Copy,Adodb,Recordset,我有一个例程,它读取一个记录集,并在类似的记录集中添加/更新行。例程首先将列复制到新记录集: 下面是创建新记录集的代码 For X = 1 To aRS.Fields.Count mRS.Fields.Append aRS.Fields(X - 1).Name, aRS.Fields(X - 1).Type, aRS.Fields(X - _ 1).DefinedSize, aRS.Fields(X - 1).Attributes Next X 非常直截了当。请注意

我有一个例程,它读取一个记录集,并在类似的记录集中添加/更新行。例程首先将列复制到新记录集:

下面是创建新记录集的代码

For X = 1 To aRS.Fields.Count
    mRS.Fields.Append aRS.Fields(X - 1).Name, aRS.Fields(X - 1).Type, aRS.Fields(X - _
          1).DefinedSize, aRS.Fields(X - 1).Attributes
Next X
非常直截了当。请注意名称、类型、DefinedSize和属性的复制

在代码的下面,(没有任何东西可以修改..之间的任何列)我将一行的值复制到新记录集中的一行,如下所示:

 For C = 1 To aRS.Fields.Count
     mRS.Fields(C - 1) = aRS.Fields(C - 1)
 Next C
当它到达最后一列,这是一个数字,它与“多步操作生成一个错误”消息垃圾


我知道MS说这是由提供程序生成的错误,在本例中是ADO 2.8。此时也没有与数据库的开放连接


我在拔这根头发上剩下的一点头发。。。(此时我并不关心列索引在一个循环中是'X',在另一个循环中是'C',等我解决了真正的问题后,我会更改它…)

猜测2:正确的行应该是

mRS.Fields(C - 1).value = aRS.Fields(C - 1).value


我的猜测是您有一个null,并且您没有正确对待dbnull类型。

在像这样打开合成记录集之前,您必须为
adDecimal
adNumeric
字段设置
精度和
数值刻度

For X = 1 To aRS.Fields.Count
    With aRS.Fields(X - 1)
        Select Case .Type
        Case adChar, adWChar, adBinary, _
                adVarChar, adVarWChar, adVarBinary, _
                adLongVarChar, adLongVarWChar, adLongVarBinary
            mRS.Fields.Append .Name, .Type, .DefinedSize, .Attributes
        Case adDecimal, adNumeric
            mRS.Fields.Append .Name, .Type, , .Attributes
            mRS.Fields(mRS.Fields.Count - 1).Precision = .Precision
            mRS.Fields(mRS.Fields.Count - 1).NumericScale = .NumericScale
        Case Else
            mRS.Fields.Append .Name, .Type, , .Attributes
        End Select
    End With
Next
仅供参考:您可能会从数据库中获得一个字段没有名称的记录集,例如

SELECT 5, 'No name'
SELECT 5 AS Col, 'Second' AS Col
但是ADO不允许在
Append
方法上使用空名称。您还可以从数据库中获取具有重复字段的记录集,例如

SELECT 5, 'No name'
SELECT 5 AS Col, 'Second' AS Col

在你的例子中,它也会在Append上爆炸。

请参阅我关于寻找替代方法的评论,但直接的答案是
字段
对象
精度和
数值刻度
属性需要设置。这是错误的再现,请取消注释这两行以修复错误:

Sub bfgosdb()

  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")
  With cat
    .Create _
        "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.mdb"
    With .ActiveConnection

      Dim Sql As String

      Sql = _
          "CREATE TABLE Test1 " & vbCr & "(" & vbCr & " col1 VARCHAR(255)," & _
          " " & vbCr & " col2 INTEGER, " & vbCr & " col3 DECIMAL(19,4)" & vbCr & ");"
      .Execute Sql

      Sql = _
          "INSERT INTO Test1 (col1, col2, col3) " & vbCr & "VALUES" & _
          " (" & vbCr & "'128000 and some change', " & vbCr & "128000, " & vbCr & "128000.1234" & vbCr & ");"
      .Execute Sql

      Sql = _
          "INSERT INTO Test1 (col1, col2, col3) " & vbCr & "VALUES" & _
          " (" & vbCr & "NULL, " & vbCr & "NULL, " & vbCr & "NULL " & vbCr & ");"
      .Execute Sql

      Sql = _
          "SELECT T11.col1, T11.col2, T11.col3 " & vbCr & "  FROM" & _
          " Test1 AS T11;"

      Dim aRS
      Set aRS = .Execute(Sql)

      Dim mRS
      Set mRS = CreateObject("ADODB.Recordset")

      Dim X As Long
      For X = 1 To aRS.Fields.Count
          mRS.Fields.Append aRS.Fields(X - 1).Name, aRS.Fields(X - 1).Type, aRS.Fields(X - _
                1).DefinedSize, aRS.Fields(X - 1).Attributes

'          mRS.Fields(mRS.Fields.Count - 1).NumericScale = aRS.Fields(X - 1).NumericScale  '
'          mRS.Fields(mRS.Fields.Count - 1).Precision = aRS.Fields(X - 1).Precision  '
      Next X

      mRS.Open

      Do While Not aRS.EOF

        mRS.AddNew

        Dim C As Long
        For C = 1 To aRS.Fields.Count
            mRS.Fields(C - 1) = aRS.Fields(C - 1)
        Next C

        aRS.MoveNext

      Loop

    End With
    Set .ActiveConnection = Nothing
  End With
End Sub

我用标准的“IF not IsNull(ColumnName)”进行了尝试,得到了相同的结果。。在本例中,该列是数值列,值为128000,并进行了一些更改。。。我还比较了两个列的大小和属性,所有的看起来都很好…见上面的一个想法,也就是columnname永远不会为空。。。该值可能为null,或者行中的字段可能不存在。“提供程序,在本例中为ADO 2.8”--不正确:提供程序将包含OLE DB提供程序、SQL Server本机客户端、ODBC驱动程序等,即“知道”数据源的组件。ADO在设计上是独立于数据源的,对源“一无所知”。创建新记录集…复制名称、类型、定义大小和属性…没有任何东西可以修改任何列…我正在将一行的值复制到新记录集中的一行中”--我想知道为什么要这么做!:)您是否考虑过a)使用其
Clone
方法克隆记录集?b) 是否使用其
Filter
属性筛选?c) 再次查询数据源?d) 将形状语法与MSDataShape OLE DB提供程序结合使用,以获得第二个记录集所需的替代(但非常类似)结构?效果非常好。我真的很感激有人在回答问题时尊重我的先验知识(或缺乏…)“问题”列是一个数字,而准确度正是解决问题的关键。非常感谢(那将是一个长的&不是一个整数…)