【问题标题】:MS VBA with loops and unions带有循环和联合的 MS VBA
【发布时间】:2013-12-23 07:52:46
【问题描述】:
Dim Counter As Integer
Dim Maxhouse As Integer
Dim FindHouse As Range
Dim RangeVar As Range
Dim HousesRange As Range

    For Counter = 1 To MaxHouse
        ActiveSheet.Cells(16, 2 + Counter).Select
        House = ActiveCell
        With Sheets("Sheet1").Range("C:KP")
            Set FindHouse = Cells.Find(What:=House, _
                After:=Cells(17, 1), _
                LookIn:=xlValues, _
                LookAt:=xlWhole, _
                SearchOrder:=xlByRows, _
                SearchDirection:=xlNext, _
                MatchCase:=False)
            If Not FindHouse Is Nothing Then
                If Counter = 1 Then
                    Set HousesRange = FindHouse
                Else
                    Set RangeVar = FindHouse
                    Set HousesRange = Union(HousesRange, RangeVar)
                End If
            End If
        End With
    Next Counter

    For Each RCell In HousesRange.Cells
        Application.Goto RCell, True
    Next RCell**

现在我的问题是遍历命名范围“HousesRange”的for循环

假设 HousesRange 包含 [2,5,9,10]。

这里的 HousesRange 是我的工作表中 [1,2,3,4,5,6,7,8,9,10] 行的子集

假设 HousesRange 是通过 [9,10,5,2] 的顺序建立的(通过第一个 for 循环与并集)。

现在,当我仅使用 rCells(第二个 for 循环)遍历 HousesRange 时,它​​会将我带到 9、10、5,然后是 2。

但我希望它带我去 2、5、9 和 10

有人可以对此有所了解吗?

我一直认为命名范围总是从左到右然后从上到下遍历。

非常感谢您

【问题讨论】:

  • 这段代码是否完整?你能在循环开始之前添加HousesRange.address结果的信息吗?
  • 没有。这是部分代码。示例:Household 包含单元格 [1,2,3,4],但它以 [3, 4, 2, 1] 的顺序遍历,假设这是形成联合的顺序
  • 编辑代码以便您可以查看上下文
  • 我已经检查了不同的选项,例如 AreasFor i >> .cells(i),但没有任何效果如您所愿。我承认,目前我不知道如何快速排序。
  • 嗨 KazJaw,我假设 VBA/Excel 总是从左到右,然后从上到下遍历命名范围。但这里不是这种情况。请在下面查看我的 cmets 以获取更多信息!

标签: excel vba for-loop cell union-all


【解决方案1】:

好的,这是很长的路要走,但它应该可以工作:

而不是使用Union 在字典对象中构建找到的房屋列表。 然后使用Bubblesort HouseRangeDic 对范围进行排序 您终于应该能够以正确的顺序使用它了:

Dim Counter As Integer
Dim Maxhouse As Integer
Dim FindHouse As Range
Dim RangeVar As Range
Dim HousesRange As Range

'****** NEW **********
Dim foundHouseCount
foundHouseCount = 1
Dim HouseRangeDic
Set HouseRangeDic = CreateObject("Scripting.dictionary")
'*********************

    For Counter = 1 To Maxhouse
        ActiveSheet.Cells(16, 2 + Counter).Select
        House = ActiveCell
        With Sheets("Sheet1").Range("C:KP")
            Set FindHouse = Cells.Find(What:=House, _
                After:=Cells(17, 1), _
                LookIn:=xlValues, _
                LookAt:=xlWhole, _
                SearchOrder:=xlByRows, _
                SearchDirection:=xlNext, _
                MatchCase:=False)
            If Not FindHouse Is Nothing Then
                HouseRangeDic.Add foundHouseCount, RangeVar '**** NEW ***
                foundHouseCount = foundHouseCount + 1 '**** NEW ***
            End If
        End With
    Next Counter

    '**** NEW ***
    Bubblesort HouseRangeDic

    For i = 1 To HouseRangeDic.Count
       Application.Goto HouseRangeDic(i), True
    Next
    '************


Sub Bubblesort(ByRef rangeDic)
    Dim tempRange
    For i = 1 To rangeDic.Count - 1
        For j = i To rangeDic.Count
            If rangeDic(i).Address > rangeDic(j).Address Then
                Set tempRange = rangeDic(i)
                Set rangeDic(i) = rangeDic(j)
                Set rangeDic(j) = tempRange
            End If
        Next
    Next
End Sub

【讨论】:

  • 联合只有 1 行。它由同一行中的不同单元格组成
  • @user3072955 嗯......可能是我误解了这个问题。 “先进先出”是什么意思。您能否发布您的 Excel 工作表中的范围是什么样的?
  • 所以假设 HousesRange 包含 [2,5,9,10]。并假设 HousesRange 是通过 [9,10,5,2] 的顺序建立的(通过第一个 for 循环与联合)。现在,当我只使用 rCells(我之前的代码)遍历 HousesRange 时,它​​会将我带到 9、10、5 然后 2。但我希望它把我带到 2、5、9 然后 10
  • 这里的 HousesRange 是行 [1,2,3,4,5,6,7,8,9,10] 的子集
  • @user3072955 - 我现在明白你的问题了。我在上面发布了一个新的解决方案
【解决方案2】:

看看这是否适合你。请注意,我的“After:=" 设置为范围的最后一个单元格,因此第一个查找从范围的开头开始。

Sub loopCells()
    Dim FindHouse As Range
    Dim HousesRange As Range
    Dim rcell As Range
    Dim r As Range
    Dim sAdd As String
    Dim House As Long

    Set r = Sheets("Sheet1").Range("$C$15:$K$20") 'change to suit

    House = 11'change to suit
    With r

        Set FindHouse = .Find(What:=House, After:=r(.Cells.Count), LookIn:=xlValues, LookAt:=xlWhole, _
            SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False)
        If Not FindHouse Is Nothing Then
            sAdd = FindHouse.Address
            Do
               If HousesRange Is Nothing Then
                    Set HousesRange = FindHouse
                Else
                    Set HousesRange = Union(HousesRange, FindHouse)
                End If
                Set FindHouse = .FindNext(FindHouse)
            Loop While Not FindHouse Is Nothing And FindHouse.Address <> sAdd
        End If
    End With

    For Each rcell In HousesRange
        Application.Goto rcell
    Next rcell

End Sub

【讨论】:

  • 不……同样的交易,我最终得到了通过 HousesRange 的确切遍历模式
  • 这是一个字符串变量,保存第一次查找的地址,因此您知道何时循环回到起点。只是为了好玩,在Do 行下添加这个 - FindHouse.Select。这样您就可以看到您的范围是如何构建的。顺便说一句,您在第一行中将范围设置为什么?
  • 第一行和“Counter=1”之后的行一样吗?我将其设置为找到的第一个地址。之后,我将以前找到的地址与新找到的地址结合起来。如果不是,您指的是哪条“第一行”?
  • 不,我在谈论我的代码 - 如果你尝试过,你在这一行中将地址设置为什么:Set r = Sheets("Sheet1").Range("$C$15:$K$20")
  • 问题是,HousesRange 正在正确填充。我似乎无法正确完成它.. 以这种速度,我将不得不编写一个 min 函数 -> 从 HousesRange 中取出 min 单元格 -> 重复直到 HousesRange 什么都没有......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-04
  • 2021-05-07
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多