我在工作表1上输入了VBA代码。我希望代码在工作表2上工作。我只是将代码从工作表1复制到工作表2吗?

时间:2014-04-22 16:31:57

标签: excel vba

我在这里发现这个VBA代码效果很好。我希望代码可以在工作簿中的其他工作表上工作。代码在Sheet 1中运行良好,但我希望代码也适用于Sheet 2,Sheet 3等。我尝试从Sheet 1模块中复制代码并将其粘贴到Sheet 2,Sheet 3等中,以查看代码是否有效。代码并没有像我预期的那样工作。我想我需要对标准模块代码做一些事情,这样代码才能正常工作。

表1模块

Private Sub Worksheet_Calculate()
    Dim rng As Range, c As Range
    Dim rngToColor As Range

    On Error GoTo ErrorHandler

    Application.EnableEvents = False
    'get only used part of the sheet
    Set rng = Intersect(Me.UsedRange, Me.Range("A:Z"))
    If rng Is Nothing Then GoTo ExitHere 

    For Each c In rng
        'check if previous value of this cell not equal to current value
        If cVals(c.Address) <> c.Text Then
            'if so (they're not equal), remember this cell
            c.ClearComments
            c.AddComment Text:="Changed value from '" & cVals(c.Address) & "' to '" & c.Text & "'" & " on " & Format(Date, "mm-dd-yyyy") & " by " & Environ("UserName")
            c.Interior.ColorIndex = 36
        End If

        'store current value of cell in dictionary (with key=cell address)
        cVals(c.Address) = c.Text
    Next c

ExitHere:
    Application.EnableEvents = True
    Exit Sub
ErrorHandler:
    Resume ExitHere
End Sub

ThisWorkbook Module

Private Sub Workbook_Open()
    Application.Calculation = xlCalculationManual
    Call populateDict
    Application.Calculation = xlCalculationAutomatic
End Sub

标准模块

Public cVals As New Dictionary

Sub populateDict()
    Dim rng As Range, c As Range

    With ThisWorkbook.Worksheets("Sheet1")
        Set rng = Intersect(.UsedRange, .Range("A:Z"))
        For Each c In rng
            cVals(c.Address) = c.Text
        Next c
        .Calculate
    End With

End Sub

编辑:我拿了标准模块并将其修改为:

Sub populateDict()
    Dim rng As Range, c As Range

    With ThisWorkbook.Worksheets("Sheet1")
        Set rng = Intersect(.UsedRange, .Range("A:Z"))
        For Each c In rng
            cVals(c.Address) = c.Text
        Next c
        .Calculate
    End With

    With ThisWorkbook.Worksheets("Sheet2")
        Set rng = Intersect(.UsedRange, .Range("A:Z"))
        For Each c In rng
            cVals(c.Address) = c.Text
        Next c
        .Calculate
    End With

End Sub

这个编辑几乎可以解决问题,但不确定为什么代码无法正常工作

1 个答案:

答案 0 :(得分:5)

执行此操作的一种方法是将代码放在单独的模块中,然后将活动工作表设置为如下变量:

Sub myScript()
    Dim wks As Worksheet

    Set wks = ActiveSheet

    MsgBox (wks.Range("A1"))
End Sub

如果您在Sheet1处于活动状态时调用它,它将从Sheet1返回值。


enter image description here


另一种方法是将工作表作为变量传递给sub。这只是一种方法。向要从中运行宏的每个工作表添加一个按钮。双击“设计模式”中的每个按钮,以便在编辑器中打开VBA单击事件。像这样添加对您的潜点的调用:

Private Sub CommandButton1_Click()
    Call myScriptPass(ActiveSheet)

    'Or you can qualify it like this
    Call myScriptPass(Sheets(1))
End Sub

现在将宏更改为:(仍位于单独的模块中)

Sub myScriptPass(wks As Worksheet)
    MsgBox (wks.Range("A1"))
End Sub

修改

使用您添加到帖子中的代码,您可以将其更改为以下内容:

Public cVals As New Dictionary

Sub record()
    Dim wks As Worksheet
    Set wks = ActiveSheet

    Dim rng As Range, c As Range

    With wks
        Set rng = Intersect(.UsedRange, .Range("A:Z"))
        For Each c In rng
            cVals(c.Address) = c.Text
        Next c
        .Calculate
    End With
End Sub

现在,它将运行哪个工作表处于活动状态。因此,如果您通过Sheet1上的按钮调用宏,则代码将在Sheet1上运行。


从主程序循环

Public cVals As New Dictionary

Sub myMainProgram()
    Dim wks As Worksheet

    'Loop thru each sheet in workbook example
    For Each wks In Worksheets
        Call record(wks)
    Next wks

    'Call subroutine for specific sheet example
    Call record(sheets("sheet1"))
End Sub

Sub record(wks As Worksheet)
    Dim rng As Range, c As Range

    With wks
        Set rng = Intersect(.UsedRange, .Range("A:Z"))
        For Each c In rng
            cVals(c.Address) = c.Text
        Next c
        .Calculate
    End With

    MsgBox ("Record macro was run on " & wks.Name & " worksheet.")
End Sub