0

So I have a workbook with multiple worksheets where I grab the data on a particular sheet(s) depending upon whether a checkbox is checked (in the code below I have 3 check boxes that will grab the data on a particular worksheet depending upon whether it is checked). The data from each worksheet is copied to a sheet that already exists (in this case "Landing Pad") and added to the next empty row. I run the below code when a button is clicked:

Public Sub CommandButton1_Click()

Dim r As Long
Dim rcnt As Long
Dim Dst As Worksheet


With ThisWorkbook

Set Dst = .Sheets("Landing Pad")
Dst.Cells.ClearContents
Sheets("Landing Pad").Select
Selection.SpecialCells(xlCellTypeBlanks).EntireRow.Delete


'r = 2
rcnt = 1  ' stores amount of inserted rows

If Me.CheckBox1 = True Then
With .Sheets("IT Certification")
r = .Range("A" & .Rows.Count).End(xlUp).Row 
.Range("A1:D" & r).Copy _
Destination:=Dst.Range("A" & rcnt)
rcnt = rcnt + r 'lastrow
End With
End If

If Me.CheckBox2 = True Then
With .Sheets("Business Skills & Productivity")
r = .Range("A" & .Rows.Count).End(xlUp).Row 
.Range("A1:D" & r).Copy _
Destination:=Dst.Range("A" & rcnt)
rcnt = rcnt + r 
End With
End If

If Me.CheckBox3 = True Then
 With .Sheets("Database and Cybersecurity")
r = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A1:D" & r).Copy _
Destination:=Dst.Range("A" & rcnt)
rcnt = rcnt + r 
End With
End If

End With

End Sub

All the worksheets have the same structure (A:D) but some of them have duplicate values in column D. What I would like to do is have only rows copied depending upon the the values of one particular column (column D) so that there are no duplicate values in that column.

Here's what happens now:

Workbook1

A   B   C   D   
aa  ee  ii  zz  
bb  ff  jj  zz
cc  gg  kk  zz
dd  hh  ll  mm

        +

Workbook2

A   B   C   D
nn  pp  rr  tt
oo  qq  ss  uu

        =

New Workbook

A   B   C   D
aa  ee  ii  zz
bb  ff  jj  zz
cc  gg  kk  zz
dd  hh  ll  mm
nn  pp  rr  tt
oo  qq  ss  uu

And here's what I'd like to have happen:

Workbook1

A   B   C   D   
aa  ee  ii  zz  
bb  ff  jj  zz
cc  gg  kk  zz
dd  hh  ll  mm

        +

Workbook2

A   B   C   D
nn  pp  rr  tt
oo  qq  ss  uu

        =

New Workbook

A   B   C   D
aa  ee  ii  zz
dd  hh  ll  mm
nn  pp  rr  tt
oo  qq  ss  uu

I'm not sure on how to go about this...maybe instead of copying each worksheet at a time I could store them in a variable and perhaps use the RemoveDuplicates method to copy the data in the variable once all the data has been added? Or would this require maybe looping through each selected worksheet that has been chosen? Any help appreciated!

2
  • RemoveDuplicates only deletes a cells contents and not the cell's row.
    – Ted D.
    Mar 13, 2019 at 16:34
  • @dagda13 your post needs few corrections since the Code above shows that you are Coping Data from sheet to another in Workbook. But attached Screen Shot has Captions indicating that you are suppose to works with THREE Workbooks !! Mar 15, 2019 at 7:03

3 Answers 3

0

Edit 2 - First Code Block modified to work with ActiveX Controls in Sheet.

  • For a UserForm: Uncomment the comemnted out If ... Then ' UserForm and delete the following If line.

Edit 1 - Details on how to configure the Const user settings after the first code block.

I strongly encourage the use of the second code block. It removes this error prone kludge and the necessity to modify the code when there are checkbox changes (both the number of checkboxes and the destination sheet name associated with the checkbox).

COPY DISTINCT

If the destination should have distinct values in column D, only add rows which meet the condition.

Option Explicit

