Consolidating two sheets - vba

I do have two different sheets (Tabelle2 & Tabelle3) and I want to consolidate them in a third one (Tabelle1) on basis of the Register No.
To copy Tabelle2 into the correct columns in Tabelle1 I'm using VLookup which is working smooth.
Dim lastrow As Long
lastrow = Tabelle2.Range("A" & Rows.Count).End(xlUp).Row
Set myrange = Tabelle2.UsedRange
For i = 2 To lastrow
Tabelle1.Cells(i, 1) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 1, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(i, 2) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 2, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(i, 6) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 3, False)
Next i
In a 2. Step I want my code to check the "Register No." in Tabelle1 and copy only those rows from Tabelle3 to Tabelle1. Note: Tabelle3 is containing many more "Register No." which data I don't need
Does anyone know which function to use or how to solve this challange? :)

Try this
Dim lastrow As Long
lastrow = Tabelle3.Range("A" & Rows.Count).End(xlUp).Row
Set myrange = Tabelle3.UsedRange
For i = 2 To lastrow
Tabelle1.Cells(i, 3) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange, 2, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(i, 4) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange, 3, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(i, 5) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange, 4, False)
Next i

Let's make it really simple - put the three tables on the same worksheet like this:
The idea would be to get something like this, after running the code below:
Probably the simplest way to achieve it with some bad practices as hard-coding is like this:
Public Sub TestMe()
Dim cnt As Long
Dim combinedIndex As Range
Dim currentCell As Range
With Worksheets(1)
Set combinedIndex = .Range("A7:A12")
'Fill table with names
For cnt = 2 To 5
Set currentCell = Nothing
Set currentCell = combinedIndex.Find(Cells(cnt, 1))
If Not currentCell Is Nothing Then
currentCell.Offset(0, 1) = .Cells(cnt, 2)
End If
Next cnt
'Fill table with Shoe Sizes
For cnt = 2 To 5
Set currentCell = Nothing
Set currentCell = combinedIndex.Find(Cells(cnt, 4))
If Not currentCell Is Nothing Then
currentCell.Offset(0, 2) = .Cells(cnt, 5)
End If
Next cnt
End With
End Sub
This is what the code does:
Defines the combinedIndex range. In a more general case it can be Worksheets(1).Range("A:A")
then loops through the table with the names. It is hardcoded from 2 to 5, but it can be loosened up a bit. Once a RegisterN is found, the second value is written to the offset of the found value
the same is for the Shoe Sizes table

Related

Excel reporting - function hlookup doesn't work in nested for loop

