【问题标题】:Loops through Access Table and for each Column with Data循环访问表并为每个包含数据的列
【发布时间】:2014-08-13 22:30:23
【问题描述】:

我认为这应该很简单,但我找不到正确的方法。我有一个带有 ID 号列的表,它后面有 10 行标记为问题 #1、问题 #2 等等。

没有重复的 ID 号,但每个 ID 号可以包含多行问题。

我想获取 ID 行,并在适用的情况下为每个不同的问题创建一个具有相同 ID 的新行。因此,如果一个 ID 号在问题 #1 和问题 #2 下列出了一个问题,我想为该 ID 号创建一个副本,并将两个问题都列在一个列下让我们称之为“总问题”,并按此分组身份证号码。这可以通过创建一个新表来完成。

例子:

发件人:

+-------+---------------------------+---------------------------+
|  ID   |        Question #1        |        Question #2        |
+-------+---------------------------+---------------------------+
| 11111 | Was it notated correctly? | Was it completed on time? |
+-------+---------------------------+---------------------------+

收件人:

+-------+-------------------------------------+
|  ID   | Total Questions                     |
+-------+-------------------------------------+
| 11111 | Was it notated correctly?           |
| 11111 | Was it completed on time?           |
+-------+-------------------------------------+

【问题讨论】:

  • 这令人困惑。您在标题中说访问表,但随后只标记了“excel”、“循环”和“excel-vba”。那么这些表是否在 Access 中?如果是这样,您可以对原始表执行查询(无需循环)以按照您想要的方式输出。
  • 抱歉,我在任何地方都没有看到对 excel 的引用。我指的是访问表。

标签: loops ms-access vba


【解决方案1】:

使用DAO的简单解决方案

sub SomeProcedure()
    Dim db as DAO.Database, recIn as DAO.Recordset, recOut as DAO.Recordset

    Set db = currentdb()
    Set recIn = db.openRecordset("yourQuestionsInputTable", dbOpenDynaset, dbReadOnly)
    Set recOut = db.openRecordset("yourQuestionsOutputTable", dbOpenDynaset, dbEditAdd)

    with recIn
        .moveFirst
        do
            for i = 1 to .Fields.count
                if left(.Fields(i).Name, 8) = "Question" then
                    recOut.addNew
                        recOut.Fields("Id") = .fields("Id")
                        recOut.Fields("Total Questions") = .Fields(i)
                    recOut.update
                end if
            next i
            .moveNext
        loop until .EOF
    end with
    recIn.close
    recOut.close
    db.close
end sub

解释:

我正在做的是:

  1. 从输入表中读取每条记录
  2. 对于名称以"Question" 开头的每一列,在输出表中创建一条新记录,其中包含输入表的Id 和所选列的值。

这只是一个草稿。您需要调整代码以满足您的需求。

希望这会有所帮助。


替代品

想了想,对于你在cmets中提到的问题,我可能有一个替代方案。

我认为您可以像这样更改循环:

' You'll need a variable of type Field
Dim f as DAO.Field ' Check if this is right
' Some code
with recIn
    .moveFirst
    do
        for f in .Fields
            if left(f.Name, 8) = "Question" then
                recOut.addNew
                    recOut.Fields("Id") = .Fields("Id").Value
                    recOut.Fields("Total Questions") = .Fields(f.Name).Value
                recOut.update
            end if
        next f
        .moveNext
    loop until .EOF
end with
' More code

不是使用索引对 Fields 集合进行迭代,而是使用其中的任何 Field 成员进行迭代。这应该可以避免“在集合中找不到项目”的问题。

警告:未测试

【讨论】:

  • 谢谢巴兰卡!这似乎解释了我想要完成的事情,我已经调整了代码,但我现在在让它循环到下一个 ID 号时遇到了问题。它为所有问题完美地运行第一个 ID 号,但之后我收到“未在集合中找到项目”错误。根据我对 VBA 的了解,我尝试了一些不同的方法,但无济于事。有什么建议吗?
  • @user3738222 对不起!我忘记在代码中添加.next 行(跳转到recIn 中的下一条记录)。至于“Item not found in collection”,你应该调试你的代码,看看它发生在哪里(逐步执行它并检查执行引发错误的位置)。如果recIn 后面的表具有固定数量的列,请修改循环以仅考虑您需要的列。
  • 每当它到达最后一个问题(问题 #10)列时,我都会收到“在此集合中找不到项目”错误。该代码实际上将 ID 号添加了 10 次(每个问题 1 次)我可以接受,但是一旦它遍历第一个 ID 号的列,它就无法转到下一个 ID 号并执行相同的操作。添加 .Next 给它一个“找不到方法或数据成员”错误,所以我做了 .MoveNext 并收到了相同的项目错误。
  • @user3738222 抱歉(我已经有一段时间没有在 VBA 中编程了);正确的方法是.moveNext。至于“Item not found in collection”,可能是字段索引的问题(i的值)。我不太记得索引是从零开始还是从一开始。使用debug.print recIn.fields(i).Name 在中间窗口中显示正在读取的字段。顺便说一句……你明白这东西在做什么吧? (检查The Ten Commandments of Access ;))
  • 大声笑是的,我明白它在做什么。我有一个类似的代码用于其他用途。我只是认为您提供的代码对我来说看起来很完美,不知道为什么在列结束后循环回 If 行时它会失败。我感谢您的帮助!你绝对让我朝着正确的方向前进。我会继续尝试不同的方法来让它发挥作用。
【解决方案2】:

尝试几个这样的查询:

SELECT ID, Question1 AS TotalQuestions
INTO NewTable
FROM OriginalTable;

SELECT ID, Question2 AS TotalQuestions
INTO NewTable
FROM OriginalTable;

【讨论】:

    猜你喜欢
    • 2019-06-10
    • 1970-01-01
    • 2019-10-29
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    相关资源
    最近更新 更多