Private Const distinctCol = "D"
Private Const firstCol = "A"
Private Const lastCol = "D"
Private Const destination = "Landing Pad"
Private Const checkboxSource = "CheckBox1, IT Certification; CheckBox2, Business Skills & Productivity; CheckBox3, Database and Cybersecurity"
Private Const separator1 = ", " ' Checkbox Name <separator1> Worksheet Name
Private Const separator2 = "; " ' 1st box&sheet <separator2> 2nd box&sheet

Private Sub CommandButton1_Click()
    Dim r As Long
    Dim distinct As Boolean
    Dim copiedRows As Long
    Dim copyRowCount As Long
    Dim copyRange As Range
    Dim copyDistinct As Range
    Dim Dws As Worksheet, Sws As Worksheet
    Dim checkBoxAndSource As Variant

    Set Dws = ThisWorkbook.Worksheets(destination)
    Dws.Cells.ClearContents
    Dws.Select
    On Error Resume Next
    Selection.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
    On Error GoTo 0

    copiedRows = 0

    For Each checkBoxAndSource In Split(checkboxSource, separator2)
        'If Me(Split(checkBoxAndSource, separator1)(0)) Then ' UserForm
        If Me.OLEObjects(Split(checkBoxAndSource, separator1)(0)).Object Then
            Set Sws = ThisWorkbook.Worksheets(Split(checkBoxAndSource, separator1)(1))
            Set copyRange = Nothing
            Set copyDistinct = Nothing
            copyRowCount = 0
            For r = 1 To Sws.Range(distinctCol & Sws.Rows.Count).End(xlUp).Row
                distinct = True
                If copiedRows Then
                    distinct = Dws.Range(distinctCol & 1, distinctCol & _
                        copiedRows).Find(Sws.Cells(r, distinctCol)) Is Nothing
                End If
                If distinct And Not copyDistinct Is Nothing Then
                    distinct = copyDistinct.Find(Sws.Cells(r, distinctCol)) Is Nothing
                End If
                If distinct Then
                    If copyRowCount Then
                        Set copyRange = Union(copyRange, Sws.Range(firstCol & r, lastCol & r))
                        Set copyDistinct = Union(copyDistinct, Sws.Cells(r, distinctCol))
                    Else
                        Set copyRange = Sws.Range(firstCol & r, lastCol & r)
                        Set copyDistinct = Sws.Cells(r, distinctCol)
                    End If
                    copyRowCount = copyRowCount + 1
                End If
            Next r
            If Not copyRange Is Nothing Then
                copyRange.Copy destination:=Dws.Cells(copiedRows + 1, firstCol)
                copiedRows = copiedRows + copyRowCount
            End If
        End If
    Next checkBoxAndSource
End Sub

Edit: Const configuration.

  • The three Const, checkboxSource, separator1 and separator2 work in unison.
  • The main Const is checkboxSource.
    • This is where the checkboxes are associated with their respective sheet names.
    • There can be as few as one and as many as one likes.
  • The Const separator are only used to delimit the checkboxSource string.
    • The comment following them describes what the separator is separating.
    • The separators should include a space after the character if that is the way the checkboxSource string was formed.
  • All three were set according to the original OP code so the OP would not need to change anything.
  • The reason for not hard coding the separator values is because both , and ; can be used in a sheet's name (although they should not be).

The whole CheckBox1 → "Sheet Name" is a bit kludgy.

This implementation uses the Form's Controls Properties instead.

To complete the implementation of this code, read the instructions for configuring the Form's Controls Properties following this code block.

Option Explicit

Private Const distinctCol = "D"
Private Const firstCol = "A"
Private Const lastCol = "D"