I've got a problem. I' m trying to match specific values by item_id using hlookup function. But this function does not return specified value.
Here is the code of my macro :
Sub create_report()
Dim itemWs As Worksheet, offerWs As Worksheet, testWs As Worksheet
Dim itemLastRow As Long, offerLastRow As Long
Dim offerLastCol As Long, itemLastCol As Long
Dim dataRng As Range
Set itemWs = ThisWorkbook.Worksheets("nn_rfx_compare_per_lot")
Set offerWs = ThisWorkbook.Worksheets("Offers")
Set testWs = ThisWorkbook.Worksheets("Testowy")
itemLastRow = itemWs.Range("A" & Rows.Count).End(xlUp).Row
offerLastRow = offerWs.Range("A" & Rows.Count).End(xlUp).Row
offerLastCol = offerWs.Cells(1, Columns.Count).End(xlToLeft).Column
itemLastCol = itemWs.Cells(1, Columns.Count).End(xlToLeft).Column
Set dataRng = testWs.Range("I3:AF" & 4)
'For x = 2 To 7
'On Error Resume Next
'itemWs.Range("I" & x).Value = Application.WorksheetFunction.VLookup(itemWs.Range("C" & x).Value & itemWs.Range("B" & x).Value, dataRng, 3, 0)
'Next x
Sheets("Testowy").Range(Sheets("Testowy").Cells(offerLastCol - 1, 1), Sheets("Testowy").Cells(itemLastRow + 4, itemLastCol)) = _
Sheets("nn_rfx_compare_per_lot").Range(Sheets("nn_rfx_compare_per_lot").Cells(1, 1), Sheets("nn_rfx_compare_per_lot").Cells(itemLastRow, itemLastCol)).Value
Sheets("Testowy").Range(Sheets("Testowy").Cells(1, itemLastCol), Sheets("Testowy").Cells(offerLastCol - 2, offerLastRow - 2)) = _
WorksheetFunction.Transpose(Sheets("Offers").Range(Sheets("Offers").Cells(1, 2), Sheets("Offers").Cells(offerLastRow, offerLastCol - 1)))
Dim lastTestCol As Long
lastTestCol = testWs.Cells(1, Columns.Count).End(xlToLeft).Column
Dim ColumnLetter As String
For Row = 6 To 11
For Col = 9 To lastTestCol
On Error Resume Next
testWs.Cells(Row, Col).Value = Application.WorksheetFunction.Index(testWs.Range( _
"I4:AF4"), WorksheetFunction.Match(testWs.Cells(Row, 3).Value, testWs.Cells(3, Col), 0))
'Match(testWs.Cells(Row, 3), dataRng, 1)
'HLookup(testWs.Cells(Row, 3), dataRng, 2, 0)
Next Col
Next Row
End Sub
In this link there is shown a report which I'd like to organise
enter image description here
The task and conditions are not completely clear (what to do with duplicates, whether they can occur, whether item_id is unique and so on).
If, for example, you need to select sup_id corresponding to item_id, it can be done by the following code:
Set item_id_rng = testWS.Range("I3:AF3")
For Row = 6 To 11
' search `item_id` in Range("I3:AF3")
find_col = Application.Match(testWS.Cells(Row, 3).Value, item_id_rng, 0)
If IsNumeric(find_col) Then ' if found, get correspondent value from correspondent row
'output to 9 column (empty area), for example
testWS.Cells(Row, 9).Value = item_id_rng(1).Offset(-1, find_col - 1)
End If
Next Row
As for the task as a whole, it would be good if you formulated the conditions of the task and placed an image of the result

how to match 2 criteria in macro

I currently have the following codes that look up the column for Columbus. But how do I specify that I only want to look up the column for Columbus in Ohio by also referring to row 4 (State)?
Amount = WorksheetFunction.Match("Columbus", Rows("5:5"), 0)
Try Looping thru all the records -
Dim Amount As Variant
Dim lngRow as long
lngRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lngRow 'Considering row 1 has headers
If ActiveSheet.Cells(i, 5) = "Columbus" And ActiveSheet.Cells(i, 4) = "Ohio" Then
Amount = i
Exit For
End If
Next i
Thanks
Use Variant Arrays and cycle through that it will be quicker:
With Worksheets("Sheet1") 'Change to your sheet
Dim rngArr() As Variant
rngArr = .Range(.Cells(4, 1), .Cells(5, .Columns.Count).End(xlToLeft)).Value
Dim i As Long
For i = 1 To UBound(rngArr, 2)
If rngArr(1, i) = "Ohio" And rngArr(2, i) = "Columbus" Then Exit For
Next i
If i <= UBound(rngArr, 2) Then
Dim Amount As Long
Amount = i
Else
MsgBox "Not Found"
End If
End With

Consolidation of two Worksheets Execution Error

