Read another file as input in vba - vba

I have this macro in a excel file:
Sub ore()
Sheets(1).Select
LR = Cells(Rows.Count, "A").End(xlUp).Row
drow = 2
For r = 2 To LR
ore = Cells(r, 4)
nome = Cells(r, 2)
totore = totore + ore
n = n + 1
If ore <> 8 Then
Rows(r).Copy Sheets("log").Cells(drow, 1)
drow = drow + 1
End If
If n = 5 Then
' Stop
If totore <> 40 Then
Sheets("log").Cells(drow - 1, 5) = totore
End If
n = 0: totore = 0
End If
Next
Sheets("log").Select
End Sub
That starts when i click a button. This file is called "example.xlsm". I want take this macro and write it in another file called "readfile.xlsm" and call as an input to the "example.xlsm" file. So I need to read the data of "example.xlsm" file in summary. How can I do this? I tried to write
Workbooks.Open "C:\Users\Me\Desktop\example.xlsm"
but it doesn't work. Thanks
EDIT:
Sub Sample()
Dim path As String
Dim openWb As Workbook
Dim openWs As Worksheet
path = "C:\Users\Me\Desktop\example.xlsm"
Set openWb = Workbooks.Open(path)
Set openWs = openWb.Sheets("Sheet1")
With openWs
'~~> Rest of your code here
Sheets(1).Select
LR = Cells(Rows.Count, "A").End(xlUp).Row
drow = 2
For r = 2 To LR
ore = Cells(r, 4)
nome = Cells(r, 2)
totore = totore + ore
n = n + 1
If ore <> 8 Then
Rows(r).Copy Sheets("log").Cells(drow, 1)
drow = drow + 1
End If
If n = 5 Then
' Stop
If totore <> 40 Then
Sheets("log").Cells(drow - 1, 5) = totore
End If
n = 0: totore = 0
End If
Next
Sheets("log").Select
End With
'openWb.Close (True)
End Sub
This doesn't work either.

You need to create your object and then work with them. See this example. This code goes in readfile.xlsm
Sub Sample()
Dim path As String
Dim openWb As Workbook
Dim openWs As Worksheet
path = "C:\Users\Me\Desktop\example.xlsm"
Set openWb = Workbooks.Open(path)
Set openWs = openWb.Sheets("Sheet1")
With openWs
'~~> Rest of your code here
End With
'openWb.Close (True)
End Sub
FOLLOWUP (From Comments)
When I meant rest of the code, I didn't mean that you copy paste the original code and not make any changes to it :p Also another important tip: Use Option Explicit I see lot of undeclared variables. I have declared all of them to Long Change as applicable
Try this (Untested)
Option Explicit
Sub Sample()
Dim path As String
Dim openWb As Workbook, thiswb As Workbook
Dim openWs As Worksheet, Logws As Worksheet
Dim LR As Long, dRow As Long, r As Long, n As Long
Dim ore As Long, nome As Long, totore As Long
path = "C:\Users\Me\Desktop\example.xlsm"
Set thiswb = ThisWorkbook
Set openWb = Workbooks.Open(path)
Set openWs = openWb.Sheets("Sheet1")
Set Logws = openWb.Sheets.Add
'~~> Create Log Sheet
On Error Resume Next
Application.DisplayAlerts = False
openWb.Sheets("log").Delete
Application.DisplayAlerts = True
On Error GoTo 0
Logws.Name = "log"
With openWs
'~~> Rest of your code here
LR = .Cells(.Rows.Count, "A").End(xlUp).Row
dRow = 2
For r = 2 To LR
ore = .Cells(r, 4).Value
'nome = .Cells(r, 2).Value '<~~ Why do we need this?
totore = totore + ore
n = n + 1
If ore <> 8 Then
.Rows(r).Copy Logws.Cells(dRow, 1)
dRow = dRow + 1
End If
If n = 5 Then
If totore <> 40 Then
Logws.Cells(dRow - 1, 5) = totore
End If
n = 0: totore = 0
End If
Next
End With
'openWb.Close (True)
End Sub

Related

Improvement on 3 Criteria Vlookup macro

