【问题标题】:Range Macro Not Functioning范围宏不起作用
【发布时间】:2020-08-14 15:26:11
【问题描述】:

.

以下宏 (CollectProjectItems) 按设计运行。在宏 (CollectContractorItems) 中应用相同的逻辑并更改范围,但无法正常工作。

我假设错误是我忽略的东西,当然......对于我的一生......我无法识别我的错误。

需要一双全新的眼睛。

提前谢谢你。

Sub UpdateCharts()
    CollectProjectItems
    CollectContractorItems
End Sub

Sub CollectProjectItems()
On Error Resume Next
    MyDate = Format(Date, "mmm") & "-" & Right(Year(Date), 2)
    For Each cl In Range("A3", Range("A" & Rows.Count).End(xlUp))
        wproj = Application.Match(cl.Value, Columns(10), 0)
        
        If IsNumeric(wproj) Then
            MyMonth = Application.Match(MyDate, Rows(wproj + 1), 0)
            Cells(wproj + 2, MyMonth) = cl.Offset(, 1)
            Cells(wproj + 3, MyMonth) = cl.Offset(, 2)
        End If
    Next
End Sub

Sub CollectContractorItems()
On Error Resume Next
    MyDate = Format(Date, "mmm") & "-" & Right(Year(Date), 2)
    For Each cl In Range("E3", Range("E" & Rows.Count).End(xlUp))
        wproj = Application.Match(cl.Value, Columns(25), 0)
        
        If IsNumeric(wproj) Then
            MyMonth = Application.Match(MyDate, Rows(wproj + 1), 0)
            Cells(wproj + 2, MyMonth) = cl.Offset(, 1)
            Cells(wproj + 3, MyMonth) = cl.Offset(, 2)
        End If
    Next
End Sub

第二个宏未完成 Col AG 中所需的编辑。它复制了与 Col R 的第一个宏相同的编辑。

我不明白如何更改第二个宏,因此它会影响 Cols Z:AK 中的编辑。

???

下载示例工作簿:Macro Error

【问题讨论】:

  • 如果您需要了解发生了什么,请删除 On Error Resume Next。这是一种糟糕的“代码气味”——没有理由让它存在。
  • 您还需要使用 IsError() 测试 MyMonth 以确保匹配。并使用显式工作表对象限定所有范围调用。
  • 好的,删除“On Error ...”我不明白你的第二个建议。
  • Match() 如果不匹配则返回错误,因此您应该始终使用 IsError() 进行测试,这样您就可以决定在这种情况下该怎么做。范围引用,如Cells()(在常规代码模块中)始终默认为 ActiveSheet,并且依赖于某个工作表处于活动状态的代码很容易意外失败。即使您真的想在 ActiveSheet 上进行操作,最好在您的代码中明确说明这一点。所以ActiveSheet.Cells() 而不仅仅是Cells()

标签: excel vba range match


【解决方案1】:

像这样:

Sub CollectContractorItems()
    Const COL_CONTRACTORS As Long = 25
    Dim MyDate As String, cl As Range, ws As Worksheet, wproj, MyMonth
    Dim rngDates As Range, dtCol As Long

    Set ws = ActiveSheet 'or some specific sheet
    MyDate = Format(Date, "mmm") & "-" & Right(Year(Date), 2)

    For Each cl In ws.Range("E3:E" & ws.Cells(ws.Rows.Count, "E").End(xlUp).Row).Cells
        wproj = Application.Match(cl.Value, ws.Columns(COL_CONTRACTORS), 0)
        
        If Not IsError(wproj) Then
            'get the range with dates
            Set rngDates = ws.Cells(wproj, COL_CONTRACTORS).Offset(1, 1).Resize(1, 12)
            MyMonth = Application.Match(MyDate, rngDates, 0) 'search only in the specific range
            If Not IsError(MyMonth) Then
                dtCol = rngDates.Cells(MyMonth).Column 'get the column number
                ws.Cells(wproj + 2, dtCol) = cl.Offset(, 1)
                ws.Cells(wproj + 3, dtCol) = cl.Offset(, 2)
            End If
        End If
    Next
End Sub

【讨论】:

  • 我理解并感谢您。但是,它仍然不会更改 Cols Z:AK 中的值。它正在改变 Cols K:V 的值,这不是目标。
  • 在这种情况下,MyMonth 的值不是您所期望的。我无法预测...您需要单步执行代码,看看哪里出了问题...
  • 为什么相同的代码对 Cols K:V .... 起作用,但对 Cols Z:AK 不起作用?如果我正确理解了宏观逻辑......指示 ws.Columns(25) 应该告诉 Excel 查看第二组列。
  • Application.Match(MyDate, ws.Rows(wproj + 1), 0) 将在该行中找到(例如)“Jan-20”的第一个匹配项。由于您在同一行的 K:V 中有一组月-年值,它会在找到 Z:AK 中的任何值之前找到它……您的“项目”和“分包商”日历不能打开相同的行。
  • 嗯……在那种情况下,看来我需要研究另一种方法才能在第二个月内获得正确的列。
猜你喜欢
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 2014-06-12
  • 2016-05-04
  • 2017-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多