Here's my first VBA project. I have some very limited Python experience, and this is my first VBA project. I'm sure I could have done it a lot more simply, but I just stuck with what I knew, and googled what I didn't, so feedback is very welcome.The basic purpose is to compare a table from one sheet (OP) with a table from another (Payroll) and print the discrepancies in a third sheet (Results).One last thing I want to do, but can't figure out (without using GoTo, which I read is bad) is to protect the worksheets after I Exit Sub on lines 22, 31, etc. (code for protecting sheets is already written in line 130 - 138.Sub Macro1()Dim counter As IntegerSet OPdata = New DictionarySet Payrolldata = New DictionarySet HRIDnames = New Dictionary'Unprotects sheetsWorksheets(Results).Unprotect Password:=Worksheets(OP).Unprotect Password:=Worksheets(Payroll).Unprotect Password:=' Clears Results worksheetWorksheets(Results).ActivateRange(A3:L10000).ClearContents' Looks for missing data in the OP worksheetWorksheets(OP).ActivateRange(A2).SelectIf IsEmpty(ActiveCell) Then    MsgBox There is data missing    Exit SubEnd IfWorksheets(OP).ActivateRange(A1).CurrentRegion.SelectFor Each C In Selection    If C =  Then    C.Select    MsgBox There is data missing    Exit Sub    End IfNext' Looks for missing data in the Payroll worksheetWorksheets(Payroll).ActivateRange(A2).SelectIf IsEmpty(ActiveCell) Then    MsgBox There is data missing    Exit SubEnd IfWorksheets(Payroll).ActivateRange(A1).CurrentRegion.SelectFor Each C In Selection    If C =  Then    C.Select    MsgBox There is data missing    Exit Sub    End IfNext' Populate OPdata dictionaryWorksheets(OP).ActivateRange(A2, ActiveCell.End(xlDown)).SelectFor Each cl In Selection    OPdata.Add cl.Value, cl.Offset(0, 2).Value &   & cl.Offset(0, 3).Value    HRIDnames.Add cl.Value, cl.Offset(0, 1).ValueNext' Populate Payrolldata dictionaryWorksheets(Payroll).ActivateRange(A2, ActiveCell.End(xlDown)).SelectFor Each cl In Selection    Payrolldata.Add cl.Value, cl.Offset(0, 2).Value &   & cl.Offset(0, 3).Value    If HRIDnames.Exists(cl.Value) = False Then    HRIDnames.Add cl.Value, cl.Offset(0, 1).Value    End IfNext' finds unique values in OPdata and prints them to columns A:CWorksheets(Results).ActivateRange(A3).SelectFor Each i In OPdata    If Payrolldata.Exists(i) = False Then    ActiveCell = i    ActiveCell.Offset(0, 2).Select    ActiveCell = OPdata.Item(i)    ActiveCell.Offset(1, -2).Select    End IfNext' finds unique values in Payrolldata and prints them to columns E:GWorksheets(Results).ActivateRange(E3).SelectFor Each i In Payrolldata    If OPdata.Exists(i) = False Then    ActiveCell = i    ActiveCell.Offset(0, 2).Select    ActiveCell = Payrolldata.Item(i)    ActiveCell.Offset(1, -2).Select    End IfNext' Finds salary discrepencies and prints them to columns I:LWorksheets(Results).ActivateRange(I3).SelectFor Each i In OPdata    If Payrolldata.Exists(i) Then        If Not OPdata.Item(i) = Payrolldata.Item(i) Then        ActiveCell = i        ActiveCell.Offset(0, 2).Select        ActiveCell = OPdata.Item(i)        ActiveCell.Offset(0, 1).Select        ActiveCell = Payrolldata.Item(i)        ActiveCell.Offset(1, -3).Select        End If    End IfNext' Prints namesSheets(Results).Range(A3).SelectWhile Not IsEmpty(ActiveCell)    ActiveCell.Offset(0, 1) = HRIDnames.Item(ActiveCell.Value)    ActiveCell.Offset(1).SelectWendSheets(Results).Range(E3).SelectWhile Not IsEmpty(ActiveCell)    ActiveCell.Offset(0, 1) = HRIDnames.Item(ActiveCell.Value)    ActiveCell.Offset(1).SelectWendSheets(Results).Range(I3).SelectWhile Not IsEmpty(ActiveCell)    ActiveCell.Offset(0, 1) = HRIDnames.Item(ActiveCell.Value)    ActiveCell.Offset(1).SelectWend' Reprotect WorksheetsWorksheets(Results).Protect Password:=Worksheets(OP).Protect Password:=Worksheets(Payroll).Protect Password:=' Success messageIf WorksheetFunction.CountA(Range(A3:L3)) = 0 ThenMsgBox (Congratulations! OurPeople and Payroll reconcile exactly!)End IfEnd Sub
Comparing tables and printing discrepancies
vba;excel