I have a list with 3 variables in the sheet "Combined" in columns A; B; C.
The workbook contains 98 sheets, with those 3 variables still in A; B; C columns but in different combinations and with a fourth column which never repeats itself, as the sheets go on, which i need to bring in the "Combined" sheet, always adding another column for the next sheet I vlookup. : A B C + D(from the next sheet) + E(from the next sheet) and so on.
I have a UDF that Vlookups on 3 based on 3 criterias and a macro that cycles through the sheets and bring the values where i want them. The problem is, it's pretty slow, left it from yesterday and its on sheet 60. Any suggestions on improving it would greatly help, Thank you in advance!
Function ThreeVlookup(Table_Range As Range, Return_Col As Long, Col1_Fnd, Col2_Fnd, Col3_Fnd)
Dim rCheck As Range, bFound As Boolean, lLoop As Long
On Error Resume Next
Set rCheck = Table_Range.Columns(1).Cells(1, 1)
With WorksheetFunction
For lLoop = 1 To .CountIf(Table_Range.Columns(1), Col1_Fnd)
Set rCheck = Table_Range.Columns(1).Find(Col1_Fnd, rCheck, xlValues, xlWhole, xlNext, xlRows, False)
If UCase(rCheck(1, 2)) = UCase(Col2_Fnd) And UCase(rCheck(1, 3)) = UCase(Col3_Fnd) Then
bFound = True
Exit For
End If
Next lLoop
End With
If bFound = True Then
ThreeVlookup = rCheck(1, Return_Col)
Else
ThreeVlookup = ""
End If
End Function
Sub test()
Dim lookupVal1 As Range, lookupVal2 As Range, lookupVal3 As Range, myString As Variant, n&, u As Long
n = Sheets("Combined").[A:A].Cells.Find("*", , , , xlByRows, xlPrevious).Row
u = 4
For j = 2 To Worksheets.Count
For i = 1 To n
Set lookupVal1 = Sheets("Combined").Cells(i, 1)
Set lookupVal2 = Sheets("Combined").Cells(i, 2)
Set lookupVal3 = Sheets("Combined").Cells(i, 3)
myString = ThreeVlookup(Sheets(j).Range("A:D"), 4, lookupVal1, lookupVal2, lookupVal3)
Sheets("Combined").Cells(i, u) = myString
Next i
u = u + 1
Next j
End Sub
Use Arrays to speed it up, my friend! Load all your sheets (or just the current sheet in the loop) into an array in VBA's memory and do the .CountIf and .Find on arrayVar(row) instead of Table_Range.Columns(1).
You will be really surprised how much quicker it goes. Do it!
Here's a tutorial I like on arrays...
http://www.cpearson.com/excel/ArraysAndRanges.aspx
Here's a guy who speed-tested an application like yours...
https://fastexcel.wordpress.com/2011/10/26/match-vs-find-vs-variant-array-vba-performance-shootout/
The basics is like this:
Sub Play_With_Arrays()
Dim varArray() As Variant
Dim lngArray() As Long
ReDim varArray(1 To 1000)
ReDim lngArray(1 To 1000)
For A = 1 To 1000
lngArray(A) = A / 2
varArray(A) = A / 2 & " examples"
Next
searchterm = 345
For B = 1 To 1000
If lngArray(B) = searchterm Then
FoundRow = B
End If
Next
searchterm2 = "5 ex"
FoundStrRowCount = 0
For C = 1 To 1000
If InStr(1, varArray(C), searchterm2, vbBinaryCompare) Then
FoundStrRowCount = FoundStrRowCount + 1
End If
Next
MsgBox (FoundRow & " in long array and " & FoundStrRowCount & " in var array")
End Sub
Something like this should be much faster:
Public Function ThreeVLookup(ByVal arg_Col1LookupVal As Variant, _
ByVal arg_Col2LookupVal As Variant, _
ByVal arg_Col3LookupVal As Variant, _
ByVal arg_LookupTable As Range, _
ByVal arg_ReturnColumn As Long) _
As Variant
Dim rConstants As Range, rFormulas As Range
Dim rAdjustedTable As Range
Dim aTable As Variant
Dim i As Long
On Error Resume Next
Set rConstants = arg_LookupTable.SpecialCells(xlCellTypeConstants)
Set rFormulas = arg_LookupTable.SpecialCells(xlCellTypeFormulas)
On Error GoTo 0
Select Case (Not rConstants Is Nothing) + 2 * (Not rFormulas Is Nothing)
Case 0: ThreeVLookup = vbNullString
Exit Function
Case -1: Set rAdjustedTable = rConstants
Case -2: Set rAdjustedTable = rFormulas
Case -3: Set rAdjustedTable = Union(rConstants, rFormulas)
End Select
If WorksheetFunction.CountIfs(rAdjustedTable.Resize(, 1), arg_Col1LookupVal, rAdjustedTable.Resize(, 1).Offset(, 1), arg_Col2LookupVal, rAdjustedTable.Resize(, 1).Offset(, 2), arg_Col3LookupVal) = 0 Then
ThreeVLookup = vbNullString
Exit Function
End If
aTable = rAdjustedTable.Value
For i = LBound(aTable, 1) To UBound(aTable, 1)
If aTable(i, 1) = arg_Col1LookupVal And aTable(i, 2) = arg_Col2LookupVal And aTable(i, 3) = arg_Col3LookupVal Then
ThreeVLookup = aTable(i, arg_ReturnColumn)
Exit Function
End If
Next i
End Function
Sub tgr()
Dim wb As Workbook
Dim wsCombined As Worksheet
Dim ws As Worksheet
Dim aResults() As Variant
Dim aCombined As Variant
Dim i As Long, j As Long
Set wb = ActiveWorkbook
Set wsCombined = wb.Sheets("Combined")
aCombined = wsCombined.Range("A1").CurrentRegion.Value
ReDim aResults(1 To UBound(aCombined, 1) - LBound(aCombined, 1) + 1, 1 To wb.Sheets.Count - 1)
For i = LBound(aCombined, 1) To UBound(aCombined, 1)
j = 0
For Each ws In wb.Sheets
If ws.Name <> wsCombined.Name Then
j = j + 1
aResults(i, j) = ThreeVLookup(aCombined(i, 1), aCombined(i, 2), aCombined(i, 3), ws.Range("A:D"), 4)
End If
Next ws
Next i
wsCombined.Range("D1").Resize(UBound(aResults, 1), UBound(aResults, 2)).Value = aResults
End Sub

