【问题标题】:Using one macro to run multiple macros使用一个宏运行多个宏
【发布时间】:2018-04-20 10:22:53
【问题描述】:

我有以下宏,它将搜索三个不同的列标题,选择这些标题下的数据并将数据从货币格式更改为数字格式。数据存储在我的工作簿的表 2 中,当我在此表中单独运行宏时,它可以正常工作。

Sub ProjectFundingFormat()
'
Dim WS As Worksheet
Dim lastCol As Long, lastRow As Long, srcRow As Range
Dim found1 As Range, found2 As Range

Set WS = Workbooks("Workbook1.xlsm").Worksheets("Sheet2") 'Needs to be open

    With WS
    lastCol = .Cells(1, Columns.count).End(xlToLeft).Column
    Set srcRow = .Range("A1", .Cells(1, lastCol))
    Set found1 = srcRow.Find(What:="2018FundingLabor", LookAt:=xlWhole, MatchCase:=False)

    If Not found1 Is Nothing Then
            lastRow = .Cells(Rows.count, found1.Column).End(xlUp).Row
            .Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).Select
            Selection.NumberFormat = "0.00"
        End If
End With


With WS
    lastCol = .Cells(1, Columns.count).End(xlToLeft).Column
    Set srcRow = .Range("A1", .Cells(1, lastCol))
    Set found1 = srcRow.Find(What:="2018FundingNonlabor", LookAt:=xlWhole, MatchCase:=False)

    If Not found1 Is Nothing Then
            lastRow = .Cells(Rows.count, found1.Column).End(xlUp).Row
            .Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).Select
            Selection.NumberFormat = "0.00"
        End If
End With

    With WS
    lastCol = .Cells(1, Columns.count).End(xlToLeft).Column
    Set srcRow = .Range("A1", .Cells(1, lastCol))
    Set found1 = srcRow.Find(What:="2018 Total Funding", LookAt:=xlWhole, MatchCase:=False)

    If Not found1 Is Nothing Then
            lastRow = .Cells(Rows.count, found1.Column).End(xlUp).Row
            .Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).Select
            Selection.NumberFormat = "0.00"
        End If
End With
End Sub

我想将此宏与另外两个结合起来,这样我就可以进入工作表 1,单击我插入的“运行”按钮,我的所有宏将一起运行以更新我的数据。
但是,我得到错误

运行时错误 1004 - 范围类的选择方法失败

在线上

.Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).Select

有人知道我的代码有什么问题吗?我很困惑,因为它本身可以正常工作,但与我的其他宏结合使用时不会运行。
我正在使用以下宏来组合我现有的两个宏:

Sub ProjectUpdate()
Call ProjectName
Call ProjectFunding
Call ProjectFundingFormat

MsgBox "Done"

End Sub

【问题讨论】:

  • 我建议阅读和使用How to avoid using Select in Excel VBA 这应该可以解决您的问题。
  • 同意PEH,特别是这里的问题可能是您试图在非活动工作表上选择一个范围。
  • @Pᴇʜ 谢谢!我已经在我的宏中添加了一行来激活工作表,它现在可以正常工作了! Worksheets("Projects").Activate
  • @nw201827 你做到了,但你做错了。请参阅下面的答案。

标签: vba excel select multiple-columns


【解决方案1】:

你真的应该避免使用.Select.Activate!这会大大降低您的代码速度并导致许多问题。这是一个非常糟糕的做法。如果您有兴趣编写稳定且优质的代码,我真的建议您阅读并关注:How to avoid using Select in Excel VBA

您的代码可以简化为以下内容:

Option Explicit

Public Sub ProjectFundingFormat()
    Dim Ws As Worksheet
    Set Ws = Workbooks("Workbook1.xlsm").Worksheets("Sheet2") 'Needs to be open

    With Ws
        Dim srcRow As Range
        Set srcRow = .Range("A1", .Cells(1, .Columns.Count).End(xlToLeft))

        Dim lastRow As Long
        Dim found1 As Range

        Set found1 = srcRow.Find(What:="2018FundingLabor", LookAt:=xlWhole, MatchCase:=False)
        If Not found1 Is Nothing Then
            lastRow = .Cells(.Rows.Count, found1.Column).End(xlUp).Row
            .Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).NumberFormat = "0.00"
        End If

        Set found1 = srcRow.Find(What:="2018FundingNonlabor", LookAt:=xlWhole, MatchCase:=False)
        If Not found1 Is Nothing Then
            lastRow = .Cells(.Rows.Count, found1.Column).End(xlUp).Row
            .Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).NumberFormat = "0.00"
        End If

        Set found1 = srcRow.Find(What:="2018 Total Funding", LookAt:=xlWhole, MatchCase:=False)
        If Not found1 Is Nothing Then
            lastRow = .Cells(.Rows.Count, found1.Column).End(xlUp).Row
            .Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).NumberFormat = "0.00"
        End If
    End With
End Sub
  1. 丢弃不必要的重复With 语句。
  2. 不需要确定最后一列编号,您可以将第 1 行的最后一个单元格直接与.Cells(1, .Columns.Count).End(xlToLeft) 一起使用。

  3. 丢弃所有.Select.Activate

让它更干净、更稳定。


或者你甚至使用额外的程序来避免重复代码,这是一个很好的做法,不重复代码,最好有程序:

Option Explicit

Public Sub ProjectFundingFormat()
    Dim Ws As Worksheet
    Set Ws = Workbooks("Workbook1.xlsm").Worksheets("Sheet2") 'Needs to be open

    With Ws
        Dim srcRow As Range
        Set srcRow = .Range("A1", .Cells(1, .Columns.Count).End(xlToLeft))

        FindAndFormat srcRow, "2018FundingLabor"
        FindAndFormat srcRow, "2018FundingNonlabor"
        FindAndFormat srcRow, "2018 Total Funding"
    End With
End Sub

Public Sub FindAndFormat(srcRow As Range, FindWhat As String)
    With srcRow.Parent
        Dim found1 As Range
        Set found1 = srcRow.Find(What:=FindWhat, LookAt:=xlWhole, MatchCase:=False)
        If Not found1 Is Nothing Then
            Dim lastRow As Long
            lastRow = .Cells(.Rows.Count, found1.Column).End(xlUp).Row
            .Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).NumberFormat = "0.00"
        End If
    End With
End Sub

【讨论】:

  • +1 表示第二种解决方案。更具可读性和易于维护以及良好的编码实践。太棒了!
  • 这太棒了!比我以前使用的要整洁得多。谢谢!
猜你喜欢
  • 2015-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 2015-07-23
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
相关资源
最近更新 更多