Private Sub CommandButton1_Click()
    Dim r As Long
    Dim distinct As Boolean
    Dim copiedRows As Long
    Dim copyRowCount As Long
    Dim copyRange As Range
    Dim copyDistinct As Range
    Dim Dws As Worksheet, Sws As Worksheet
    Dim ctrl As Control

    Set Dws = ThisWorkbook.Worksheets(Me.CommandButton1.Tag)
    Dws.Cells.ClearContents
    Dws.Select
    On Error Resume Next
    Selection.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
    On Error GoTo 0

    copiedRows = 0
    For Each ctrl In Me.Controls
      If TypeName(ctrl) = "CheckBox" Then
        If ctrl.GroupName = Me.CommandButton1.Tag Then
          If ctrl Then
            Set Sws = ThisWorkbook.Worksheets(ctrl.Tag)
            Set copyRange = Nothing
            Set copyDistinct = Nothing
            copyRowCount = 0
            For r = 1 To Sws.Range(distinctCol & Sws.Rows.Count).End(xlUp).Row
                distinct = True
                If copiedRows Then
                    distinct = Dws.Range(distinctCol & 1, distinctCol & _
                        copiedRows).Find(Sws.Cells(r, distinctCol)) Is Nothing
                End If
                If distinct And Not copyDistinct Is Nothing Then
                    distinct = copyDistinct.Find(Sws.Cells(r, distinctCol)) Is Nothing
                End If
                If distinct Then
                    If copyRowCount Then
                        Set copyRange = Union(copyRange, Sws.Range(firstCol & r, lastCol & r))
                        Set copyDistinct = Union(copyDistinct, Sws.Cells(r, distinctCol))
                    Else
                        Set copyRange = Sws.Range(firstCol & r, lastCol & r)
                        Set copyDistinct = Sws.Cells(r, distinctCol)
                    End If
                    copyRowCount = copyRowCount + 1
                End If
            Next r
            If Not copyRange Is Nothing Then
                copyRange.Copy destination:=Dws.Cells(copiedRows + 1, firstCol)
                copiedRows = copiedRows + copyRowCount
            End If
          End If
        End If
      End If
    Next ctrl
End Sub