I am using the following code to consolidate two Worksheets (Sheet 5 and Sheet 3). More precisely, I am adding the data from Sheet 5 to Sheet 3 what is working smooth as long as have opened Sheet 3 when processing the code. However, when I switch to another sheet and run the code, the code doesn't work properly anymore.
When I run the code for the first time it works smooth
When I run the code repeatedly nothing should happen, because my macro just inserts data from Sheet 5 in Sheet 3that isn't already in Sheet 3 and since this data has already been inserted in the first run nothing should happen. This is the case, when I stay on Sheet 3. However, if I switch to another sheet and run the code a second, third, fourth time, then the macro is partly executed everytime.
Let me explain this a lil bit further:
For my tests I am using three rows with data. When I execute the button a first time, all three rows in Sheet 5 are added to Sheet 3. When I press the button a second, third, fourth time three rows are added to Sheet 3
First added row: Is empty
Second & Third added row: contain the data of the second and third row in Sheet 3
Does anyone have an idea what is going wrong here?
Sub Consolidation()
Dim lastrow As Long
Dim NFR As Long
lastrow = Tabelle5.Range("A" & Rows.Count).End(xlUp).Row
NFR = Tabelle3.Range("A" & Rows.Count).End(xlUp).Offset(-3).Row
Set myrange = Tabelle5.UsedRange
For i = 4 To lastrow
On Error Resume Next
If Tabelle3.Cells(5 + i, 1) <> "" And Not IsError(Application.Match(Tabelle3.Cells(5 + i, 1), Tabelle5.Range("A:A"), False)) Then
Tabelle3.Cells(5 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle3.Cells(5 + i, 1), myrange, 2, False)
End If
If IsError(Application.Match(Tabelle5.Cells(i, 1), Tabelle3.Range("A9:A" & Range("A1048576").End(xlUp).Offset(8).Row), False)) Then
Tabelle3.Cells(NFR + i, 1) = Application.WorksheetFunction.VLookup(Tabelle5.Cells(i, 1), myrange, 1, False)
Tabelle3.Cells(NFR + i, 2) = Application.WorksheetFunction.VLookup(Tabelle5.Cells(i, 1), myrange, 2, False)
End If
Next i
Set Rng = Tabelle3.Range("A9:A" & Range("A1048576").End(xlUp).Offset(8).Row)
On Error Resume Next
Rng.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
Something like this (untested):
Sub Consolidation()
Dim lastrow As Long
Dim NFR As Long, r, v
lastrow = Tabelle5.Range("A" & Rows.Count).End(xlUp).Row
NFR = Tabelle3.Range("A" & Rows.Count).End(xlUp).Offset(-3).Row
Set myrange = Tabelle5.UsedRange
For i = 4 To lastrow
v = Tabelle3.Cells(5 + i, 1)
If v <> "" And Not IsError(Application.Match(v, Tabelle5.Range("A:A"), False)) Then
r = Application.VLookup(v, myrange, 2, False)
Tabelle3.Cells(5 + i, 2) = IIf(IsError(r), "No match", r)
End If
v = Tabelle5.Cells(i, 1)
If IsError(Application.Match(v, Tabelle3.Range("A9:A" & _
Tabelle3.Range("A1048576").End(xlUp).Offset(8).Row), False)) Then
r = Application.VLookup(v, myrange, 1, False)
Tabelle3.Cells(NFR + i, 1) = IIf(IsError(r), "No match", r)
r = Application.VLookup(v, myrange, 2, False)
Tabelle3.Cells(NFR + i, 2) = IIf(IsError(r), "No match", r)
End If
Next i
Set Rng = Tabelle3.Range("A9:A" & Range("A1048576").End(xlUp).Offset(8).Row)
On Error Resume Next
Rng.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub

Consolidating two Worksheets

