The difference between your code and the one submitted below is in the effort expanded on preparation. Preparation led to recognition of problems where lack of preparation led to confusion and, ultimately, this question. What I'm saying is that I don't think you would have needed to ask had you known to prepare adequately.
Private Sub Snippet()
' 218
Dim Ws(1 To 2) As Worksheet ' "Source 1" and "Source 2"
Dim i As Integer ' loop counter: Ws index
Dim Rs As Long ' loop counter: rows (source)
Dim WsOut As Worksheet ' "Output"
Dim Rt As Long ' target row
With ThisWorkbook
Set WsOut = .Worksheets("Output")
Set Ws(1) = .Worksheets("Source 1")
Set Ws(2) = .Worksheets("Source 2")
End With
With WsOut ' = last used row in WsOut
Rt = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Application.ScreenUpdating = False
For i = 1 To 2 ' loop through Ws(1 to 2)
With Ws(i) ' find last used row in Ws(1)
' start copying from row 2 because row 1 probably holds captions
' end with last used row in column A
For Rs = 2 To .Cells(.Rows.Count, "A").End(xlUp).Row
Rt = Rt + 1
.Range(.Cells(Rs, 1), .Cells(Rs, 3)).Copy
WsOut.Cells(Rt, 1).PasteSpecial xlPasteValues
Next Rs
End With
Next i
With Application
.CutCopyMode = False
.ScreenUpdating = True
End With
End Sub
The procedure starts off by naming all variables. The first result was to replace references like "Sheet(1)" even at this early stage because "Sheet(1)" is the first sheet from the left in the tab bar. If you add a sheet unwittingly your code won't work anymore or, rather, it will destroy your workbook. Your variables "k" and "j" were replaced with "Rs" and "Rt" marking them as row numbers (source and target).
Next, the code makes sure that the worksheets are properly defined as being within ThisWorkbook. They are also properly linked to their real life names, executing a decision made at the beginning. Actually, the variable declarations are modified many times while the rest of the code is developed. It isn't hewn in stone at the beginning but everything is built on it nevertheless.
Then the Target Row is set, and a system for it's maintenance designed. The system is to find the last used row first and then increment that number every time before a new row is written.
The decision is made to turn off ScreenUpdating
while the code runs. It will run faster that way but you must make provision to turn the feature back on at the end. That part of the code is written at this time.
And only now I arrive at the point which you had started out with. My code is remarkably like yours. Note that Copy/PasteSpecial allows you to choose what to paste, in this case "Values". You might use Copy
with Destination
instead which would also include formats. Or you might specify to copy formulas instead of values. To copy values you could simply use syntax like WsOut.Cells(Rt, 1).Value = .Cells(Rs, 1).Value` in a little loop. Because of the solid fundament on which this code is built it's very easy to modify these two lines using the established components.
The code ends on setting Application.CutCopyMode = False
and presenting the result of the action in the display by restoring ScreenUpdating
.