These are the Property Settings for the Form Controls

  • The CommandButton's Tag is both:
    • the Destination Sheet Name (OP: "Landing Pad") and
    • the CheckBox's GroupName
  • The CheckBox's Tag is its Source Sheet Name (OP: cb1.tag "IT Certification").
  • The CheckBox's GroupName is its associated CommandButton's Tag.
    (See CommanButton's Tag above. This is also the Destination Sheet Name.)
    • This convention allows the button to be associated with the checkboxes.
    • It is a guard against the form's other checkboxes being included in the operation.
8
  • Thanks very much, Ted. When I used 'Copy Distinct', I received a Run-time error '9', Subscript out of range. When I ran the debugger : If Me(Split(checkBoxAndSource, separator1)(0)) Then was highlighted. I'm wondering if I did not asign Private Const separator1 the correct values, as below: Private Const separator1 = "CheckBox1, IT Certification" ' Checkbox Name <separator1> Worksheet Name Private Const separator2 = "CheckBox1, IT Certification; CheckBox2, Business Skills & Productivity" ' 1st box&sheet <separator2> 2nd box&sheet
    – dagda13
    Mar 14, 2019 at 21:54
  • @dagda13, The code was already configured for you according to your OP. None of the user Const needed to be changed. That being said, I have added additional instructions. I encourage you to reread the non code content in the answer. Do understand, the answer code completely replaces your Public Sub CommandButton1_Click() code (it is not in addition to, nor do you call it from your code, but rather, it replaces your code and is called by the click of the form's button1). Consider using the second code block instead, change a couple of the form's properties and no more Const to deal with.
    – Ted D.
    Mar 15, 2019 at 1:13
  • Thanks again, still learning on how to access Form Controls Properties. I’m able to access the GroupName field when I right-click on the check boxes but I do not see the Tag property when I right click on CommandButton1. Just want to make sure that these are the fields to be modified or should I modify the code itself, as for example I can see CommandButton1.Tag.
    – dagda13
    Mar 15, 2019 at 13:56
  • The second code block uses a Form's Controls' Properties and not a sheet's ActiveX Controls' Properties. There is no Tag property for these ActiveX Controls when inserted directly to a sheet. Therefore, use the first code block without modifying the Const which already have the proper values as outlined in the OP.
    – Ted D.
    Mar 15, 2019 at 15:57
  • Gotcha. When I run the first code block I get: Run-time error ‘438’: Object doesn’t support this property or method. When I use the debugger, line If Me(Split(checkBoxAndSource, separator1)(0)) Then Is highlighted.
    – dagda13
    Mar 15, 2019 at 16:32
0

This little code should do it for you.
See "Sub Test" how to call "delDoubleRow".

Private Sub delDoubleRow(aSht As Worksheet, aCol As String)
Dim rx As Long
Dim lastrow As Long

lastrow = aSht.Range(aCol & aSht.Rows.Count).End(xlUp).Row
For rx = lastrow To 1 Step -1  'count backwards from last to keep next row(rx) valid!
  If WorksheetFunction.CountIf(aSht.Range(aCol & "1" & ":" & aCol & rx), aSht.Range(aCol & rx)) > 1 Then
    aSht.Rows(rx).EntireRow.Delete
  End If
Next
End Sub

Public Sub Test()
delDoubleRow ThisWorkbook.Sheets("Landing Pad"), "D"
End Sub
3
  • Thanks for the help, again! Unfortunately the code does not appear to work. I may not be incorporating it properly into the code I have above.
    – dagda13
    Mar 13, 2019 at 19:26
  • Do you have further information like messages or so, or don't you know how sub-/function-calls are used ?
    – busybyte
    Mar 13, 2019 at 21:38
  • No messages, and no. Still new to VBA, and lots still to learn obviously...but this has been very educational. :)
    – dagda13
    Mar 13, 2019 at 22:23
-1

I would like to suggest this VBA code (Macro), will help you to Delete entire Row/Rows based on Duplicate Values in Column D.

Sub RemoveDuplicatesCells_EntireRow()


Dim rng As Range
Dim x As Integer

Sheets("LandingPad").Activate 
Set rng = Sheets("LandingPad").Range("A:D")
Range("A:D").Select


  Application.ScreenUpdating = False


  On Error GoTo InvalidSelection
  Set rng = Selection
  On Error GoTo 0


  On Error GoTo InputCancel
    x = InputBox("Which Column Should Look For Duplicates? (Number only!)", _
      "Select A Column", 1)
  On Error GoTo 0


  Application.Calculation = xlCalculationManual


  rng.EntireRow.RemoveDuplicates Columns:=x

  Application.Calculation = xlCalculationAutomatic

  With ActiveSheet
    .EnableSelection = xlNoSelection
  End With

 Application.CutCopyMode = False


Exit Sub


InvalidSelection:
  MsgBox "You selection is not valid", vbInformation
  Exit Sub

InputCancel:

End Sub

How it works:

  • Copy & Paste this code with Landing Pad Sheet as Standard Module.
  • Activate this MACRO using Call RemoveDuplicatesCells_EntireRow statement just before the last End With in the Code you are using to Copy Data From different Sheets to Landing Pad Sheet.
  • Use this command line to call the MACRO.

Call LandingPad.RemoveDuplicatesCells_EntireRow

  • Respond INPUT BOX with the appropriate Column Number, in your case is 4 for D.
4
  • Thanks Rajesh! I copied and pasted Sub RemoveDuplicatesCells_EntireRow() below the code that Im using, and called it before the last End With. I receive the following error when I click the button: Run-time error ‘1004’ Select method of Range class failed When I run the debugger the following line in Sub RemoveDuplicatesCells_EntireRow() is highlighted: Range("A:D").Select My destination worksheet (Sheet14 (Landing Pad)) is in the Microsoft Excel Objects…I’m not sure if I’m setting it correctly as a standard module and maybe this is the problem? Thanks again for all the help!
    – dagda13
    Mar 15, 2019 at 13:42
  • @dagda13, as far my Code is concern is working without any error, I've tested it many times before post as Answer here. Let me check one more time. Mar 16, 2019 at 5:10
  • @dagda13, check my post I've edited Line no 4, 5 & 6 to activate the Sheet LANDINGPAD to delete the duplicate Rows. Also,, while test your code I got lots of error Invalid use of properties & Methods,, for WITH This Workbook then next WITH also !! Mar 16, 2019 at 5:41
  • @dagda13 use this command line to activate Macro Call LandingPad.RemoveDuplicatesCells_EntireRow. Since the Macro is stored with Sheet LandingPad Check the How it works section with my post there also I've edited. Mar 16, 2019 at 6:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .