While there is already a valid answer, in terms of speed the less you interact with the sheets, the better. See below for an alternative, and comments in the code for more details:
Sub copyValues()
Dim wb As Workbook: Set wb = ActiveWorkbook
Dim wsSrc As Worksheet: Set wsSrc = wb.Worksheets("Sheet2")
With wsSrc
Dim lRowSrc As Long: lRowSrc = .Cells(.Rows.Count, 1).End(xlUp).Row 'get last row in source data
Dim lColSrc As Long: lColSrc = .Cells(1, .Columns.Count).End(xlToLeft).Column 'get last column in source data
Dim arrSrc As Variant: arrSrc = .Range(.Cells(1, 1), .Cells(lRowSrc, lColSrc)) 'allocate the data to an array
End With
Dim wsDst As Worksheet: Set wsDst = wb.Worksheets("Sheet1")
With wsDst
Dim lRowDst As Long: lRowDst = .Cells(.Rows.Count, 1).End(xlUp).Row 'get last row in destination data
Dim lColDst As Long: lColDst = 8 '.Cells(1, .Columns.Count).End(xlToLeft).Column 'get last column in destination data - if no other data, can use the dynamic version, otherwise use the set value i guess
Dim arrDst As Variant: arrDst = .Range(.Cells(1, 1), .Cells(lRowDst, lColSrc + lColDst)) '
End With
Dim Rd As Long, Rs As Long, C As Long
For Rd = LBound(arrDst) To UBound(arrDst) 'iterate through all rows in the destination data
For Rs = LBound(arrSrc) To UBound(arrSrc) 'iterate through all rows in the source data
If arrDst(Rd, 1) = arrSrc(Rs, 1) Then 'if there is a match
For C = LBound(arrDst, 2) + lColDst To UBound(arrDst, 2) 'iterate through all columns in the source
arrDst(Rd, C) = arrSrc(Rs, C - lColDst) 'allocate to the destination array
Next C
'alternatively, can write the values directly back to the sheet (comment the C loop above and values allocation below the loops)
' With wsDst
' .Range(.Cells(Rd, 9), .Cells(Rd, lColSrc + lColDst)).Value = _
' wsSrc.Range(wsSrc.Cells(Rs, 1), wsSrc.Cells(Rs, lColSrc)).Value
' End With
Exit For
End If
Next Rs
Next Rd
With wsDst
.Range(.Cells(1, 1), .Cells(lRowDst, lColSrc + lColDst)) = arrDst 'put the values back on the sheet
End With
End Sub