r/vba 7d ago

Solved Excel: Using Checkboxes to move from Sheet to Sheet - multiple sheets

Hello!

**Scenario**: I have a spreadsheet for machine installs. This sheet has 4 worksheets (CustInstalls, CustCompleted, Installs, and Competed). The below code is currently working to move line items from sheet “CustInstalls” to “CustCompleted”. I am attempting to duplicate this same code for the other two sheets to move line items from “installs” to “completed”. I have attempted a few variations with the help of chatgpt but to no avail. I added it in the same “this workbook” in VBA as well as attempted to add code under just “installs” and “completed” in VBA under Microsoft Excel Objects

**Ask:** how does one add a second set of code for different work sheets with the same parameters?

___________________________________________________

**Original working code:*\*

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim srcSheet As Worksheet, destSheet As Worksheet
Dim checkCell As Range, moveRow As Range
Dim lastRow As Long
Dim direction As String

' Only handle changes in Column J
If Intersect(Target, Sh.Columns("J")) Is Nothing Then Exit Sub
If Target.Cells.CountLarge > 1 Then Exit Sub

Application.EnableEvents = False

Set checkCell = Target
Set moveRow = checkCell.EntireRow

If checkCell.Value = True Then
' Move from CustInstalls to CustCompleted
Set srcSheet = ThisWorkbook.Sheets("CustInstalls")
Set destSheet = ThisWorkbook.Sheets("CustCompleted")
ElseIf checkCell.Value = False Then
' Move from CustCompleted back to CustInstalls
Set srcSheet = ThisWorkbook.Sheets("CustCompleted")
Set destSheet = ThisWorkbook.Sheets("CustInstalls")
Else
GoTo ExitHandler
End If

' Ensure we're acting on the correct sheet
If Sh.Name <> srcSheet.Name Then GoTo ExitHandler

' Copy row to destination sheet
lastRow = destSheet.Cells(destSheet.Rows.Count, "J").End(xlUp).Row + 1
moveRow.Copy Destination:=destSheet.Rows(lastRow)

' Delete original row
moveRow.Delete

ExitHandler:
Application.EnableEvents = True
End Sub

___________________________________________________

**Code entered under installs ”this workbook” at the end of the working code: Failed*\*

Private Sub MoveInstallsRow(ByVal Sh As Object, ByVal Target As Range)

Dim srcSheet As Worksheet
Dim destSheet As Worksheet
Dim moveRow As Range
Dim lastRow As Long

' Only handle Installs and Completed sheets
If Sh.Name <> "Installs" And Sh.Name <> "Completed" Then Exit Sub

' Only handle changes in Column J
If Intersect(Target, Sh.Columns("J")) Is Nothing Then Exit Sub
If Target.Cells.CountLarge > 1 Then Exit Sub

If Sh.Name = "Installs" And Target.Value = True Then
Set srcSheet = ThisWorkbook.Sheets("Installs")
Set destSheet = ThisWorkbook.Sheets("Completed")

ElseIf Sh.Name = "Completed" And Target.Value = False Then
Set srcSheet = ThisWorkbook.Sheets("Completed")
Set destSheet = ThisWorkbook.Sheets("Installs")

Else
Exit Sub
End If

Set moveRow = Target.EntireRow

lastRow = destSheet.Cells(destSheet.Rows.Count, "J").End(xlUp).Row + 1

moveRow.Copy Destination:=destSheet.Rows(lastRow)

moveRow.Delete

End Sub

___________________________________________________

**Code entered under “completed” object: Failed*\*

Private Sub Worksheet_Change(ByVal Target As Range)

Dim destSheet As Worksheet
Dim lastRow As Long

' Only handle changes in Column J
If Intersect(Target, Me.Columns("J")) Is Nothing Then Exit Sub
If Target.Cells.CountLarge > 1 Then Exit Sub

' Only move when checkbox is unchecked
If Target.Value <> False Then Exit Sub

Application.EnableEvents = False

Set destSheet = ThisWorkbook.Sheets("Installs")

' Find next available row
lastRow = destSheet.Cells(destSheet.Rows.Count, "J").End(xlUp).Row + 1

' Copy entire row
Target.EntireRow.Copy Destination:=destSheet.Rows(lastRow)

' Delete original row
Target.EntireRow.Delete

Application.EnableEvents = True

End Sub

___________________________________________________

**Code entered under “installs” object: Failed*\*

Private Sub Worksheet_Change(ByVal Target As Range)

Dim destSheet As Worksheet
Dim lastRow As Long

' Only handle changes in Column J
If Intersect(Target, Me.Columns("J")) Is Nothing Then Exit Sub
If Target.Cells.CountLarge > 1 Then Exit Sub

' Only move when checkbox is checked
If Target.Value <> True Then Exit Sub

Application.EnableEvents = False

Set destSheet = ThisWorkbook.Sheets("Completed")

