Start by caching the end row numbers so that you're not calculating them on every iteration of the loop:
Dim wsRow As Long, ws2Row As Long
wsRow = ws.Cells(ws.Rows.Count, 14).End(xlUp).Row
ws2Row = ws2.Cells(ws2.Rows.Count, 98).End(xlUp).Row
For i = 3 To wsRow
...
For j = 3 To ws2Row
...
But remember, the performance of your code will depend on how many rows are in your source and destination sheets. The total number of iterations is going to be the product of the two - if
ws
has 42 rows and
ws2
has 1000 rows, your inner loop will execute
42000 times.
If there will only be one matching row in
ws2
, then you should exit from the inner loop as soon as you find a match:
If ws2.Cells(j, 98).Value = a _
And ws2.Cells(j, 103).Value = b _
And ws2.Cells(j, 114).Value = c _
Then
ws2.Cells(j, 120).Value = ws.Cells(j, 18).Value
Exit For
End If