I want to consolidate two worksheets on the basis of a "Register No." in a third worksheet.
Workbook:
Tabelle1: Consolidated Worksheet //
Tabelle2: Input Data1 //
Tabelle3: Input Data2
Notes:
At first the "Register No." can only be found in Tabelle2 & Tabelle3 in column A.
Because Tabelle1 has also a different column sequence than Tabelle2 & Tabelle3 I am using vLookup to paste the data to the right columns in Tabelle1.
Idea:
1. Step
Pasting Tabelle2 Data, including "Register No.", to the right columns in Tabelle1 via vLookup. Note: This means "Register No." to Tabelle 1 column A.
2. Step
Pasting Tabelle3 Data to right rows and columns in Tabelle1 via vLookup.
As Tabelle3 contains more "Register No." than Tabelle2, I want my code to check the "Register No." in Tabelle1 column A and copy the corresponding data from Tabelle3.
ERROR:
The 2. Step is not working.
Runtime-Error '1004'
For example:
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 2, False)
Next i
Does anyone know what is wrong with my code? Thanks a lot :)
My Code:
Sub ConsolidateData()
Dim lastrow As Long
lastrow = Tabelle2.Range("A" & Rows.Count).End(xlUp).Row
Set myrange = Tabelle2.UsedRange
For i = 2 To lastrow
Tabelle1.Cells(7 + i, 1) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 1, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(7 + i, 3) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 2, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(7 + i, 6) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 3, False)
Next i
Dim lastrow2 As Long
lastrow2 = Tabelle3.Range("A" & Rows.Count).End(xlUp).Row
Set myrange2 = Tabelle3.UsedRange
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 2, False)
Next i
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 4) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 3, False)
Next i
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 5) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 4, False)
Next i
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 7) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 5, False)
Next i
End Sub
I think the problem is the way you are referencing your worksheets. You are using the Worksheet.CodeName vs the Worksheet.Name of the worksheet.
Look at my example below and you will see that the Worksheet.CodeName and Worksheet.Name do not match.
Worksheet.CodeName is the 1st part of the name and Worksheet.Name is what's shown in parentheses. Therefore the Worksheet.CodeName for the second worksheet is Sheet5, whereas the Worksheet.Name is Sheet6.
This is because I deleted a worksheet and excel, behind the scenes, renamed the Worksheet.CodeName reference.
To use what you see when looking at the tabs in the workbook you need to reference it by Worksheet.Name, not Worksheet.CodeName.
Sub testPickingWorksheets()
' This code fails
a = Sheet6.Range("A1").Value
MsgBox (a)
' This code works
a = Worksheets("Sheet6").Range("A1").Value
MsgBox (a)
End Sub
As you can see from the code above, you need to use the Worksheets() Ojbect with the Worksheet.Name in "quotes" instead of directly referencing the Worksheet.CodeName.

Merging multiple rows based on first column

I have an excel with two columns (B & C) - Business case and solution, there will be multiple business cases which might have same solution, i want to merge it based on solution. Something like below -
BC1 Sol1
BC2 Sol2
BC3 Sol2
BC4 Sol3
BC5 Sol4
BC6 Sol4
BC7 Sol4
output should be -
BC1 Sol1
BC2, BC3 Sol2
BC4 Sol3
BC5, BC6, BC7 Sol4
i would like to do this in VBA and tried something like below -
LASTROW = Range("C" & Rows.Count).End(xlUp).Row 'get last row
For I = 0 To LASTROW Step 1
For J = I + 1 To LASTROW Step 1
If Cells(I, "C") = Cells(J, "C") Then
Cells(I, "B") = Cells(I, "B") & "," & Cells(J, "B")
Rows(J).Delete
End If
Next
Next
the above works, but is very slow when running on 1000 rows, i went through other questions similar to this but not good in VBA to mod that for above one. Can someone please help ?
As you have commented, using a variant array rather than looping the cells directly will speed this up enormously
To apply that here you could:
Determine the source data range, and copy that into an array
Create another array to contain the new data
Loop the source array, testing for the required patterns, and populate the destination array
Copy the new data back to the sheet, overwriting the old data
Sub Demo()
Dim ws As Worksheet
Dim rng As Range
Dim datSrc As Variant
Dim datDst As Variant
Dim i As Long
Dim j As Long
Dim rwOut As Long
Dim str As String
Set ws = ActiveSheet
With ws
Set rng = Range(.Cells(1, 2), .Cells(.Rows.Count, 3).End(xlUp))
datSrc = rng.Value
ReDim datDst(1 To UBound(datSrc, 1), 1 To UBound(datSrc, 2))
rwOut = 1
For i = 1 To UBound(datSrc, 1)
str = datSrc(i, 1)
If datSrc(i, 2) <> vbNullString Then
For j = i + 1 To UBound(datSrc, 1)
If datSrc(i, 2) = datSrc(j, 2) Then
str = str & "," & datSrc(j, 1)
datSrc(j, 2) = vbNullString
End If
Next
datDst(rwOut, 1) = str
datDst(rwOut, 2) = datSrc(i, 2)
rwOut = rwOut + 1
End If
Next
rng = datDst
End With
End Sub