【问题标题】:Looping through an array and posting array to table循环遍历数组并将数组发布到表
【发布时间】:2021-07-15 14:56:34
【问题描述】:

我是一个老 Foxpro 程序员,我习惯使用数组来发布变量字段。

我想做的是在我设计的新表中有 15 个日期字段。
在我的查询中,我有一个活动日期的个人记录。

我想将每个 Client_id 的 15 个不同日期编译为一个包含 15 个日期的记录,但我似乎无法将表数据作为数组引用。
我尝试了几种不同的方法来定义数组,但似乎没有任何效果。

这是我的代码。在我的表中,我有 15 个日期字段,分别命名为 Mail_date1Mail_date2Mail_date3 等。
我首先尝试将它定义为一个数组,但不喜欢它;当我尝试引用结果表 rs2!mdate2 = memdate(intcounter) 中的日期字段时,我的代码总是失败

  1. 如何将我的结果表输出字段作为数组引用?

  2. 我是否必须放置一大堆 if 语句才能加载我的结果?
    好像很浪费......应该可以将它们作为数组加载。

我是一名新的 Access 2007 VBA 程序员。

Dim db As DAO.Database
Set db = CurrentDb
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset

Dim FinTotal, intcounter As Integer
Dim FinMPU, FinVersion As String
Dim mail_date(1 To 15) As Date
Dim memdate(1 To 15) As Date
Dim mdate2 As String

Set rs1 = db.OpenRecordset( _
            "SELECT NewFile.MPU_ID,   " & _
            "       NewFile.MAIL_DATE," & _
            "       NewFile.TOTAL,    " & _ 
            "       Freight.Version   " &_
            "FROM Freight " & _
            "  LEFT JOIN NewFile ON Freight.[MPU ID] = NewFile.MPU_ID " & _
            "ORDER BY NewFile.MPU_ID, NewFile.MAIL_DATE")

Set rs2 = db.OpenRecordset("Final")

DoCmd.RunSQL "DELETE Final.* FROM Final;"

intcounter = 1
memdate(intcounter) = rs1!mail_date
FinMPU = rs1!mpu_ID
FinTotal = rs1!total
FinVersion = rs1!Version
rs1.MoveNext

On Error GoTo Error_MayCauseAnError

Do While Not rs1.EOF
    Do While Not rs1.EOF _
             And memdate(intcounter) <> rs1!mail_date _
             And FinMPU = rs1!mpu_ID
        intcounter = intcounter + 1
        memdate(intcounter) = rs1!mail_date
        FinTotal = FinTotal + rs1!total
        FinVersion = rs1!Version
        FinMPU = rs1!mpu_ID
        rs1.MoveNext
    Loop

    If FinMPU <> rs1!mpu_ID Then
        rs2.AddNew
        mdate2 = "mail_date" & CStr(intcounter)
        rs2!mdate2 = memdate(intcounter)
        rs2!total = FinTotal
        rs2!mpu_ID = FinMPU
        rs2!Version = FinVersion
        rs2.Update

        FinTotal = rs1!total
        FinVersion = rs1!Version
        FinMPU = rs1!mpu_ID
        intcounter = 1
        memdate(intcounter) = rs1!mail_date
    End If
    rs1.MoveNext
Loop

【问题讨论】:

  • DAO 是一条死胡同。不要再将它用于新代码。
  • @Tomalak 嗯,不。对于使用 ACE 数据库引擎的本机 Access 应用程序,“Microsoft Office ... Access 数据库引擎对象库”(在 VBA 中映射到 DAO)仍然是默认和首选的访问方法。
  • @Gord IIRC 他们已切换到 ADO 作为 Access 2007 (?) 的默认库。
  • @Tomalak DAO 仍然是在 Access 2007/2010/2013 中处理数据的默认和本地方式,因为它已更新以支持新数据库格式的增强。当然,您对我们完全免费ADO;有些事情你可以在其中做而不能在另一个做,反之亦然。另见stackoverflow.com/questions/1039224/…
  • @RenaudBompuis 好的,感谢您提供的信息。

标签: ms-access vba


【解决方案1】:

首先,如果您期望并回答,您真的应该花更多时间正确格式化您的解释和代码...

现在,对于问题的一些评论和可能的答案:

  • 在记录集中打开该表之前,您应该DELETE FROM Final

  • 您应该明确您要打开的记录集的类型:

    ' Open as Read-only '
    Set rs1 = db.OpenRecordSet("...", dbOpenSnapshot)
    ' Open as Read/Write '
    Set rs1 = db.OpenRecordSet("...", dbOpenDynaset)
    
  • 您应该Dim memdate(1 To 15) As Variant 而不是Date,因为Date 数据类型不能是Null,并且由于您从左连接中提取数据,因此返回的值可能是Null如果Newfile表中没有与Freight对应的数据。

  • On Error GoTo Error_MayCauseAnError 可能不应该存在。
    仅使用 On Error Goto 来捕获您根本无法处理的错误。
    在这里使用它只会隐藏代码中的错误。使用一些适当的检查语句,您甚至不需要On Error Goto...

  • 您的第一个内部循环似乎正在尝试跳过一些记录。
    但是,当该循环中断时,可能是因为它到达了 EOF,而您永远不会在循环后面的代码中测试它。

  • 您永远不会测试您的intcounter 是否超过了分配的 15 个日期。
    您确定您的记录永远不会超过 15 条吗?

  • 您没有说出您收到的确切错误消息。这可能有助于确定手头的问题类型。

【讨论】:

  • 您还应该包括 Dim FinTotal, intcounter As Integer 将声明 FinTotal 一个变体。假设它也是Integer 是一个常见的错误。
【解决方案2】:

代替

mdate2 = "mail_date" & CStr(intcounter)
rs2!mdate2 = memdate(intcounter)

使用

rs2.Fields("mail_date" & intcounter).Value = memdate(intcounter)

DAO 的! 语法实际上只是更长的rs.Fields("name") 形式的简写。

【讨论】:

  • 当然,显式使用.Value 仍然是完全可选的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-16
  • 2015-11-08
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多