VBA Looping Through Multiple Worksheets

I am working on building code which can loop through a column (B5:B) on multiple worksheets to find matching values. If the Value on one worksheet's column (B5:B) is equal to a worksheet name, then the worksheet name is placed on the adjacent column (C5:C) to where the value was found. I am not a programmer, but I've been learning VBA to make this happen. So far I have tried unsuccessfully to use the For Next Loop (starting with the 3rd sheet), the For Each ws in Thisworkbook.sheets method. But I don't seem to be able to make it work. I've searched all over the internet for something similar, but no dice. Any suggestions would be greatly appreciated.
Sub MatchingPeople()
Dim c As Variant
Dim lastrow As Long
Dim i As Variant
Dim g As Long
Dim w As Long
i = Sheets("Anthony").Name
g = Sheets("Anthony").Cells(Rows.Count, "C").End(xlUp).Row
For w = 3 To Sheets.Count
lastrow = Sheets(w).Cells(Rows.Count, 2).End(xlUp).Row
Set NewRang = Sheets("Anthony").Cells(g + 1, 3)
On Error Resume Next
With Sheets(w).Range(Cells(5, 2), Cells(lasty, 2))
Set c = .Find(i, LookIn:=xlValues)
If Not c Is Nothing Then
firstaddress = c.Address
Do
NewRang.Value = Sheets(w).Name
Set c = .FindNext(c)
Loop While Not c Is Nothing And c.Address <> firstaddress
End If
End With
Next w
End Sub
Here are 2 versions, one using the Find method like in your code, the other using a For loop
Option Explicit
Public Sub MatchingPeopleFind()
Dim i As Long, lrColB As Long
Dim wsCount As Long, wsName As String
Dim found As Variant, foundAdr As String
wsCount = Worksheets.Count
If wsCount >= 3 Then
For i = 3 To wsCount
With Worksheets(i)
wsName = .Name
lrColB = .Cells(.Rows.Count, 2).End(xlUp).Row
With .Range(.Cells(5, 2), .Cells(lrColB, 2))
Set found = .Find(wsName, LookIn:=xlValues)
If Not found Is Nothing Then
foundAdr = found.Address
Do
found.Offset(0, 1).Value2 = wsName
Set found = .FindNext(found)
Loop While Not found Is Nothing And found.Address <> foundAdr
End If
End With
End With
Next
End If
End Sub
Public Sub MatchingPeopleForLoop()
Dim wsCount As Long, wsName As String, i As Long, j As Long
wsCount = Worksheets.Count
If wsCount >= 3 Then
For i = 3 To wsCount
With Worksheets(i)
wsName = .Name
For j = 5 To .Cells(.Rows.Count, 2).End(xlUp).Row
If .Cells(j, 2).Value2 = wsName Then .Cells(j, 3).Value2 = wsName
Next
End With
Next
End If
End Sub
Sub Bygone()
Dim x As Long
Dim y As Long
Dim z As Long
Dim w As Long
Dim a As Long
Dim b As Long
Dim c As Long
Dim m As Long
a = Sheets.Count
For m = 3 To a
x = Sheets(m).Cells(3, 3).Value
For b = 3 To a
w = Sheets(b).Cells(Rows.Count, 1).End(xlUp).row
For z = 5 To w
y = Sheets(b).Cells(z, 1)
Select Case x
Case y
c =Sheets(m).Cells(Rows.Count,3).End(xlUp).Offset(1, 0).row
Sheets(m).Cells(c, 3).Value = Sheets(b).Name
End Select
Next z
Next b
Next m
End Sub

