excel 需要Worksheet_Change宏来处理工作簿中的所有工作表

z18hc3ub  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(177)

我有一个Excel工作簿,其中有两个工作表:“未完成”和“完成”。在“未完成”工作表中,当Z列更改为“完成”时,我希望WorkSheet_Change函数将当前行移动到“完成”工作表中。而在“完成”工作表中,我希望WorkSheet_Change函数在Z列更改为Outstanding时将当前行移动到Outstanding工作表。如果在VBA中将宏放在某个工作表下,则可以对该工作表执行此操作,但如果宏位于工作簿的模块下,则无法使其工作。由于无法在一个工作簿的多个宏中使用WorkSheet_Change(即不能只在每个工作表下创建相同的宏)我必须弄清楚如何使它在模块下工作。这是当它在一个工作表下工作时的代码,但是它只对那个工作表有效。当它在工作簿的模块中时,我如何让它对两个工作表都有效?

'Remove Case Sensitivity
  Option Compare Text
Sub Worksheet_Change(ByVal Target As Range)
   ' On Error Resume Next - I took this out of this code that I found on the internet because it apparently causes problems
    
    Application.EnableEvents = False
    
        'If Cell that is edited is in column Z and the value is Complete then
    If Target.Column = 26 And Target.Cells(1).Value = "Complete" Then
        'Define last row on Complete worksheet to know where to place the row of data
        LrowCompleted = Sheets("Complete").Cells(Rows.Count, "A").End(xlUp).Row
        'Copy and paste data
        Range("A" & Target.Row & ":Z" & Target.Row).Copy Sheets("Complete").Range("A" & LrowCompleted + 1)
        'Delete Row from the ActiveSheet
        Range("A" & Target.Row & ":Z" & Target.Row).Delete xlShiftUp
     ElseIf Target.Column = 26 And Target.Cells(1).Value = "Outstanding" Then
        'Define last row on Outstanding worksheet to know where to place the row of data
        LrowCompleted = Sheets("Outstanding").Cells(Rows.Count, "A").End(xlUp).Row
        'Copy and paste data
        Range("A" & Target.Row & ":Z" & Target.Row).Copy Sheets("Outstanding").Range("A" & LrowCompleted + 1)
        'Delete Row from the ActiveSheet
        Range("A" & Target.Row & ":Z" & Target.Row).Delete xlShiftUp

   End If
     
    Application.EnableEvents = True
End Sub
dxxyhpgq

dxxyhpgq1#

工作簿工作表变更:复制行

  • 将以下代码复制到ThisWorkbook模块中。
Option Explicit

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    
    Dim Success As Boolean
    On Error GoTo ClearError

    Const CRITERIA_COLUMN As Long = 26
    
    Dim wsNames(): wsNames = VBA.Array("Complete", "Outstanding")
    Dim FirstRows(): FirstRows = VBA.Array("A2:Z2", "A2:Z2")
    Dim Criteria(): Criteria = VBA.Array("Outstanding", "Complete")
    
    Dim aIndex: aIndex = Application.Match(Sh.Name, wsNames, 0)
    If IsError(aIndex) Then Exit Sub
    
    aIndex = aIndex - 1
    Dim sws As Worksheet: Set sws = Me.Sheets(wsNames(aIndex))
    
    Dim srg As Range
    With sws.Range(FirstRows(aIndex))
        Set srg = .Resize(sws.Rows.Count - .Row + 1)
    End With
    
    Dim irg As Range: Set irg = Intersect(srg.Columns(CRITERIA_COLUMN), Target)
    If irg Is Nothing Then Exit Sub
    
    Dim urg As Range, cel As Range
    
    For Each cel In irg.Cells
        If StrComp(CStr(cel.Value), Criteria(aIndex), vbTextCompare) = 0 Then
            If urg Is Nothing Then Set urg = cel Else Set urg = Union(urg, cel)
        End If
    Next cel
    
    If urg Is Nothing Then Exit Sub

    aIndex = (aIndex + 1) Mod 2
    
    Dim dws As Worksheet: Set dws = Me.Sheets(wsNames(aIndex))
    If dws.FilterMode Then dws.ShowAllData
    
    Dim dfCell As Range
    
    With dws.Range(FirstRows(aIndex))
        Dim dlCell As Range: Set dlCell = .Resize(dws.Rows.Count - .Row + 1) _
            .Find("*", , xlFormulas, , xlByRows, xlPrevious)
        If dlCell Is Nothing Then
            Set dfCell = .Cells(1)
        Else
            Set dfCell = .Cells(1).Offset(dlCell.Row - .Row + 1)
        End If
    End With
     
    Application.EnableEvents = False
    
    With Intersect(srg, urg.EntireRow)
        .Copy dfCell
        .Delete xlShiftUp
    End With
    
    Success = True
    
ProcExit:
    If Not Application.EnableEvents Then Application.EnableEvents = True
    If Not Success Then MsgBox "Something went wrong.", vbCritical
    Exit Sub
ClearError:
    Debug.Print "Run-time error '" & Err.Number & "':" & vbLf & Err.Description
    Resume ProcExit
End Sub
xjreopfe

xjreopfe2#

我做过这个测试。
1.在通用模块Module1中,我们创建子例程DoWorksheet_Change(),使用ActiveSheet来标识我们正在编辑的工作表。

'Remove Case Sensitivity
Option Compare Text
Option Explicit

Sub DoWorksheet_Change(ByVal Target As Range)
    ' On Error Resume Next - I took this out of this code that I found on the internet because it apparently causes problems
      
    Dim LrowCompleted As Long
      
    Application.EnableEvents = False
    
    'Debug.Print ActiveSheet.Name
    'If Cell that is edited is in column Z and the value is Complete then
    If Target.Column = 26 And Target.Cells(1).Value = "Complete" Then
        'Define last row on Complete worksheet to know where to place the row of data
        LrowCompleted = Sheets("Complete").Cells(Rows.Count, "A").End(xlUp).Row
        'Copy and paste data
        ActiveSheet.Range("A" & Target.Row & ":Z" & Target.Row).Copy Sheets("Complete").Range("A" & LrowCompleted + 1)
        'Delete Row from the ActiveSheet
        ActiveSheet.Range("A" & Target.Row & ":Z" & Target.Row).Delete xlShiftUp
    ElseIf Target.Column = 26 And Target.Cells(1).Value = "Outstanding" Then
        'Define last row on Outstanding worksheet to know where to place the row of data
        LrowCompleted = Sheets("Outstanding").Cells(Rows.Count, "A").End(xlUp).Row
        'Copy and paste data
        ActiveSheet.Range("A" & Target.Row & ":Z" & Target.Row).Copy Sheets("Outstanding").Range("A" & LrowCompleted + 1)
        'Delete Row from the ActiveSheet
        ActiveSheet.Range("A" & Target.Row & ":Z" & Target.Row).Delete xlShiftUp

    End If
     
    'Debug.Print ActiveSheet.Name
    
    Application.EnableEvents = True
End Sub

1.在Outstanding和Complete表单私有模块中,我们放置相同的代码,调用公共宏DoWorksheet_Change()

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
  DoWorksheet_Change Target
End Sub

相关问题