Copy Range
To learn why the 1st code is not recommended, read through the following 'classic': How to avoid using Select in Excel VBA.
The 2nd code shows how to copy a range in three steps: define CopyRange, define PasteCell(PasteRange) and finally Copy/Paste.
To better understand the 2nd code, check out Range.Copy and Range.PasteSpecial from Microsoft, this tutorial or these videos.
To make the codes work in your case, replace Sheet1 with Sheet9, Sheet2 with Sheet14 and B10 with B100.
The Code
Option Explicit
Sub CopyPasteSelectActivate()
' A quick fix, not recommended. It's a poorly improved version of what
' the macro recorder what produce.
' Rather use one of the 3 ways below.
Dim LastRow As Long ' In this case 'As String' works, too.
Sheet1.Activate
Sheet1.Range("B2:B10").Select
Sheet1.Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
LastRow = Sheet2.Cells(Rows.Count, "B").End(xlUp).Row + 1
Sheet2.Activate
Sheet2.Range("B" & LastRow).Activate
Sheet2.Paste
End Sub
Sub CopyPaste3Ways()
' Define CopyRange.
Dim CopyRange As Range
' Either...
'Set CopyRange = Sheet1.Range("B2", Sheet1.Range("B2:B10").End(xlDown))
' ...or (I prefer the following 'xlUp' approach):
Dim LastRow As Long
LastRow = Sheet1.Cells(Sheet1.Rows.Count, "B").End(xlUp).Row
Set CopyRange = Sheet1.Range("B2:B" & LastRow)
Debug.Print "CopyRange:", Sheet1.Name, CopyRange.Address
' Define PasteCell.
Dim FirstEmptyRow As Long
FirstEmptyRow = Sheet2.Cells(Sheet2.Rows.Count, "B").End(xlUp).Row + 1
Dim PasteCell As Range
Set PasteCell = Sheet2.Range("B" & FirstEmptyRow)
Debug.Print "PasteCell:", Sheet2.Name, PasteCell.Address
' The CopyPaste
' 1st Version
' This version is the most efficient of these 3 versions, but it can
' only be used for copying values (not formulas, formats... etc.).
' Either...
'PasteCell.Resize(CopyRange.Rows.Count, CopyRange.Columns.Count).Value _
= CopyRange.Value
' ...or:
' To better understand it, you can define a 'PasteRange'.
Dim PasteRange As Range
Set PasteRange = PasteCell.Resize(CopyRange.Rows.Count, _
CopyRange.Columns.Count)
PasteRange.Value = CopyRange.Value
Debug.Print "PasteRange:", Sheet2.Name, PasteRange.Address
' ' 2nd Version
' ' This version will copy 'everything', including formulas, formats etc.
' ' The following line...
' CopyRange.Copy PasteCell
' ' is just short for:
' CopyRange.Copy Destination:=PasteCell
' ' 3rd Version
' ' This version will do the same as the previous, but as a downside,
' ' it will change the selection on the 'PasteSheet' to 'PasteRange' and
' ' will set the 'CutCopyMode' to 'xlCopy'. But as an upside, you can
' ' choose what you want to copy by 'adding arguments' to 'PasteSpecial'.
' ' Put the cursor right behind 'PasteSpecial' and press 'SPACE' to
' ' see the various arguments and their parameters.
' CopyRange.Copy
' PasteCell.PasteSpecial
' Application.CutCopyMode = False
End Sub