Vba Excel - concatenate cell value and loop to all columns

I need help.
In a sheet I need concatenate with a loop the columns "a" + "b" + "c", next the columns "d" + "e" + "f", etc ... an go up to the last column.
My script is locked to the second loop...
The concatenated results are to appear in a second sheet.
this is my incorrect code:
Sub concatena()
Dim x As String
Dim Y As String
b = 1 'colonna selezionata
For c = 1 To 5 'colonne concatenate da riportare
For q = 1 To 10 'righe su cui effettuare l'operazione
For t = 1 To 3 'numero celle da concatenare
For Each cell In Worksheets(1).Cells(q, t)
If cell.Value = "" Then GoTo Line1
x = x & cell(1, b).Value & "" & ""
Next
Next t
Line1:
On Error GoTo Terminate
Worksheets(2).Cells(q, c).Value = Mid(x, 1, Len(x))
x = "" 'mantiene la formattazione
Next q
b = 3 + 1 ' sposta il concatena di 3 celle la selezione delle colonne
Next c
Terminate: 'error handler
End Sub
Thank you all for the help!
This one uses arrays to speed it up a little:
Sub concatena()
Dim inArr() As Variant
Dim oArr() As Variant
Dim i&, j&
Dim ws As Worksheet
Dim rng As Range
Set ws = Worksheets("Sheet9") ' change to your worksheet
With ws
Set rng = .Range(.Cells(1, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, .Cells(1, .Columns.Count).End(xlToLeft).Column))
inArr = rng.Value
ReDim oArr(1 To UBound(inArr, 1), 1 To UBound(inArr, 2) / 3)
For i = LBound(inArr, 1) To UBound(inArr, 1)
For j = LBound(inArr, 2) To UBound(inArr, 2) Step 3
oArr(i, Int((j - 1) / 3) + 1) = inArr(i, j) & inArr(i, j + 1) & inArr(i, j + 2)
Next j
Next i
rng.Clear
.Range("A1").Resize(UBound(oArr, 1), UBound(oArr, 2)).Value = oArr
End With
you can try this code:
Option Explicit
Sub concatena()
Dim iRow As Long, iCol As Long, iCol2 As Long
Dim arr As Variant
With Worksheets("numbers")
With .Cells(1, 1).CurrentRegion
ReDim arr(1 To .Rows.Count, 1 To .Columns.Count / 3 + .Columns.Count Mod 3)
For iRow = 1 To .Rows.Count
iCol2 = 1
For iCol = 1 To .Columns.Count Step 3
arr(iRow, iCol2) = Join(Application.Transpose(Application.Transpose(.Cells(iRow, iCol).Resize(, 3).Value)), "")
iCol2 = iCol2 + 1
Next iCol
Next iRow
Worksheets("results").Range("A1").Resize(.Rows.Count, UBound(arr, 2)).Value = arr
End With
End With
End Sub
This solution provides flexibility as it uses the variable bClls to hold the number of cells to be concatenated.
Assuming the source range is B2:M16 and you want to concatenate the value of every 3 cells for each row.
It avoids the use of redim.
Sub Range_Concatenate_Cells_TEST()
Dim rSel As Range
Dim bClls As Byte
Dim rCllOut As Range
bClls = 3 'change as required
Set rSel = ThisWorkbook.Sheets("Sht(0)").Range("B2:M16") 'change as required
Set rCllOut = ThisWorkbook.Sheets("Sht(1)").Cells(2, 2) 'change as required
Call Range_Concatenate_Cells(bClls, rSel, rCllOut)
End Sub
Sub Range_Concatenate_Cells(bClls As Byte, rSel As Range, rCllOut As Range)
Dim lRow As Long, iCol As Integer
Dim lRowOut As Long, iColOut As Integer
Dim vResult As Variant
With rSel
For lRow = 1 To .Rows.Count
lRowOut = 1 + lRowOut
iColOut = 0
For iCol = 1 To .Columns.Count Step 3
iColOut = 1 + iColOut
vResult = .Cells(lRow, iCol).Resize(1, 3).Value2
vResult = WorksheetFunction.Index(vResult, 0, 0)
vResult = Join(vResult, "")
rCllOut.Offset(-1 + lRowOut, -1 + iColOut).Value = vResult
Next: Next: End With
End Sub

