【问题标题】:Nested For Next Loops: Outer loop not iterating嵌套下一个循环:外循环不迭代
【发布时间】:2014-12-23 08:34:28
【问题描述】:

我有来自A2:A34 的一系列数据,其中包含各种名称,我需要将其复制到E9:E14 范围内。我只需要复制和粘贴唯一的名称(我不需要同名的双精度)。我很确定使用嵌套的For Next 循环是可行的方法,但我无法让外循环进入下一次迭代。现在这只是给我在A2:A34 范围内的姓氏,在E9:14 中重复。我正在考虑使用Exit For,但是当我在代码中添加它时,外部循环迭代但内部循环从 2 开始。

对此的任何帮助将不胜感激。谢谢! 以下是我的代码:

Sub FillTable()
  Dim tableCount As Integer
  Dim rowCount As Integer

  For tableCount = 9 To 13
    If Range("E" & tableCount).Value = "" Then
      For rowCount = 2 To 34  
        If Range("E" & tableCount).Value = Range("A" & rowCount).Value Then

        ElseIf Range("E" & tableCount).Value <> Range("A" & rowCount).Value Then
          Range("E" & tableCount).Value = Range("A" & rowCount).Value
        End If
      Next rowCount
    End If
  Next tableCount
End Sub

【问题讨论】:

  • 看来您的数据将始终采用非常特定的格式,因为您知道要迭代的唯一值的确切数量。如果是这样,为什么不直接将列表复制到 E 列,然后使用“数据”菜单中内置的“删除重复项”?
  • 如果没有一些样本数据,很难想象您正在尝试做什么。最简单的方法是一步一步(调试)并找出为什么它没有按照您的预期进行。例如,IF 可能没有按您的预期进行评估。
  • 感谢您的回复。我一直在逐步进行,问题是一旦 ELSEIF 语句为真并且它复制了名字,它会迭代但外部循环不会。因此,一旦发生这种情况,For rowCount 下的第一个 if 语句将变为 true,并将第二个唯一名称粘贴到表的同一位置。
  • 如果您只想在 A2:34 范围内搜索唯一值并将它们粘贴到旁边的 B 列中,部分代码会是什么样子?

标签: excel for-loop nested-loops vba


【解决方案1】:

我不确定这个确切的问题是否真的需要 VBA,但希望下面的代码会有所帮助。我切换了循环,以便您只遍历大型名称列表一次,然后遍历第二个列表检查重复项。我还添加了一个变量,因此它允许超过 5 个唯一名称(与 tablecount 为 9 到 13 时不同)。

公平警告 - 这是一种快速简便的解决方案。它既不优雅也不优化。

Sub FillTable()

Dim tableCount As Integer
Dim rowCount As Integer
Dim n As Integer

n = 0
For rowCount = 2 To 34

  For tableCount = 9 To 9 + n
      If Range("E" & tableCount).Value = Range("A" & rowCount).Value Then
        ' name already found, break out of loop
        Exit For
      ElseIf Range("E" & tableCount).Value = "" Then
        Range("E" & tableCount).Value = Range("A" & rowCount).Value
        n = n + 1
      End If
  Next tableCount

Next rowCount

End Sub

【讨论】:

  • 这非常适合我的需要。非常感谢。 n 变量计数器是我所缺少的。
  • 我有点困惑的是For tableCount = 9 to 9 + n。如果您将 n = n + 1 留在代码之外,它不会迭代到下一个 rowCount 而是卡在 tableCount 循环中怎么办?
  • 我只是选择了 9 作为值,因为您说您希望范围从单元格 E9 开始。通常你会设置 n=1,然后 For 循环将从 1 到 n。如果取出 n=n+1,n 永远 = 0,tableCount 永远 = 9。内部的 For 循环只会运行一次,因为已经达到退出条件(tableCount = 9 + 0)。带有 rowCount 的外部 For 循环仍将迭代,但您无法判断,因为没有任何编码。您可以通过在 Next tableCount 和 Next rowCount 之间添加“MsgBox(rowCount)”来测试它。
【解决方案2】:

您对目标的描述似乎与代码不符。

您正在从(为了简化一点)col A 复制到 col E。 col E 是否已经包含数据?如果不是,为什么第一个“if”stmt 来查看某个单元格是否为空? 如果是,E 已经包含数据,那么您想遍历 E 以查看 E 是否已经包含新名称。 我还要指出,E 有 6 个名称的空间(根据您的规范),而源有 33 个名称。

在不知道你的目标的情况下,我不会建议真正的代码,但是,也许是解决问题的一种方法: 创建只做非常简单的小事情的函数。例如,也许最简单的一个函数来查看名称是否已经在列表中。请注意,我假设使用次数最多的行有一个值,请务必将其定义为 14 或某个计数器。

Function Is_Name_Already_Present_in_E( Name-to-check as String ) As Bool
   Is_Name_Already_Present_in_E = False               ; Default we'll return if don't find name.
   for r = 9 to highest-so-far-used
      if Name-to-check = Range( "E" & r ).value then  ; If found name in list,
         Is_Name_Already_Present_in_E = true          ; then return true.
         exit function
      end if
   next r
end function                                          ; If scan whole list, and not found,false.

我确定有一些语法错误,但它们应该很容易解决。

然后,创建一个简单的函数将您的新名称添加到 E。也许类似于(当心假设!):

Function Add_New_Name_To_List( Name  as string ) as bool
   if highest_used_so_far >= 14 then
      Error "No room to insert name:" & Name & ". Rejected."
      Add_New_Name_To_List = false
      exit function
   end if
   highest_used_so_far = highest_used_so_far + 1
   range( A & h_u_s_r ).value = Name
   Add_New_Name_To_List = true
exit function

然后,您的 main 变得非常简单(假代码示例,因为我不知道您的意图):

for r = 2 to 34
    if not Is_Name_Already_Present_in_E( range( "A" & r ).value ) then
        if not Add_Name_to_E( range( "A" & r ).value ) then
           ... what to do if add fails. ...
        end if
    end if
next name

把你的问题分成几部分,应该清楚如何写每一部分。祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-22
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多