How to copy and paste faster? - excel

I copy data from "database" and paste it to another sheet.
Macro takes the names from the list in Sheet1 and looks for matches in Sheet2.
When the match is found it is copying a specific cell.
I have a macro for each person on the list so I have five macros doing the same thing so maybe that why it takes so much time (around three minutes).
Is there any way to make it faster?
Sub CopySalesMan1()
Dim lastrow As Long, erow As Long
lastrow = Worksheets("Sheet2").Cells(Rows.Count, 2).End(xlUp).Row
For i = 2 To lastrow
If Worksheets("Sheet2").Cells(i, 25).Value = Worksheets("Sheet1").Cells(6, 12).Value Then
Worksheets("Sheet2").Cells(i, 2).Copy
erow = Worksheets("Sheet1").Cells(Rows.Count, 4).End(xlUp).Row
Worksheets("Sheet1").Cells(erow + 1, 3).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Sheet2").Cells(i, 25).Copy
Worksheets("Sheet1").Cells(erow + 1, 4).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Sheet2").Cells(i, 3).Copy
Worksheets("Sheet1").Cells(erow + 1, 5).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Sheet2").Cells(i, 4).Copy
Worksheets("Sheet1").Cells(erow + 1, 6).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Sheet2").Cells(i, 5).Copy
Worksheets("Sheet1").Cells(erow + 1, 7).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Sheet2").Cells(i, 6).Copy
Worksheets("Sheet1").Cells(erow + 1, 8).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Sheet2").Cells(i, 21).Copy
Worksheets("Sheet1").Cells(erow + 1, 9).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
Next i
End Sub
And the macro calling for every salesman in the list
Sub All()
If Worksheets("Sheet1").Range("L7").Value <> "" Then Call CopySalesMan2
If Worksheets("Sheet1").Range("L8").Value <> "" Then Call CopySalesMan3
If Worksheets("Sheet1").Range("L9").Value <> "" Then Call CopySalesMan4
If Worksheets("Sheet1").Range("L10").Value <> "" Then Call CopySalesMan5
End Sub
Sheet1
Sheet2 (database)

I got the solution:
as braX said .value = .value will be better option
Sub CopySalesMan()
Application.ScreenUpdating = False
Dim XlWkSht As Worksheet, sVal As String, lRow As Long, i As Long, r As Long
Set XlWkSht = Worksheets("Sheet1")
lRow = XlWkSht.Range("D" & XlWkSht.Rows.Count).End(xlUp).Row
For i = 6 To 10
If XlWkSht.Range("L" & i).Value <> "" Then
sVal = XlWkSht.Range("L" & i).Value
With Worksheets("Sheet2")
For r = 2 To .Range("B" & .Rows.Count).End(xlUp).Row
If .Range("Y" & r).Value2 = sVal Then
lRow = lRow + 1
XlWkSht.Range("B" & lRow).Value = .Range("B" & r).Value
XlWkSht.Range("C" & lRow).Value = .Range("Y" & r).Value
XlWkSht.Range("D" & lRow).Value = .Range("C" & r).Value
XlWkSht.Range("E" & lRow).Value = .Range("D" & r).Value
XlWkSht.Range("F" & lRow).Value = .Range("E" & r).Value
XlWkSht.Range("G" & lRow).Value = .Range("F" & r).Value
XlWkSht.Range("H" & lRow).Value = .Range("U" & r).Value
End If
Next r
End With
End If
Next
Application.ScreenUpdating = True
End Sub

Related

How to apply a macro to selected row only

