【问题标题】:A macro that does not properly recognize contraints in scheduling无法正确识别调度约束的宏
【发布时间】:2016-04-20 18:59:05
【问题描述】:

我正在研究一个宏,它提供了我们生产的产品的 4 个不同生产阶段的可视化表示。电子表格设置为显示为线性日历,显示一年中的所有 365 天并将它们分组为日历周。每个生产阶段都有与之相关的不同颜色。四个构建阶段是:1) 组装:1 天(黄色)2) 初步分析:1 天(紫色)3) 深入分析:7 天(绿色)4) 运输:1 天(红色)

周末或节假日不进行任何工作。周六和周日由黑色单元格表示,假期由橙色单元格表示,并具有十字形图案。该宏旨在使用以下 if then 语句跳过这些假期:

Dim i As Integer

i = Analysis days

for i = 1 to 7

ActiveCell.Select

If Selection.Interior.Pattern = x1CrissCross And Selection.Interior.Color = orange Then

    ActiveCell.Offset(0, 1).Select

Else: ActiveCell.Select

End If

If Selection.Interior.Color = black Then

    ActiveCell.Offset(0, 2).Select

Else: ActiveCell.Select

End If

告诉宏跳过周六和周日的 If Then 语句每次都有效。但是,告诉宏跳过假期的语句仅在部分时间有效,如果假期持续时间超过几天(圣诞节假期持续 9 天),宏会插入贯穿整个假期的生产工作日。我发现将上述语句直接复制并粘贴到另一个下方似乎可以快速解决该问题。但我确信必须有一种更有效的方法来做到这一点。有谁知道我可以解决问题而不必多次复制和粘贴相同的代码行的方法?

提前致谢!

【问题讨论】:

  • 这很有野心^_^;
  • 手工上色很乏味,但可能远没有宏所需的逻辑那么乏味?
  • 啊,我高度建议您通读How to avoid .Select,它会为您省去很多麻烦,并有助于了解VBA的工作原理/思考方式.
  • 您是否在模块顶部使用了Option Explicit?我认为x1CrissCross 应该是xlCrissCrossxlPatternCrissCross

标签: vba excel macros


【解决方案1】:

您的问题之一与循环的逻辑有关,因为您总是“处理”下一个单元而不对其进行测试(假期)。同样如上所述,x1crisscross 应该是 xlcrisscross,我不认为橙色是“已定义”的颜色,因此您可能需要获取该值并对其进行测试(请参阅下面的 myorange)。

这样的循环可以避免这种情况:

' I think you need to need to define what color orange is - as its not one of the "standard" named ones
myOrange = 4626167

For i = 1 To 7
    Debug.Print Selection.Interior.Color
    Debug.Print Selection.Interior.Pattern

    If (Selection.Interior.Color = black Or (Selection.Interior.Color = myOrange And Selection.Interior.Pattern = xlCrissCross))  Then
        ' skip this one so decrement counter
        i = i - 1
    Else
        ' Do the "stuff" for a valid cell here - for testing I just put the counter in the cell
        ActiveCell.Value = i
    End If
    ' move to next cell
    ActiveCell.Offset(0, 1).Select
Next i

就我个人而言,我从不喜欢像这样摆弄“计数器”,减少它似乎很麻烦。

获得相同效果的另一种方法是在 for/next 循环中设置一个循环,不断检查直到找到有效单元格。

myOrange = 4626167

For i = 1 To 7
    found1 = False
    While Not found1
        If Not ( Selection.Interior.Color = black Or (Selection.Interior.Color = myOrange And Selection.Interior.Pattern = xlCrissCross))  Then
            found1 = True
        Else
            ' move to next cell as this one isnt available
            ActiveCell.Offset(0, 1).Select
        End If
    Wend
    ' Do the "stuff" for a valid cell here
     ActiveCell.Value = i
    ' move to next cell
    ActiveCell.Offset(0, 1).Select

Next i

我还将周末(黑色)和假期的测试添加到同一个 If 语句中(注意括号以确保正确处理 or 和 and )。我总是倾向于把它们放在一起只是为了让它更清楚。

当然,您可以使用计数器和“范围”等来完成所有这些操作...而不是选择单元格,但最终结果将是相同的。

如果没有更多有效单元格,这两种方法“可能”永远循环,因此可能值得测试一些最大列数并在达到该值时中断。

【讨论】:

  • 谢谢 NanoTera。我想这就是我要找的。感谢您抽出宝贵的时间
猜你喜欢
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
相关资源
最近更新 更多