how to change output location for each loop and run multiple loops

I have code here which loops through a list of files; opening them, extracting data and moving it into the main workbook. What i am looking to do get it so the data for abel is in columns c and d but then put varo in f and g etc. the problem that i see is that the placement code is inside the loop so for each i it will just write over the previous line instead of being in a different column all together!
Sub Source_Data()
Dim r
Dim findValues() As String
Dim Wrbk As Workbook
Dim This As Workbook
Dim sht As Worksheet
Dim i
Dim tmp
Dim counter
Dim c As Range
Dim firstAddress
Dim rng As Range
ReDim findValues(1 To 3)
findValues(1) = "abel"
findValues(2) = "varo"
findValues(3) = "Tiger"
counter = 0
r = Range("A1").End(xlDown).Row
Set rng = Range(Cells(1, 1), Cells(r, 1))
Set This = ThisWorkbook
For Each tmp In rng
Workbooks.Open tmp
Set Wrbk = ActiveWorkbook
Set sht = ActiveSheet
For i = 1 To 3
With sht.Range(Cells(1, 1), Range("A1").SpecialCells(xlCellTypeLastCell))
Set c = .Find(findValues(i), LookIn:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Offset(0, 2).Value
Do
This.Activate
tmp.Offset(0, 2).Value = tmp.Value
tmp.Offset(0, 3).Value = firstAddress
Set c = .FindNext(c)
counter = counter + 1
Loop While Not c Is Nothing And c.Value = firstAddress
End If
End With
Wrbk.Activate
Next
Wrbk.Close
Next tmp
End Sub
**EDIT:**I know it can be done by adding a multiplier of "i" to the offset value but this makes things bigger than they need to be if i wish to search for 50 keywords
Here is my answer, hope to help you, and as always, if you need an improvement, just tell me.
Sub Source_Data()
Dim r
Dim findValues() As String
Dim Wrbk As Workbook
Dim This As Workbook
Dim sht As Worksheet
Dim i
Dim tmp
Dim counter
Dim c As Range
Dim firstAddress
Dim rng As Range
Dim ColNum 'the columns number var
ReDim findValues(1 To 3)
findValues(1) = "abel"
findValues(2) = "varo"
findValues(3) = "Tiger"
counter = 0
r = Range("A1").End(xlDown).Row
Set rng = Range(Cells(1, 1), Cells(r, 1))
Set This = ThisWorkbook
For Each tmp In rng
Workbooks.Open tmp
Set Wrbk = ActiveWorkbook
Set sht = ActiveSheet
For i = 1 To 3
With sht.Range(Cells(1, 1), Range("A1").SpecialCells(xlCellTypeLastCell))
Set c = .Find(findValues(i), LookIn:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Offset(0, 2).Value
Do
This.Activate
Select Case i 'Test var i (the value)
Case "abel" 'in case the value (that is a string) is equal to...
ColNum = 1 'set the var, with the number of the column you want
Case "varo" 'in case the value...
ColNum = 2 'Set the column...
Case "Tiger"
ColNum = 3
Case Else 'In case that the i var not match with anyvalue take this column number
ColNum = 20 'the garbage!
End Select
tmp.Offset(0, ColNum).Value = tmp.Value 'Put the value in the selected columns
tmp.Offset(0, ColNum + 1).Value = firstAddress 'and put the value to the next column of the
'selected column
Set c = .FindNext(c)
counter = counter + 1
Loop While Not c Is Nothing And c.Value = firstAddress
End If
End With
Wrbk.Activate
Next
Wrbk.Close
Next tmp
End Sub
Note:
You need to set the ColNum var to the values that you need, put there the numbers of the columns you really need to store the value of i and the next line is to put the address of the i var
You can just change these two lines:
tmp.Offset(0, 2).Value = tmp.Value
tmp.Offset(0, 3).Value = firstAddress
To this
tmp.Offset(0, 2 + (i-1)*2).Value = tmp.Value
tmp.Offset(0, 3 + (i-1)*2).Value = firstAddress

Excel - Transpose Dynamic Columns into Rows in different sheet and copy necessary data items

I have data in the format below in Sheet 1:
I want to reorganize the data in format below in Sheet 2:
The length for "Identifier" will be dynamic.
I have tried building macros for transpose with loops and copy range but havent been successful. Any help is greatly appreciated.
This works. But you would have to rearrange the final results' columns to move the "Identifier" column to the start of the result set.
Sub test()
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Dim A, B, R, C As Long
Dim x() As Variant
Dim y() As Variant
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
With ws
Range("A1").Select
A = Range("A" & Rows.Count).End(xlUp).Row
x = Range("A1", "I" & A)
y = Range("J1", "Z" & A)
For R = 1 To UBound(y, 1)
B = R + 0
For C = 1 To UBound(y, 2)
If (y(R, C)) <> "" Then
Range("A" & B, "H" & B).Copy
Range("A" & A + 1).PasteSpecial
Application.CutCopyMode = False
Range("I" & A + 1).Value = y(R, C)
A = A + 1
Else
GoTo xxx:
End If
Next C
xxx:
Next R
Range("A1").Select
End With
End Sub
If I understand what you are after, here is a macro that does that. When it starts it asks you to select the top left corner of the source data (it defaults to the active cell) and then it asks for the top left corner of the destination - while the selection box is up you can select the cell with the mouse if you don't want to type it in. Put this code in a Module:
Sub TransposeByLastColumn()
'get the top left corner of the source
Dim Source As Range
On Error Resume Next
Set Source = Application.InputBox("Select Source:", "Source", "=" & ActiveCell.Address, Type:=8)
On Error GoTo 0
If Source Is Nothing Then Set Source = ActiveCell
'get the top left corner of the destination
Dim Destination As Range
On Error Resume Next
Set Destination = Application.InputBox("Select Destination:", "Destination", Type:=8)
On Error GoTo 0
If Destination Is Nothing Then Exit Sub
'calculate the number of headers
Dim HeaderColumns As Long
HeaderColumns = 0
While Source.Offset(0, HeaderColumns).Value <> vbNullString
HeaderColumns = HeaderColumns + 1
Wend
'copy the headers
Dim HeaderIndex As Long
Destination.Offset(0, 0).Value = Source.Offset(0, HeaderColumns - 1).Value
For HeaderIndex = 1 To HeaderColumns - 1
Destination.Offset(0, HeaderIndex).Value = Source.Offset(0, HeaderIndex - 1).Value
Next
'copy the data
Dim SourceRowIndex As Long
Dim DestinationRowIndex As Long
Dim DataColumnIndex As Long
Dim IdentifierColumnIndex As Long
SourceRowIndex = 1
DestinationRowIndex = 1
While Source.Offset(SourceRowIndex, HeaderColumns - 1).Value <> vbNullString
IdentifierColumnIndex = 1
While Source.Offset(SourceRowIndex, HeaderColumns - 1 + IdentifierColumnIndex - 1).Value <> vbNullString
Destination.Offset(DestinationRowIndex, 0).Value = Source.Offset(SourceRowIndex, HeaderColumns - 1 + IdentifierColumnIndex - 1).Value
For DataColumnIndex = 1 To HeaderColumns - 1
Destination.Offset(DestinationRowIndex, DataColumnIndex).Value = Source.Offset(SourceRowIndex, DataColumnIndex - 1).Value
Next
IdentifierColumnIndex = IdentifierColumnIndex + 1
DestinationRowIndex = DestinationRowIndex + 1
Wend
SourceRowIndex = SourceRowIndex + 1
Wend
'show the result
Destination.Worksheet.Activate: Destination.Select
End Sub