I'm really new at maccros.
I've made one using the auto recording, but I can't seem to use it to the selected row only, it keeps doing it on the same row as the record.
I really need your help to solve it, and help me having a better understanding on how maccros actually works
My macro is as follow:
Sub COPIERVALEURS()
'
' COPIERVALEURS Macro
'
' Touche de raccourci du clavier: Ctrl+Shift+V
'
Range("A34:H34").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("M34:N34").Select
Application.CutCopyMode = False
Selection.Copy
Range("K34").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("S34:T34").Select
Application.CutCopyMode = False
Selection.Copy
Range("Q34").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("Y34:Z34").Select
Application.CutCopyMode = False
Selection.Copy
Range("W34").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("AE34:AF34").Select
Application.CutCopyMode = False
Selection.Copy
Range("AC34").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveWindow.SmallScroll ToRight:=5
Range("AI34:AJ34").Select
Application.CutCopyMode = False
Selection.Copy
Range("AG34").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("AK34").Select
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
I try to understand your logic to help you as much as i can. Select the row you want this code to take action, import a break point in the With line, execute and debug the code to see if its fits your requirements. In order to select a line press on the number of each line on your left.
Code:
Option Explicit
Sub test()
Dim RowNo As Long
With ThisWorkbook.Worksheets("Sheet1")
RowNo = Selection.Row '<- Here you get the row number you have select
.Range("M" & RowNo & ":N" & RowNo).Copy '<- Copy range M:N of the RowNo you have selct
.Range("K" & RowNo).PasteSpecial Paste:=xlPasteValues '<- Paste in Column K row the one tou have select
.Range("S" & RowNo & ":T" & RowNo).Copy
.Range("Q" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("Y" & RowNo & ":Z" & RowNo).Copy
.Range("W" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("AE" & RowNo & ":AF" & RowNo).Copy
.Range("AC" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("AI" & RowNo & ":AJ" & RowNo).Copy
.Range("AG" & RowNo).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End With
End Sub
Thanks Error 1004, It helped me a lot, the final code is now as below, and work perfectly, thanks to you:
Option Explicit
Sub COPIERVALEURS()
' COPIERVALEURS Macro
' Touche de raccourci du clavier: Ctrl+Shift+V
Dim RowNo As Long
With ThisWorkbook.Worksheets("PAQ")
RowNo = Selection.Row '<- Here you get the row number you have select
.Range("A" & RowNo & ":H" & RowNo).Copy
.Range("A" & RowNo & ":H" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("M" & RowNo & ":N" & RowNo).Copy
.Range("K" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("S" & RowNo & ":T" & RowNo).Copy
.Range("Q" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("Y" & RowNo & ":Z" & RowNo).Copy
.Range("W" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("AE" & RowNo & ":AF" & RowNo).Copy
.Range("AC" & RowNo).PasteSpecial Paste:=xlPasteValues
ActiveWindow.SmallScroll ToRight:=5
.Range("AI" & RowNo & ":AJ" & RowNo).Copy
.Range("AG" & RowNo).PasteSpecial Paste:=xlPasteValues
.Range("AK" & RowNo).Copy
.Range("AK" & RowNo).PasteSpecial Paste:=xlPasteValues
End With
End Sub

How to convert Excel VBA created on a mac to Windows?

I've made a VBA for a button in Excel for Mac that is supposed to copy the content of a few selected cells on one tab and paste it (as values) on the first available cell in an assigned row on a different tab.
This is the first time I've ever had a go at making this, so I probably didn't do it as efficient as possible, but it works.
The problem is that it only works on Mac. My co-workers that I've made it for uses PC. Can I convert the code to work on Excel for PC?
Edit: I should have been more explicit into what the problem actually is (thanks #KenWhite).
So here's what happened:
I created the file and the VBA.
I saved my file and attatched it to an email
my co-worker saved it and opened it up
When she pressed the button she got an error "Indexet är utanför intervall". My best translation for this is Index out of Range (but I'm not completely sure)
I suspected that it had to do with Mac -> PC, but some have pointed out that there should be no difference. I realize that the named on the sheets and that the data needs to be in the exact same spot - but that shouldn't be an issue in this case.
Edit 2: It seems to be a problem with special characters. the "ä" and "ö" used in the sheet names where changed in to "š" and "¨" in the VBA code on their end. I can't test it right now, but my guess is that the code will work if I either manually change the characters in the code or make sure to use sheet names without special characters.
If I should/could add additional information, let me know and I'll make another edit.
Thank you everyone.
Sub Generera()
'
' Generera Makro
'
'
Range("B1").Select
Selection.Copy
Sheets("Utveckling över tid").Select
BMaxRows = Cells(Rows.Count, "B").End(xlUp).Row
Range("B" & BMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B2").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
CMaxRows = Cells(Rows.Count, "C").End(xlUp).Row
Range("C" & CMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B3").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
DMaxRows = Cells(Rows.Count, "D").End(xlUp).Row
Range("D" & DMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B4").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
EMaxRows = Cells(Rows.Count, "E").End(xlUp).Row
Range("E" & EMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B6").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
FMaxRows = Cells(Rows.Count, "F").End(xlUp).Row
Range("F" & FMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B7").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
GMaxRows = Cells(Rows.Count, "G").End(xlUp).Row
Range("G" & GMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B8").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
HMaxRows = Cells(Rows.Count, "H").End(xlUp).Row
Range("H" & HMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B9").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("veckoräckvidd").Select
Range("B11").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
IMaxRows = Cells(Rows.Count, "I").End(xlUp).Row
Range("I" & IMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("veckoräckvidd").Select
Range("B12").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Utveckling över tid").Select
JMaxRows = Cells(Rows.Count, "J").End(xlUp).Row
Range("J" & JMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
I believe this is a replacement for your current macro, so this might solve your problem.
Sub Generera()
Dim ws1 As Worksheet
Set ws1 = sheets("Utveckling över tid")
Dim ws2 As Worksheet
Set ws2 = sheets("veckoräckvidd")
Dim i As Long
For i = 2 To 10
Dim colLetter As String
colLetter = Split(Cells(1, i).Address, "$")(1)
ws1.Range(colLetter & ws1.Cells(rows.count, colLetter).End(xlUp).row + 1).value = ws2.Range("B" & i - 1).value
Next i
End Sub
Here are the steps I took to convert your original code to my shorter version:
Range("B1").Select
Selection.copy
sheets("Utveckling över tid").Select
BMaxRows = Cells(rows.count, "B").End(xlUp).row
Range("B" & BMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Stopped using .Select, and started using direct Range().value transferring instead of .copy and .pastespecial so that I dont have to juggle cutcopymode and because you're not doing anything special, just copying the values only.
BMaxRows = sheets("veckoräckvidd").Cells(rows.count, "B").End(xlUp).row
sheets("veckoräckvidd").Range("B" & BMaxRows + 1).value = _
sheets("Utveckling över tid").Range("B1").value
Include the statement for BMaxRows inside of the range itself for eventual simplicity.
sheets("veckoräckvidd").Range("B" & sheets("veckoräckvidd").Cells(rows.count, "B").End(xlUp).row + 1).value = _
sheets("Utveckling över tid").Range("B1").value
Use Worksheet variables to shorten every time that I need to refer to one of the sheet names.
ws2.Range("B" & ws2.Cells(rows.count, "B").End(xlUp).row + 1).value = _
ws1.Range("B1").value
And to convert it to a loop you can compare a couple of the converted operations side by side to see what changes every instance. In this case it's the column letter for ws2 and the row number in ws1.
ws2.Range("B" & ws2.Cells(rows.count, "B").End(xlUp).row + 1).value = ws1.Range("B1").value
ws2.Range("C" & ws2.Cells(rows.count, "C").End(xlUp).row + 1).value = ws1.Range("B2").value
ws2.Range("D" & ws2.Cells(rows.count, "D").End(xlUp).row + 1).value = ws1.Range("B3").value

Range.Find(String) Doesn't Work

I have the following Spreadsheet:
[Data in Columns A-Q and almost 3000 Rows][1]
I have a dropdown on another page that has a cell for Name/Mode/Shift Listed on it and am creating a variable for each. For some reason when I change a field in a drop down, I get a '91' Object error. When I use a combination of all of the items in the dropdown that are in the 1st position, the macro works just fine. The issue is always when I change either the DC/Mode/Shift. DC is a string, Mode is a String, and Shift is an Integer.
Each Dim Search / Dim FindRow was it's own passthrough function but combined everything. Any help would be much appreciated!!!
Below is my code:
Sub DailyRouteInput_Button8_Click()
Dim DC As String
Worksheets("Daily Route Input").Activate
Range("U1").Select
DC = ActiveCell.Value
ActiveCell.Offset(0, 1).Select
Mode = ActiveCell.Value
Range("C5").Select
Shift = ActiveCell.Value
Worksheets("Daily Route Master Data").Activate
(Was new passthrough function)
Dim SearchRange As Range
Dim FindRow As Range
Set SearchRange = Range("A2", Range("A2").End(xlUp))
Set FindRow = SearchRange.Find(What:=DC, LookIn:=xlValues, lookat:=xlWhole)
DC = FindRow.Row '---- Here is where the problem is ---------
Range("A" & DC).Offset(0, 1).Select
(Was new passthrough function)
Dim newSearchRange As Range
Dim newFindRow As Range
Set newSearchRange = Range("B" & DC, Range("B" & DC).End(xlUp))
Set newFindRow = newSearchRange.Find(Mode, LookIn:=xlValues, lookat:=xlWhole)
Mode = newFindRow.Row '---- Here is where the problem is ---------
Range("B" & Mode).Offset(0, 1).Select
(Was new passthrough function)
Dim finalNewSearchRange As Range
Dim finalNewFindRow As Range
Set finalNewSearchRange = Range("C" & Mode, Range("C" & Mode).End(xlUp))
Set finalNewFindRow = finalNewSearchRange.Find(Shift, LookIn:=xlValues, lookat:=xlWhole)
Shift = finalNewFindRow.Row '---- Here is where the problem is ---------
Range("C" & Mode).Offset(0, 1).Select
WeekCheck = ActiveCell.Value
ActiveCell.Offset(0, 1).Select
MonthCheck = ActiveCell.Value
Thank you everyone that tried to give me some tips. I was able to figure it out. XlUp was the culprit and I changed it to xlDown. It was returning an empty object for that reason because I was testing data in a column that had nothing above it. Then I listened to the rest of you and set object variables and was able to eliminate .copy and did what I originally set out to do which is increase the overall speed of the returned results from 13 seconds to just over 1 second. You can find my code below. I know I didn't call out a few variables as strings or integers but outside of that if you can provide me with any further constructive criticism I would definitely be grateful!
Sub DailyRouteInput_Button8_Click()
Dim nResult As Long
nResult = MsgBox( _
Prompt:="Did you save your prior DC/Mode updates to Master?", _
Buttons:=vbYesNo)
If nResult = vbNo Then
Exit Sub
End If
Dim VL As Workbook
Dim DailyRouteInput As Worksheet
Dim DailyRouteMaster As Worksheet
Dim masterRange As Range
Dim inputRange As Range
Dim DCInput As String
Dim ModeInput As String
Dim SearchRange As Range
Dim FindRow As Range
Dim finalNewSearchRange As Range
Dim finalNewFindRow As Range
Dim newSearchRange As Range
Dim newFindRow As Range
Set VL = ThisWorkbook
Set DailyRouteInput = VL.Sheets("Daily Route Input")
Set DailyRouteMaster = VL.Sheets("Daily Route Master Data")
Set masterRange = DailyRouteMaster.Range("A1:N2545")
Set inputRange = DailyRouteInput.Range("A1:BH57")
DCInput = inputRange.Cells(1, 21)
ModeInput = inputRange.Cells(1, 22)
ShiftInput = inputRange.Cells(5, 3)
DailyRouteMaster.Activate
Set SearchRange = masterRange.Range("A1", Range("A1").End(xlDown))
Set FindRow = SearchRange.Find(DCInput, LookIn:=xlValues, lookat:=xlWhole)
DC = FindRow.Row
Set newSearchRange = Range("B" & DC - 1, Range("B" & DC - 1).End(xlDown))
Set newFindRow = newSearchRange.Find(ModeInput, LookIn:=xlValues, lookat:=xlWhole)
Mode = newFindRow.Row
Set finalNewSearchRange = Range("C" & Mode - 1, Range("C" & Mode - 1).End(xlDown))
Set finalNewFindRow = finalNewSearchRange.Find(ShiftInput, LookIn:=xlValues, lookat:=xlWhole)
Shift = finalNewFindRow.Row
MonthCheck = DailyRouteMaster.Range("E" & DC)
If (MonthCheck = "January") Then
DailyRouteMaster.Range("F" & Shift, "N" & Shift + 3).Copy
DailyRouteInput.Activate
inputRange.Cells(5, 26).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 4, "N" & Shift + 7).Copy
DailyRouteInput.Activate
inputRange.Cells(5, 39).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 8, "N" & Shift + 12).Copy
DailyRouteInput.Activate
inputRange.Cells(5, 52).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Range("F" & Shift + 13, "N" & Shift + 16).Copy
DailyRouteInput.Activate
inputRange.Cells(14, 26).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 17, "N" & Shift + 20).Copy
DailyRouteInput.Activate
inputRange.Cells(14, 39).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 21, "N" & Shift + 25).Copy
DailyRouteInput.Activate
inputRange.Cells(14, 52).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Range("F" & Shift + 26, "N" & Shift + 29).Copy
DailyRouteInput.Activate
inputRange.Cells(23, 26).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 30, "N" & Shift + 33).Copy
DailyRouteInput.Activate
inputRange.Cells(23, 39).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 34, "N" & Shift + 38).Copy
DailyRouteInput.Activate
inputRange.Cells(23, 52).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Range("F" & Shift + 39, "N" & Shift + 42).Copy
DailyRouteInput.Activate
inputRange.Cells(32, 26).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 43, "N" & Shift + 46).Copy
DailyRouteInput.Activate
inputRange.Cells(32, 39).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteMaster.Activate
DailyRouteMaster.Range("F" & Shift + 47, "N" & Shift + 52).Copy
DailyRouteInput.Activate
inputRange.Cells(32, 52).PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
DailyRouteInput.Activate
Else
MsgBox ("Something is Wrong!")
End If
End Sub

Excel Theory: Consolidating Data from Multiple Tabs to one tab

I have 4 sheets of data with thousands of rows in each sheet. There is one column within each sheet that I would like to consolidate into a 5th sheet. In this column, I'd like to make sure that every name from the previous four sheets is included in one comprehensive list with no repeats.
See a simple example below, but imagine 20,000 rows on each sheet with complex names. Can anyone think of a method of doing this, that does not require tweaking everytime the inputs change? I've been trying to use PivotChart Wizard with no luck.
Sheet 1 Sheet 2 Sheet 3 Sheet 4 Ideal Sheet 5
Dog Cat Fish Giraffe Dog
Hamster Dog Lhama Cat Cat
Giraffe Elephant Dog Fish Fish
Giraffe
Elephant
Hamster
Lhama
Here is the code I came up with to solve the problem in case anyone is interested. "Zone & Fam" just specifies the column I'm interested in.
Sub GetUniqueZoneFam()
Application.ScreenUpdating = False
Dim Lastrow As Long
Worksheets("Calculation Indv").Range("A:A").ClearContents
Worksheets("fcst fg").Activate
Range("Fcst_Fg[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("fcst ps").Activate
Range("Fcst_PS[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A" & Lastrow + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("sales fg").Activate
Range("Sales_FG[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A" & Lastrow + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("sales ps").Activate
Range("Sales_PS[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A" & Lastrow + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Application.CutCopyMode = False
Range("A:A").RemoveDuplicates Columns:=1, Header:=xlNo
Range("A1").Select
Worksheets("Calculation Indv").Range("A1").Value = "Zone & Fam"
Worksheets("Calculation Indv").Range("A1").Font.Bold = True
Application.ScreenUpdating = True
MsgBox ("Done!")
End Sub
In vba this would look something like the following (Totally not tested, written outside of VBE, probably riddled with mistakes, definitely will need tweaking to fit your sheet names and columns where your data lives):
Dim wsName as String
Dim lastRow as Long
Dim writeRow as Long
'set the row on which we are going to start writing data to "Sheet 5"
writeRow = 1
'Loop though your sheets to copy from
For Each wsName In Array("Sheet 1", "Sheet 2", "Sheet 3", "Sheet 4")
'determine the last used row in the worksheet we are copying from
lastRow = Sheets(wsName).Range("A1").End(xlDown).Row
'grab the data
Sheets(wsName).Range("A1:A" & lastRow).Copy Destination:=Sheets("Sheet 5").Range("A" & writeRow)
'increment the writeRow
writeRow = writeRow + lastRow
Next wsName
'Now that all the data is copied, dedup it
Sheets("Sheet 5").Range("A1:A" & writeRow).RemoveDuplicates Columns:=Array(1), Header:=xlNo
Sub GetUniqueZoneFam()
Application.ScreenUpdating = False
Dim Lastrow As Long
Worksheets("Calculation Indv").Range("A:A").ClearContents
Worksheets("fcst fg").Activate
Range("Fcst_Fg[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("fcst ps").Activate
Range("Fcst_PS[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A" & Lastrow + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("sales fg").Activate
Range("Sales_FG[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A" & Lastrow + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("sales ps").Activate
Range("Sales_PS[Zone & Fam]").Copy
Worksheets("Calculation Indv").Activate
Range("A" & Lastrow + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Application.CutCopyMode = False
Range("A:A").RemoveDuplicates Columns:=1, Header:=xlNo
Range("A1").Select
Worksheets("Calculation Indv").Range("A1").Value = "Zone & Fam"
Worksheets("Calculation Indv").Range("A1").Font.Bold = True
Application.ScreenUpdating = True
MsgBox ("Done!")
End Sub

Excel Macro - Union of table

I am trying to run a macro that copy three tables from different worksheets and paste it together in a new worksheet.
The number of rows in the tables are not always the same. Therefore, I need a macro with a 'dynamic' "LastRow" parameter so that every time I update one single table the result of the macro is updated.
I tried to run this macro:^
Dim lastRow As Long
lastRow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row + 1
Sheets("Discussed Files").Select
Range("Table1[#Headers]").Select
Selection.Copy
Sheets("All data").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Discussed Files").Select
Range("Table1").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("All data").Select
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Files within 3 Days").Select
Range("Table3").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("All data").Select
Range("A" & lastRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Files 10.04.17").Select
Range("Table5").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("All data").Select
Range("A" & lastRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveSheet.ListObjects.Add(xlSrcRange, Range("$A$1:$Y$" & lastRow), , xlYes).Name = _
"Table14"
Range("Table14[#All]").Select
ActiveSheet.ListObjects("Table14").TableStyle = "TableStyleMedium2"
I cannot understand exactly what the macro is doing. It ends up woth a table having number of rows equal to first sheet but data inside the table are 'randomly' taken from the other sheets.
Moreover, the selection to make the result a table is not working properly.
As per comment above (have also removed unnecessary Selects)
Sub x()
Dim lastRow As Long
With Sheets("All data")
Sheets("Discussed Files").Range("Table1[#All]").Copy
.Range("A1").PasteSpecial Paste:=xlPasteValues
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
Sheets("Files within 3 Days").Range("Table3").Copy
.Range("A" & lastRow).PasteSpecial Paste:=xlPasteValues
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
Sheets("Files 10.04.17").Range("Table5").Copy
.Range("A" & lastRow).PasteSpecial Paste:=xlPasteValues
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
.ListObjects.Add(xlSrcRange, .Range("$A$1:$Y$" & lastRow), , xlYes).Name = "Table14"
.ListObjects("Table14").TableStyle = "TableStyleMedium2"
End With
End Sub
You don't update lastRow between steps, so you are basically pasting them one over another into same spot because the lastRow does not update after you paste one of your tables, it retains the same value from the beginning of your code in each:
Range("A" & lastRow).Select
Selection.PasteSpecial
Also, this code will return last row with data in it so if you are pasting into clean sheet, you are pasting all tables into the same spot:
lastRow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row + 1
EDIT:
Dim lastRow As Long
lastRow = Sheets("All data").Cells(Rows.Count, "A").End(xlUp).Row + 1
Sheets("Discussed Files").Range("Table1[#All]").Select
Selection.Copy
Sheets("All data").Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
lastRow = Sheets("All data").Cells(Rows.Count, "A").End(xlUp).Row + 1
Sheets("Files within 3 Days").Range("Table3").Select
Selection.Copy
Sheets("All data").Range("A" & lastRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
lastRow = Sheets("All data").Cells(Rows.Count, "A").End(xlUp).Row + 1
Sheets("Files 10.04.17").Range("Table5").Select
Selection.Copy
Sheets("All data").Range("A" & lastRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
lastRow = Sheets("All data").Cells(Rows.Count, "A").End(xlUp).Row + 1
Sheets("All data").ListObjects.Add(xlSrcRange, Range("$A$1:$Y$" & lastRow), , xlYes).Name = _
"Table14"
Range("Table14[#All]").Select
Sheets("All data").ListObjects("Table14").TableStyle = "TableStyleMedium2"

Resources