Reputation: 113
I'm using a VLookup function to screen Tabelle5.Range("A:A")
based on identification numbers in Tabelle3.Cells(7 + i, 1)
. If the identifaction number is found in Tabelle5.Range("A:A")
then various cells from this row should be copied to the right cells in (row) Tabelle3.Cells(7 + i, 1)
.
This is working fine with the following code.
Sub VLookup
Dim lastrow As Long
Dim NFR As Long
lastrow = Tabelle5.Range("A" & Rows.Count).End(xlUp).Row
NFR = Tabelle3.Range("B" & Rows.Count).End(xlUp).Offset(-1).Row
Set myrange = Tabelle5.UsedRange
For i = 2 To lastrow
On Error Resume Next
If Tabelle3.Cells(7 + i, 1) <> "" And Not IsError(Application.Match(Tabelle3.Cells(7 + i, 1), Tabelle5.Range("A:A"), False)) Then
Tabelle3.Cells(7 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 2, False)
Tabelle3.Cells(7 + i, 3) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 3, False)
Tabelle3.Cells(7 + i, 4) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 4, False)
End If
Next i
End Sub
My challenge here is that there might be cells in Tabelle3
which do already contain data. This data will be overwritten with the 'new' data from Tabelle5
. However, it can occur that the 'new' data from Tabelle5
is an empty cell. This would mean, that I would lose data, because a filled cell would be overwritten by an empty cell.
EDIT
Does someone know how to apply Vlookup, only if the identification number from Tabelle3.Cells(7 + i, 1)
is also found in Tabelle5.Range("A:A")
(that's what I'm using Vlookup for) and in a second step only takes not-empty cells from myrange Column 2,3, and 4
.
Example
The identification number from Tabelle3.Cells(12, 1)
is found in Tabelle5.Cells(29,1)
. Row 29 in Tabelle5
contains following values:
In a next step I want my code only copying the 'New Data' from B29 and D29 to the definied cells in Tabelle3
but skipping C29 because it is a empty cell and this might overwrite a already filled cell in Tabelle3
.
Upvotes: 0
Views: 190
Reputation: 2569
You could nest your if statement under another if statement, as Banana kindly suggested:
If Tabelle5.Cells(7 + i, 1) <> "" Then
If Tabelle3.Cells(7 + i, 1) <> "" And Not IsError(Application.Match(Tabelle3.Cells(7 + i, 1), Tabelle5.Range("A:A"), False)) Then
Tabelle3.Cells(7 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 2, False)
Tabelle3.Cells(7 + i, 3) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 3, False)
Tabelle3.Cells(7 + i, 4) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 4, False)
End If
End If
UPDATED:
In this case you can you use if statements to apply each of your VLookups as this:
If Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 2, False) <> "" Then Tabelle3.Cells(7 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 2, False)
or
res1 = Application.WorksheetFunction.VLookup(Tabelle3.Cells(7 + i, 1), myrange, 2, False)
If res1 <> "" Then Tabelle3.Cells(7 + i, 2) = res1
There are surely better ways to this whole logic, but this should help get your code working at least.
Upvotes: 2
Reputation: 19722
This method uses FIND
to get a reference to the correct cell in column A. It then uses OFFSET
to check the values in the various columns before copying the values across.
This assumes the identification numbers are unique on both sheets.
Public Sub ReplaceFigures()
Dim rT5_LastCell As Range
Dim rT3_LastCell As Range
Dim rCell As Range
Dim rFound As Range
'References to last cell in column A.
Set rT5_LastCell = Tabelle5.Range("A" & Tabelle5.Rows.Count).End(xlUp)
Set rT3_LastCell = Tabelle3.Range("A" & Tabelle3.Rows.Count).End(xlUp)
'rcell will be a direct reference to the column A cell in Tabelle3
'rFound will be a direct reference to the column A cell in Tabelle5 (or nothing).
With Tabelle5.Range("A1", rT5_LastCell)
For Each rCell In Tabelle3.Range("A1", rT3_LastCell)
Set rFound = .Find(What:=rCell, _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchDirection:=xlNext)
If Not rFound Is Nothing Then 'A match has been found.
'If the Tabelle3 value is empty then copy the Tabelle5 value across.
If rCell.Offset(, 1) = "" Then rCell.Offset(, 1) = rFound.Offset(, 1) 'column B.
If rCell.Offset(, 2) = "" Then rCell.Offset(, 2) = rFound.Offset(, 2) 'column C.
If rCell.Offset(, 3) = "" Then rCell.Offset(, 3) = rFound.Offset(, 3) 'column D.
End If
Next rCell
End With
End Sub
To speed test the macro add the code below and then insert StartTimer
at the top of the ReplaceFigures()
code and StopTimer
at the bottom.
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public CodeTimer As Long
'^^^^^ Top of module ^^^^^^
Public Function StartTimer()
CodeTimer = GetTickCount
End Function
Public Function StopTimer()
Dim FinalTime As Long
FinalTime = GetTickCount - CodeTimer
MsgBox Format(Now(), "ddd dd-mmm-yy hh:mm:ss") & vbCr & vbCr & _
Format((FinalTime / 1000) / 86400, "hh:mm:ss") & vbCr & _
FinalTime & " ms.", vbOKOnly + vbInformation, _
"Code Timer"
CodeTimer = 0
End Function
Upvotes: 1