【问题标题】:multiple for next loops, 2 (or more) of them must change concurrently多个 for next 循环,其中 2 个(或更多)必须同时更改
【发布时间】:2015-02-15 13:58:29
【问题描述】:

我有以下逻辑方案和价值观:

Sub PrezziFissi()

Dim i As Integer, k As Integer, z As Integer
Dim FornitCerca As Range, data As Range, FornitVerif As Range, DataPaste As Range, NomePaste As Range, PrezzoPaste As Range
Dim PrezzoFisso As Range
Dim foglio As Worksheet

Set foglio = ActiveWorkbook.Sheets("CODICI")

For k = 10 To 110

    Set FornitCerca = foglio.Range("I" & k)
    Set PrezzoFisso = foglio.Range("J" & k)

    For z = 3 To 601
        Set data = foglio.Range("R" & z)
        Set FornitVerif = foglio.Range("S" & z)

        If FornitCerca = FornitVerif Then 'ELABORA - copia e incolla

            For i = 20 To 150

            Set DataPaste = foglio.Range("B" & i)
            Set NomePaste = foglio("C" & i)
            Set PrezzoPaste = foglio("D" & i)

            If PrezzoPaste = 0 Then

            PrezzoFisso.Copy
            PrezzoPaste.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, operation:=xlNone
            Application.CutCopyMode = False

            FornitCerca.Copy 'c 20
            NomePaste.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, operation:=xlNone
            Application.CutCopyMode = False

            data.Copy 'b 20
            DataPaste.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, operation:=xlNone
            Application.CutCopyMode = False
            Else: Next i
            End If
            Next i

        Else: Next z
        End If
        Next z

    Next k


End Sub

因为如果仅 (i) 更改为前向 1,那么它会在所有列 D、C 和 B 单元格中复制 z=3 的值, 如果只有 z 改变,那么在位置 D20、C20、B20 它将覆盖来自第 20 行匹配的值

相反,我想 (i) 向前移动 1 到另一个目标空单元格(第 21 行), 以及从 S3 到 S4 的匹配移动(在单元格下方到 S 列) 我想放下一个z,下一个我。这可能吗?如果是,VBA 会同时更改这些变量吗? 非常感谢您,并为您耽误您的时间道歉

【问题讨论】:

  • 听起来您需要将Else: Next i 替换为Exit For,将其留在If/End If 中。这将使您脱离 i 的 For/Next 循环,增加 z 并继续。 FWIW,像Else: Next i 这样的行几乎应该永远被使用,因为Next i 会递增。

标签: excel vba


【解决方案1】:

可能不需要三个循环,尤其是因为您的循环限制未对齐:z 运行时间比 k 长,而 i 比 z 短得多。另外,嵌套循环将具有乘法迭代。例如,对于每个第 k 个元素,z 将迭代 3 到 150,然后 i 对每个第 z 个元素迭代 20 到 150,因此总体而言,598 * 100 * 130!几乎是Cartesian Product 效果。这就是为什么您会看到发生覆盖的原因,因为您不断地迭代相同的单元格。

通用循环

要同时迭代,您可以将所有范围包装在一个通用迭代中(您已经这样做了),初始化您的迭代器,然后运行您的 if/then 逻辑和复制/粘贴处理:

k = 10
z = 3
i = 20
for iter = iter to 1000
    Set yourfirstrange = Range("A" & k)
    Set yoursecondrange = Range("B" & z)
    Set yourthirdrange = Range("C" & i)
    ...
    k = k + 1
    z = z + 1
    i = i + 1
next iter

同样,请注意您的范围限制和单元格数量之间没有充分对齐。

VLOOKUP

但是,您可能有机会使用Vlookup,因为您只需复制和粘贴与列范围内的值匹配的单元格。

以下是最里面的 for/next (i) 循环的示例:

'PrezzoFisso.Copy ---> PrezzoPaste.PasteSpecial
Range("D20").Formula = "=VLOOKUP(S3, "I10:J110", 2, FALSE)"
...
Range("D150").Formula = "=VLOOKUP(S133, "I10:J110", 2, FALSE)"


'FornitCerca.Copy ---> NomePaste.PasteSpecial
Range("C20").Formula = "=VLOOKUP(S3, "I10:J110", 1, FALSE)"
...
Range("C150").Formula = "=VLOOKUP(S133, "I10:J110", 1, FALSE)"


'data.Copy ---> DataPaste.PasteSpecial
Range("B20").Formula = "=IF(VLOOKUP(S3, "I10:J110", 1, FALSE) > 0, R3, 0)"
...
Range("B150").Formula = "=IF(VLOOKUP(S133, "I10:J110", 1, FALSE) > 0, R133, 0)"

注意 S 不能超过 133,因为公式会逐个单元格地运行。

索引/匹配

或者,您可以使用Index/Match 来克服一些 Vlookup 限制:

'PrezzoFisso.Copy ---> PrezzoPaste.PasteSpecial
Range("D20").Formula = "=INDEX(I10:J110,MATCH(S3,I10:I110,0),2)"

'FornitCerca.Copy ---> NomePaste.PasteSpecial
Range("C20").Formula = "=INDEX(I10:J110,MATCH(S3,I10:I110,0),1)"

'data.Copy ---> DataPaste.PasteSpecial
Range("B20").Formula = "=IF(INDEX(I10:J110,MATCH(S3,I10:I110,0),1)>0, R3, 0)"

数据库

最后,关于笛卡尔积,在关系数据库中,SQL query joins 就是:表格上的笛卡尔积。因此,如果您可以将您的范围(FornitCerca、PrezzoFisso、FornitVerif 等)放入不同的表中,则可以将相关列连接在一起以在最终结果集中创建查询。 MS Access,Excel 的同级 Office 产品可以使用 Microsoft Query 轻松执行此连接或操作

【讨论】:

    猜你喜欢
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 2021-02-13
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2014-01-02
    相关资源
    最近更新 更多