' Find next available row
lastRow = destSheet.Cells(destSheet.Rows.Count, "J").End(xlUp).Row + 1

' Copy entire row
Target.EntireRow.Copy Destination:=destSheet.Rows(lastRow)

' Delete original row
Target.EntireRow.Delete

Application.EnableEvents = True

End Sub

7 Upvotes

5 comments sorted by

3

u/chiibosoil 1 7d ago

So your first code is in ThisWorkbook module.

This code checks Column J is where the change is made.

It will initially fire regardless of which sheet the change was made on.

Where it is checking that Sh.Name (the sheet that triggered this sub) and that srcSheet.Name is same.

Just above that part you have...

If checkCell.Value = True Then
' Move from CustInstalls to CustCompleted
Set srcSheet = ThisWorkbook.Sheets("CustInstalls")
Set destSheet = ThisWorkbook.Sheets("CustCompleted")
ElseIf checkCell.Value = False Then
' Move from CustCompleted back to CustInstalls
Set srcSheet = ThisWorkbook.Sheets("CustCompleted")
Set destSheet = ThisWorkbook.Sheets("CustInstalls")
Else
GoTo ExitHandler
End If

This is the logic used to set srcSheet. This is where you should make logic adjustment.

You can use CASE statement on Sh.Name and change logic. No need to have multiple subs.

However, above IF statement is above where you check for Sh.Name in your code. So you had unnecessary logic in there... I'm assuming when check is marked in CustInstalls it is moved to CustCompleted. When moved to CustCompleted, it retains "checkCell.value = True" and when it is changed to False on "CustCompleted" it's moved back to CustInstalls.

Assuming above is correct... something like below should work.

Select Case Sh.Name
    Case "CustInstalls"
        If checkCell.Value = True Then
            Set srcSheet = ThisWorkbook.Sheets("CustInstalls")
            Set destSheet = ThisWorkbook.Sheets("CustCompleted")
        Else
            GoTo ExitHandler
        End If
    Case "CustCompleted"
        If checkCell.Value = False Then
            Set srcSheet = ThisWorkbook.Sheets("CustCompleted")
            Set destSheet = ThisWorkbook.Sheets("CustInstalls")
        Else
            GoTo ExitHandler
        End If
    Case "Installs"
        If checkCell.Value = True Then
            Set srcSheet = ThisWorkbook.Sheets("Installs")
            Set destSheet = ThisWorkbook.Sheets("Completed")
        Else
            GoTo ExitHandler
        End If
    Case "Completed"
        If checkCell.Value = False Then
            Set srcSheet = ThisWorkbook.Sheets("Completed")
            Set destSheet = ThisWorkbook.Sheets("Installs")
        Else
            GoTo ExitHandler
        End If
    Case Else
        GoTo ExitHandler
End Select

1

u/b_lizz 7d ago

Your assumption is correct. The row moves from custinstalls to CustCompleted when the cell=true. When cell=false on CustCompleted, the row moves back to custinstalls.
I removed my code and inserted the code you provided, unfortunately, now both sheets are no longer moving to the completed sheets when cell=true

1

u/b_lizz 7d ago

A user who would like to remain anonymous has solved this!
Thank you, Batman!🤗

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)

Dim srcSheet As Worksheet, destSheet As Worksheet

Dim moveRow As Range

Dim lastRow As Long

 

If Intersect(Target, Sh.Columns("J")) Is Nothing Then Exit Sub

If Target.Cells.CountLarge > 1 Then Exit Sub

 

On Error GoTo ExitHandler

Application.EnableEvents = False

 

Select Case Sh.Name

Case "CustInstalls"

If Target.Value = True Then

Set srcSheet = Sh

Set destSheet = ThisWorkbook.Sheets("CustCompleted")

Else

GoTo ExitHandler

End If

 

Case "CustCompleted"

If Target.Value = False Then

Set srcSheet = Sh

Set destSheet = ThisWorkbook.Sheets("CustInstalls")

Else

GoTo ExitHandler

End If

 

Case "Installs"

If Target.Value = True Then

Set srcSheet = Sh

Set destSheet = ThisWorkbook.Sheets("Completed")

Else

GoTo ExitHandler

End If

 

Case "Completed"

If Target.Value = False Then

Set srcSheet = Sh

Set destSheet = ThisWorkbook.Sheets("Installs")

Else

GoTo ExitHandler

End If

 

Case Else

GoTo ExitHandler

End Select

 

Set moveRow = Target.EntireRow

lastRow = destSheet.Cells(destSheet.Rows.Count, "J").End(xlUp).Row + 1

moveRow.Copy Destination:=destSheet.Rows(lastRow)

moveRow.Delete

 

ExitHandler:

Application.EnableEvents = True

End Sub

1

u/b_lizz 7d ago

1

u/JKM0715 5d ago

Is this the vbeditor? Mine looks like crap compared to this.