VBA - Vlookup Multiple Columns and Fill to End of Rangeexcel replace function in access vbaVBA Lookup with Dynamic RangeShow only selected table column after filter to new worksheetsVBA Sum a Variable Range With Non-Empty Cells and Looping through arrayMultiple Vlookups using VBA in one subTake the date in one worksheet and find the same date in another worksheet column and return the cell reference for that date to use in a loopInsert line after last row of specific textInserting Range into Array in VBA for iterationVLookup between two workbooks combined with ISNA function. Run-time Error '1004': Application defined or object defined errorCombined data from multiple sheets into one sheet
Reply ‘no position’ while the job posting is still there (‘HiWi’ position in Germany)
Can the electrostatic force be infinite in magnitude?
Golf game boilerplate
Is there an Impartial Brexit Deal comparison site?
Why does this part of the Space Shuttle launch pad seem to be floating in air?
For airliners, what prevents wing strikes on landing in bad weather?
Was the picture area of a CRT a parallelogram (instead of a true rectangle)?
Hostile work environment after whistle-blowing on coworker and our boss. What do I do?
My boss asked me to take a one-day class, then signs it up as a day off
Stereotypical names
Can a Gentile theist be saved?
The most efficient algorithm to find all possible integer pairs which sum to a given integer
Invariance of results when scaling explanatory variables in logistic regression, is there a proof?
Who must act to prevent Brexit on March 29th?
Java - What do constructor type arguments mean when placed *before* the type?
Can I create an upright 7-foot × 5-foot wall with the Minor Illusion spell?
What is the opposite of 'gravitas'?
Proof of Lemma: Every integer can be written as a product of primes
Simulating a probability of 1 of 2^N with less than N random bits
Adding empty element to declared container without declaring type of element
A workplace installs custom certificates on personal devices, can this be used to decrypt HTTPS traffic?
I2C signal and power over long range (10meter cable)
Partial sums of primes
Does "Dominei" mean something?
VBA - Vlookup Multiple Columns and Fill to End of Range
excel replace function in access vbaVBA Lookup with Dynamic RangeShow only selected table column after filter to new worksheetsVBA Sum a Variable Range With Non-Empty Cells and Looping through arrayMultiple Vlookups using VBA in one subTake the date in one worksheet and find the same date in another worksheet column and return the cell reference for that date to use in a loopInsert line after last row of specific textInserting Range into Array in VBA for iterationVLookup between two workbooks combined with ISNA function. Run-time Error '1004': Application defined or object defined errorCombined data from multiple sheets into one sheet
I need to do a Vlookup of an ID on the source sheet to a table in the data sheet. When the Vlookup is done, it needs to return the cell values from 6 different columns.
Here I have a function to get the range:
Function find_Col(header As String) As Range
Dim aCell As Range, rng As Range, def_Header As Range
Dim col As Long, lRow As Long, defCol As Long
Dim colName As String, defColName As String
Dim y As Workbook
Dim ws1 As Worksheet
Set y = Workbooks("Template.xlsm")
Set ws1 = y.Sheets("Results")
With ws1
Set def_Header = Cells.Find(what:="ID", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
Set aCell = .Range("B2:Z2").Find(what:=header, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
defCol = def_Header.Column
defColName = Split(.Cells(, defCol).Address, "$")(1)
col = aCell.Column
colName = Split(.Cells(, col).Address, "$")(1)
lRow = Range(defColName & .Rows.count).End(xlUp).Row - 1
Set myCol = Range(colName & "2")
'This is your range
Set find_Col = Range(myCol.Address & ":" & colName & lRow).Offset(1, 0)
'If not found
Else
MsgBox "Column Not Found"
End If
End With
End Function
Then in my sub, I select the range and do a Vlookup which fills this range:
Selection.FormulaR1C1 = "=VLOOKUP(RC[-4],myTable,2,FALSE)"
And this works great.
Then I needed to return more than just one column, so I ended up with the formula:
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Source Sheet:
Data Sheet:
So, my function returns only the range for one column, which I think I can use in terms of getting a row count then using something like this:
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
Then perhaps instead of C3
it could look something like this:
C & currentRow
--> Selection.FormulaArray = "=VLOOKUP($C & currentRow,myTable,2,3,4,5,6,FALSE)"
But then I have the issue that only one cell is selected (G3) and from H-L is not. And I have no idea whether this is even a plausible effort.
Ideally of course, I would have cells G3:L3
selected and fill the formula down to the last row.
My brain is just fried from all the thinking and attempts.
excel vba
|
show 3 more comments
I need to do a Vlookup of an ID on the source sheet to a table in the data sheet. When the Vlookup is done, it needs to return the cell values from 6 different columns.
Here I have a function to get the range:
Function find_Col(header As String) As Range
Dim aCell As Range, rng As Range, def_Header As Range
Dim col As Long, lRow As Long, defCol As Long
Dim colName As String, defColName As String
Dim y As Workbook
Dim ws1 As Worksheet
Set y = Workbooks("Template.xlsm")
Set ws1 = y.Sheets("Results")
With ws1
Set def_Header = Cells.Find(what:="ID", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
Set aCell = .Range("B2:Z2").Find(what:=header, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
defCol = def_Header.Column
defColName = Split(.Cells(, defCol).Address, "$")(1)
col = aCell.Column
colName = Split(.Cells(, col).Address, "$")(1)
lRow = Range(defColName & .Rows.count).End(xlUp).Row - 1
Set myCol = Range(colName & "2")
'This is your range
Set find_Col = Range(myCol.Address & ":" & colName & lRow).Offset(1, 0)
'If not found
Else
MsgBox "Column Not Found"
End If
End With
End Function
Then in my sub, I select the range and do a Vlookup which fills this range:
Selection.FormulaR1C1 = "=VLOOKUP(RC[-4],myTable,2,FALSE)"
And this works great.
Then I needed to return more than just one column, so I ended up with the formula:
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Source Sheet:
Data Sheet:
So, my function returns only the range for one column, which I think I can use in terms of getting a row count then using something like this:
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
Then perhaps instead of C3
it could look something like this:
C & currentRow
--> Selection.FormulaArray = "=VLOOKUP($C & currentRow,myTable,2,3,4,5,6,FALSE)"
But then I have the issue that only one cell is selected (G3) and from H-L is not. And I have no idea whether this is even a plausible effort.
Ideally of course, I would have cells G3:L3
selected and fill the formula down to the last row.
My brain is just fried from all the thinking and attempts.
excel vba
Isn't the output ending the same as the source table with all the data? If so... Why don't you just use a excel formula VLOOKUP+MATCH?=VLOOKUP($B2,SHEETDATA!$B:$J,MATCH(G$2,SHEETDATA!$B$2:$J$2,0),0)
– Damian
Mar 8 at 8:28
Where do you usecurrentRow
inside yourFor...Next
statement?
– Pspl
Mar 8 at 8:30
@Damian Thank you for the reply.. I'm trying to avoid hard-coded cells as much as possible - in the event headers are shifted on the source sheet. Then also, the source sheet number of rows will not always bee the same as the data sheet, it is at the moment for the purpose of this demonstration.
– Eitel Dagnin
Mar 8 at 8:34
@Pspl Than you for the reply. After the code with theFor Loop
, I included what the possible formula could look like.
– Eitel Dagnin
Mar 8 at 8:35
1
@SJR Once again, I do apologize. I had it asfind_Header
in the question at the end of the function. I have updated it tofind_Col
– Eitel Dagnin
Mar 8 at 8:43
|
show 3 more comments
I need to do a Vlookup of an ID on the source sheet to a table in the data sheet. When the Vlookup is done, it needs to return the cell values from 6 different columns.
Here I have a function to get the range:
Function find_Col(header As String) As Range
Dim aCell As Range, rng As Range, def_Header As Range
Dim col As Long, lRow As Long, defCol As Long
Dim colName As String, defColName As String
Dim y As Workbook
Dim ws1 As Worksheet
Set y = Workbooks("Template.xlsm")
Set ws1 = y.Sheets("Results")
With ws1
Set def_Header = Cells.Find(what:="ID", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
Set aCell = .Range("B2:Z2").Find(what:=header, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
defCol = def_Header.Column
defColName = Split(.Cells(, defCol).Address, "$")(1)
col = aCell.Column
colName = Split(.Cells(, col).Address, "$")(1)
lRow = Range(defColName & .Rows.count).End(xlUp).Row - 1
Set myCol = Range(colName & "2")
'This is your range
Set find_Col = Range(myCol.Address & ":" & colName & lRow).Offset(1, 0)
'If not found
Else
MsgBox "Column Not Found"
End If
End With
End Function
Then in my sub, I select the range and do a Vlookup which fills this range:
Selection.FormulaR1C1 = "=VLOOKUP(RC[-4],myTable,2,FALSE)"
And this works great.
Then I needed to return more than just one column, so I ended up with the formula:
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Source Sheet:
Data Sheet:
So, my function returns only the range for one column, which I think I can use in terms of getting a row count then using something like this:
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
Then perhaps instead of C3
it could look something like this:
C & currentRow
--> Selection.FormulaArray = "=VLOOKUP($C & currentRow,myTable,2,3,4,5,6,FALSE)"
But then I have the issue that only one cell is selected (G3) and from H-L is not. And I have no idea whether this is even a plausible effort.
Ideally of course, I would have cells G3:L3
selected and fill the formula down to the last row.
My brain is just fried from all the thinking and attempts.
excel vba
I need to do a Vlookup of an ID on the source sheet to a table in the data sheet. When the Vlookup is done, it needs to return the cell values from 6 different columns.
Here I have a function to get the range:
Function find_Col(header As String) As Range
Dim aCell As Range, rng As Range, def_Header As Range
Dim col As Long, lRow As Long, defCol As Long
Dim colName As String, defColName As String
Dim y As Workbook
Dim ws1 As Worksheet
Set y = Workbooks("Template.xlsm")
Set ws1 = y.Sheets("Results")
With ws1
Set def_Header = Cells.Find(what:="ID", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
Set aCell = .Range("B2:Z2").Find(what:=header, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
defCol = def_Header.Column
defColName = Split(.Cells(, defCol).Address, "$")(1)
col = aCell.Column
colName = Split(.Cells(, col).Address, "$")(1)
lRow = Range(defColName & .Rows.count).End(xlUp).Row - 1
Set myCol = Range(colName & "2")
'This is your range
Set find_Col = Range(myCol.Address & ":" & colName & lRow).Offset(1, 0)
'If not found
Else
MsgBox "Column Not Found"
End If
End With
End Function
Then in my sub, I select the range and do a Vlookup which fills this range:
Selection.FormulaR1C1 = "=VLOOKUP(RC[-4],myTable,2,FALSE)"
And this works great.
Then I needed to return more than just one column, so I ended up with the formula:
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Source Sheet:
Data Sheet:
So, my function returns only the range for one column, which I think I can use in terms of getting a row count then using something like this:
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Selection.FormulaArray = "=VLOOKUP($C3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
Then perhaps instead of C3
it could look something like this:
C & currentRow
--> Selection.FormulaArray = "=VLOOKUP($C & currentRow,myTable,2,3,4,5,6,FALSE)"
But then I have the issue that only one cell is selected (G3) and from H-L is not. And I have no idea whether this is even a plausible effort.
Ideally of course, I would have cells G3:L3
selected and fill the formula down to the last row.
My brain is just fried from all the thinking and attempts.
excel vba
excel vba
edited Mar 8 at 12:38
Eitel Dagnin
asked Mar 8 at 8:23
Eitel DagninEitel Dagnin
360415
360415
Isn't the output ending the same as the source table with all the data? If so... Why don't you just use a excel formula VLOOKUP+MATCH?=VLOOKUP($B2,SHEETDATA!$B:$J,MATCH(G$2,SHEETDATA!$B$2:$J$2,0),0)
– Damian
Mar 8 at 8:28
Where do you usecurrentRow
inside yourFor...Next
statement?
– Pspl
Mar 8 at 8:30
@Damian Thank you for the reply.. I'm trying to avoid hard-coded cells as much as possible - in the event headers are shifted on the source sheet. Then also, the source sheet number of rows will not always bee the same as the data sheet, it is at the moment for the purpose of this demonstration.
– Eitel Dagnin
Mar 8 at 8:34
@Pspl Than you for the reply. After the code with theFor Loop
, I included what the possible formula could look like.
– Eitel Dagnin
Mar 8 at 8:35
1
@SJR Once again, I do apologize. I had it asfind_Header
in the question at the end of the function. I have updated it tofind_Col
– Eitel Dagnin
Mar 8 at 8:43
|
show 3 more comments
Isn't the output ending the same as the source table with all the data? If so... Why don't you just use a excel formula VLOOKUP+MATCH?=VLOOKUP($B2,SHEETDATA!$B:$J,MATCH(G$2,SHEETDATA!$B$2:$J$2,0),0)
– Damian
Mar 8 at 8:28
Where do you usecurrentRow
inside yourFor...Next
statement?
– Pspl
Mar 8 at 8:30
@Damian Thank you for the reply.. I'm trying to avoid hard-coded cells as much as possible - in the event headers are shifted on the source sheet. Then also, the source sheet number of rows will not always bee the same as the data sheet, it is at the moment for the purpose of this demonstration.
– Eitel Dagnin
Mar 8 at 8:34
@Pspl Than you for the reply. After the code with theFor Loop
, I included what the possible formula could look like.
– Eitel Dagnin
Mar 8 at 8:35
1
@SJR Once again, I do apologize. I had it asfind_Header
in the question at the end of the function. I have updated it tofind_Col
– Eitel Dagnin
Mar 8 at 8:43
Isn't the output ending the same as the source table with all the data? If so... Why don't you just use a excel formula VLOOKUP+MATCH?
=VLOOKUP($B2,SHEETDATA!$B:$J,MATCH(G$2,SHEETDATA!$B$2:$J$2,0),0)
– Damian
Mar 8 at 8:28
Isn't the output ending the same as the source table with all the data? If so... Why don't you just use a excel formula VLOOKUP+MATCH?
=VLOOKUP($B2,SHEETDATA!$B:$J,MATCH(G$2,SHEETDATA!$B$2:$J$2,0),0)
– Damian
Mar 8 at 8:28
Where do you use
currentRow
inside your For...Next
statement?– Pspl
Mar 8 at 8:30
Where do you use
currentRow
inside your For...Next
statement?– Pspl
Mar 8 at 8:30
@Damian Thank you for the reply.. I'm trying to avoid hard-coded cells as much as possible - in the event headers are shifted on the source sheet. Then also, the source sheet number of rows will not always bee the same as the data sheet, it is at the moment for the purpose of this demonstration.
– Eitel Dagnin
Mar 8 at 8:34
@Damian Thank you for the reply.. I'm trying to avoid hard-coded cells as much as possible - in the event headers are shifted on the source sheet. Then also, the source sheet number of rows will not always bee the same as the data sheet, it is at the moment for the purpose of this demonstration.
– Eitel Dagnin
Mar 8 at 8:34
@Pspl Than you for the reply. After the code with the
For Loop
, I included what the possible formula could look like.– Eitel Dagnin
Mar 8 at 8:35
@Pspl Than you for the reply. After the code with the
For Loop
, I included what the possible formula could look like.– Eitel Dagnin
Mar 8 at 8:35
1
1
@SJR Once again, I do apologize. I had it as
find_Header
in the question at the end of the function. I have updated it to find_Col
– Eitel Dagnin
Mar 8 at 8:43
@SJR Once again, I do apologize. I had it as
find_Header
in the question at the end of the function. I have updated it to find_Col
– Eitel Dagnin
Mar 8 at 8:43
|
show 3 more comments
2 Answers
2
active
oldest
votes
So this should do the trick... I've explained every instance but if you need help understanding just ask:
Option Explicit
Sub FillData1()
Dim ws As Worksheet, wsData As Worksheet, arr As Variant, arrData As Variant
Dim DictHeaders As Scripting.Dictionary, DictIds As Scripting.Dictionary, DictDataHeaders As Scripting.Dictionary, _
DictDataIds As Scripting.Dictionary
Dim LastRow As Long, LastCol As Integer, i As Long, j As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
With ThisWorkbook
Set ws = .Sheets("Results")
Set wsData = .Sheets("List")
End With
'Lets suppose your data always starts on row 2 in both sheets and column B will always have the max amount of rows filled
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arr = .Range("B2", .Cells(LastRow, LastCol)).Value
End With
With wsData 'filling the data array
LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arrData = .Range("A2", .Cells(LastRow, LastCol)).Value
End With
'Now lets put everything into Dictionaries so if the data moves columns or rows won't matter
Set DictHeaders = New Scripting.Dictionary
Set DictIds = New Scripting.Dictionary
For i = 1 To UBound(arr, 2) 'this will fill the headers positions on the main sheet
If Not DictHeaders.Exists(arr(1, i)) Then DictHeaders.Add arr(1, i), i
Next i
For i = 2 To UBound(arr, 1) 'this will fill the IDs positions on the main sheet
If Not DictIds.Exists(arr(i, DictHeaders("KW ID"))) Then DictIds.Add arr(i, 1), i
Next i
Set DictDataHeaders = New Scripting.Dictionary
Set DictDataIds = New Scripting.Dictionary
For i = 1 To UBound(arrData, 2) 'this will fill the headers positions on the data sheet
If Not DictDataHeaders.Exists(arrData(1, i)) Then DictDataHeaders.Add arrData(1, i), i
Next i
For i = 2 To UBound(arrData, 1) 'this will fill the IDs positions on the data sheet
If Not DictDataIds.Exists(arrData(i, DictDataHeaders("KW ID"))) Then DictDataIds.Add arrData(i, DictDataHeaders("KW ID")), i
Next i
'Finally will loop through the main array to fill it with the data from the data array
On Error Resume Next
For i = 2 To UBound(arr)
For j = 6 To UBound(arr, 2) 'I'm assuming you want to avoid the first columns which are hidden
arr(i, j) = arrData(DictDataIds(arr(i, 1)), DictDataHeaders(arr(1, j)))
Next j
Next i
On Error GoTo 0
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
.Range("B2", .Cells(LastRow, LastCol)).Value = arr
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Wow, thank you for this.. Looking promising! :) I have an error popping up onDim DictHeaders As Scripting.Dictionary
. This is the errorUser Defined Type Not Defined
– Eitel Dagnin
Mar 8 at 8:54
Sorry! you need to checkMicrosoft Scripting Runtime
on your libraries
– Damian
Mar 8 at 8:55
Okay, I found theScripting Runtime
library now I am getting an error on this line:Set DictIds = New Scripting
and the error is forNew Scripting
. The error message isExpected user-defined type, not project
– Eitel Dagnin
Mar 8 at 9:02
You cant write that fast... Sorry, it's Scripting.Dictionary by the way, are there columns on the main sheet that won't on the data sheet?
– Damian
Mar 8 at 9:12
Yes, there are 5 columns not visible in the question. These 5 columns appear on the source sheet but not on the data sheet.
– Eitel Dagnin
Mar 8 at 9:19
|
show 5 more comments
I don't know if I got the true issue of your goal. However, since your Selection
parts in your code should be avoid, why don't make something like the following?
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Range(Cells(currentRow, 5), Cells(currentRow, 9)).FormulaArray = "=VLOOKUP(RC3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
Thank you for the answer :) I am getting strange results. Please refer to my question as I have attached a screenshot of the results for your answer.
– Eitel Dagnin
Mar 8 at 9:11
Toy have to adjust the formula yourself. For instance, don't you have to complete theC3
cell address?? With the name of the sheet? The#N/A
result simply means Excel isn't finding the text on the table.
– Pspl
Mar 8 at 11:26
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55059246%2fvba-vlookup-multiple-columns-and-fill-to-end-of-range%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
So this should do the trick... I've explained every instance but if you need help understanding just ask:
Option Explicit
Sub FillData1()
Dim ws As Worksheet, wsData As Worksheet, arr As Variant, arrData As Variant
Dim DictHeaders As Scripting.Dictionary, DictIds As Scripting.Dictionary, DictDataHeaders As Scripting.Dictionary, _
DictDataIds As Scripting.Dictionary
Dim LastRow As Long, LastCol As Integer, i As Long, j As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
With ThisWorkbook
Set ws = .Sheets("Results")
Set wsData = .Sheets("List")
End With
'Lets suppose your data always starts on row 2 in both sheets and column B will always have the max amount of rows filled
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arr = .Range("B2", .Cells(LastRow, LastCol)).Value
End With
With wsData 'filling the data array
LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arrData = .Range("A2", .Cells(LastRow, LastCol)).Value
End With
'Now lets put everything into Dictionaries so if the data moves columns or rows won't matter
Set DictHeaders = New Scripting.Dictionary
Set DictIds = New Scripting.Dictionary
For i = 1 To UBound(arr, 2) 'this will fill the headers positions on the main sheet
If Not DictHeaders.Exists(arr(1, i)) Then DictHeaders.Add arr(1, i), i
Next i
For i = 2 To UBound(arr, 1) 'this will fill the IDs positions on the main sheet
If Not DictIds.Exists(arr(i, DictHeaders("KW ID"))) Then DictIds.Add arr(i, 1), i
Next i
Set DictDataHeaders = New Scripting.Dictionary
Set DictDataIds = New Scripting.Dictionary
For i = 1 To UBound(arrData, 2) 'this will fill the headers positions on the data sheet
If Not DictDataHeaders.Exists(arrData(1, i)) Then DictDataHeaders.Add arrData(1, i), i
Next i
For i = 2 To UBound(arrData, 1) 'this will fill the IDs positions on the data sheet
If Not DictDataIds.Exists(arrData(i, DictDataHeaders("KW ID"))) Then DictDataIds.Add arrData(i, DictDataHeaders("KW ID")), i
Next i
'Finally will loop through the main array to fill it with the data from the data array
On Error Resume Next
For i = 2 To UBound(arr)
For j = 6 To UBound(arr, 2) 'I'm assuming you want to avoid the first columns which are hidden
arr(i, j) = arrData(DictDataIds(arr(i, 1)), DictDataHeaders(arr(1, j)))
Next j
Next i
On Error GoTo 0
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
.Range("B2", .Cells(LastRow, LastCol)).Value = arr
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Wow, thank you for this.. Looking promising! :) I have an error popping up onDim DictHeaders As Scripting.Dictionary
. This is the errorUser Defined Type Not Defined
– Eitel Dagnin
Mar 8 at 8:54
Sorry! you need to checkMicrosoft Scripting Runtime
on your libraries
– Damian
Mar 8 at 8:55
Okay, I found theScripting Runtime
library now I am getting an error on this line:Set DictIds = New Scripting
and the error is forNew Scripting
. The error message isExpected user-defined type, not project
– Eitel Dagnin
Mar 8 at 9:02
You cant write that fast... Sorry, it's Scripting.Dictionary by the way, are there columns on the main sheet that won't on the data sheet?
– Damian
Mar 8 at 9:12
Yes, there are 5 columns not visible in the question. These 5 columns appear on the source sheet but not on the data sheet.
– Eitel Dagnin
Mar 8 at 9:19
|
show 5 more comments
So this should do the trick... I've explained every instance but if you need help understanding just ask:
Option Explicit
Sub FillData1()
Dim ws As Worksheet, wsData As Worksheet, arr As Variant, arrData As Variant
Dim DictHeaders As Scripting.Dictionary, DictIds As Scripting.Dictionary, DictDataHeaders As Scripting.Dictionary, _
DictDataIds As Scripting.Dictionary
Dim LastRow As Long, LastCol As Integer, i As Long, j As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
With ThisWorkbook
Set ws = .Sheets("Results")
Set wsData = .Sheets("List")
End With
'Lets suppose your data always starts on row 2 in both sheets and column B will always have the max amount of rows filled
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arr = .Range("B2", .Cells(LastRow, LastCol)).Value
End With
With wsData 'filling the data array
LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arrData = .Range("A2", .Cells(LastRow, LastCol)).Value
End With
'Now lets put everything into Dictionaries so if the data moves columns or rows won't matter
Set DictHeaders = New Scripting.Dictionary
Set DictIds = New Scripting.Dictionary
For i = 1 To UBound(arr, 2) 'this will fill the headers positions on the main sheet
If Not DictHeaders.Exists(arr(1, i)) Then DictHeaders.Add arr(1, i), i
Next i
For i = 2 To UBound(arr, 1) 'this will fill the IDs positions on the main sheet
If Not DictIds.Exists(arr(i, DictHeaders("KW ID"))) Then DictIds.Add arr(i, 1), i
Next i
Set DictDataHeaders = New Scripting.Dictionary
Set DictDataIds = New Scripting.Dictionary
For i = 1 To UBound(arrData, 2) 'this will fill the headers positions on the data sheet
If Not DictDataHeaders.Exists(arrData(1, i)) Then DictDataHeaders.Add arrData(1, i), i
Next i
For i = 2 To UBound(arrData, 1) 'this will fill the IDs positions on the data sheet
If Not DictDataIds.Exists(arrData(i, DictDataHeaders("KW ID"))) Then DictDataIds.Add arrData(i, DictDataHeaders("KW ID")), i
Next i
'Finally will loop through the main array to fill it with the data from the data array
On Error Resume Next
For i = 2 To UBound(arr)
For j = 6 To UBound(arr, 2) 'I'm assuming you want to avoid the first columns which are hidden
arr(i, j) = arrData(DictDataIds(arr(i, 1)), DictDataHeaders(arr(1, j)))
Next j
Next i
On Error GoTo 0
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
.Range("B2", .Cells(LastRow, LastCol)).Value = arr
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Wow, thank you for this.. Looking promising! :) I have an error popping up onDim DictHeaders As Scripting.Dictionary
. This is the errorUser Defined Type Not Defined
– Eitel Dagnin
Mar 8 at 8:54
Sorry! you need to checkMicrosoft Scripting Runtime
on your libraries
– Damian
Mar 8 at 8:55
Okay, I found theScripting Runtime
library now I am getting an error on this line:Set DictIds = New Scripting
and the error is forNew Scripting
. The error message isExpected user-defined type, not project
– Eitel Dagnin
Mar 8 at 9:02
You cant write that fast... Sorry, it's Scripting.Dictionary by the way, are there columns on the main sheet that won't on the data sheet?
– Damian
Mar 8 at 9:12
Yes, there are 5 columns not visible in the question. These 5 columns appear on the source sheet but not on the data sheet.
– Eitel Dagnin
Mar 8 at 9:19
|
show 5 more comments
So this should do the trick... I've explained every instance but if you need help understanding just ask:
Option Explicit
Sub FillData1()
Dim ws As Worksheet, wsData As Worksheet, arr As Variant, arrData As Variant
Dim DictHeaders As Scripting.Dictionary, DictIds As Scripting.Dictionary, DictDataHeaders As Scripting.Dictionary, _
DictDataIds As Scripting.Dictionary
Dim LastRow As Long, LastCol As Integer, i As Long, j As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
With ThisWorkbook
Set ws = .Sheets("Results")
Set wsData = .Sheets("List")
End With
'Lets suppose your data always starts on row 2 in both sheets and column B will always have the max amount of rows filled
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arr = .Range("B2", .Cells(LastRow, LastCol)).Value
End With
With wsData 'filling the data array
LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arrData = .Range("A2", .Cells(LastRow, LastCol)).Value
End With
'Now lets put everything into Dictionaries so if the data moves columns or rows won't matter
Set DictHeaders = New Scripting.Dictionary
Set DictIds = New Scripting.Dictionary
For i = 1 To UBound(arr, 2) 'this will fill the headers positions on the main sheet
If Not DictHeaders.Exists(arr(1, i)) Then DictHeaders.Add arr(1, i), i
Next i
For i = 2 To UBound(arr, 1) 'this will fill the IDs positions on the main sheet
If Not DictIds.Exists(arr(i, DictHeaders("KW ID"))) Then DictIds.Add arr(i, 1), i
Next i
Set DictDataHeaders = New Scripting.Dictionary
Set DictDataIds = New Scripting.Dictionary
For i = 1 To UBound(arrData, 2) 'this will fill the headers positions on the data sheet
If Not DictDataHeaders.Exists(arrData(1, i)) Then DictDataHeaders.Add arrData(1, i), i
Next i
For i = 2 To UBound(arrData, 1) 'this will fill the IDs positions on the data sheet
If Not DictDataIds.Exists(arrData(i, DictDataHeaders("KW ID"))) Then DictDataIds.Add arrData(i, DictDataHeaders("KW ID")), i
Next i
'Finally will loop through the main array to fill it with the data from the data array
On Error Resume Next
For i = 2 To UBound(arr)
For j = 6 To UBound(arr, 2) 'I'm assuming you want to avoid the first columns which are hidden
arr(i, j) = arrData(DictDataIds(arr(i, 1)), DictDataHeaders(arr(1, j)))
Next j
Next i
On Error GoTo 0
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
.Range("B2", .Cells(LastRow, LastCol)).Value = arr
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
So this should do the trick... I've explained every instance but if you need help understanding just ask:
Option Explicit
Sub FillData1()
Dim ws As Worksheet, wsData As Worksheet, arr As Variant, arrData As Variant
Dim DictHeaders As Scripting.Dictionary, DictIds As Scripting.Dictionary, DictDataHeaders As Scripting.Dictionary, _
DictDataIds As Scripting.Dictionary
Dim LastRow As Long, LastCol As Integer, i As Long, j As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
With ThisWorkbook
Set ws = .Sheets("Results")
Set wsData = .Sheets("List")
End With
'Lets suppose your data always starts on row 2 in both sheets and column B will always have the max amount of rows filled
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arr = .Range("B2", .Cells(LastRow, LastCol)).Value
End With
With wsData 'filling the data array
LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
arrData = .Range("A2", .Cells(LastRow, LastCol)).Value
End With
'Now lets put everything into Dictionaries so if the data moves columns or rows won't matter
Set DictHeaders = New Scripting.Dictionary
Set DictIds = New Scripting.Dictionary
For i = 1 To UBound(arr, 2) 'this will fill the headers positions on the main sheet
If Not DictHeaders.Exists(arr(1, i)) Then DictHeaders.Add arr(1, i), i
Next i
For i = 2 To UBound(arr, 1) 'this will fill the IDs positions on the main sheet
If Not DictIds.Exists(arr(i, DictHeaders("KW ID"))) Then DictIds.Add arr(i, 1), i
Next i
Set DictDataHeaders = New Scripting.Dictionary
Set DictDataIds = New Scripting.Dictionary
For i = 1 To UBound(arrData, 2) 'this will fill the headers positions on the data sheet
If Not DictDataHeaders.Exists(arrData(1, i)) Then DictDataHeaders.Add arrData(1, i), i
Next i
For i = 2 To UBound(arrData, 1) 'this will fill the IDs positions on the data sheet
If Not DictDataIds.Exists(arrData(i, DictDataHeaders("KW ID"))) Then DictDataIds.Add arrData(i, DictDataHeaders("KW ID")), i
Next i
'Finally will loop through the main array to fill it with the data from the data array
On Error Resume Next
For i = 2 To UBound(arr)
For j = 6 To UBound(arr, 2) 'I'm assuming you want to avoid the first columns which are hidden
arr(i, j) = arrData(DictDataIds(arr(i, 1)), DictDataHeaders(arr(1, j)))
Next j
Next i
On Error GoTo 0
With ws 'filling the first array
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
.Range("B2", .Cells(LastRow, LastCol)).Value = arr
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
edited Mar 8 at 11:20
answered Mar 8 at 8:50
DamianDamian
1,056214
1,056214
Wow, thank you for this.. Looking promising! :) I have an error popping up onDim DictHeaders As Scripting.Dictionary
. This is the errorUser Defined Type Not Defined
– Eitel Dagnin
Mar 8 at 8:54
Sorry! you need to checkMicrosoft Scripting Runtime
on your libraries
– Damian
Mar 8 at 8:55
Okay, I found theScripting Runtime
library now I am getting an error on this line:Set DictIds = New Scripting
and the error is forNew Scripting
. The error message isExpected user-defined type, not project
– Eitel Dagnin
Mar 8 at 9:02
You cant write that fast... Sorry, it's Scripting.Dictionary by the way, are there columns on the main sheet that won't on the data sheet?
– Damian
Mar 8 at 9:12
Yes, there are 5 columns not visible in the question. These 5 columns appear on the source sheet but not on the data sheet.
– Eitel Dagnin
Mar 8 at 9:19
|
show 5 more comments
Wow, thank you for this.. Looking promising! :) I have an error popping up onDim DictHeaders As Scripting.Dictionary
. This is the errorUser Defined Type Not Defined
– Eitel Dagnin
Mar 8 at 8:54
Sorry! you need to checkMicrosoft Scripting Runtime
on your libraries
– Damian
Mar 8 at 8:55
Okay, I found theScripting Runtime
library now I am getting an error on this line:Set DictIds = New Scripting
and the error is forNew Scripting
. The error message isExpected user-defined type, not project
– Eitel Dagnin
Mar 8 at 9:02
You cant write that fast... Sorry, it's Scripting.Dictionary by the way, are there columns on the main sheet that won't on the data sheet?
– Damian
Mar 8 at 9:12
Yes, there are 5 columns not visible in the question. These 5 columns appear on the source sheet but not on the data sheet.
– Eitel Dagnin
Mar 8 at 9:19
Wow, thank you for this.. Looking promising! :) I have an error popping up on
Dim DictHeaders As Scripting.Dictionary
. This is the error User Defined Type Not Defined
– Eitel Dagnin
Mar 8 at 8:54
Wow, thank you for this.. Looking promising! :) I have an error popping up on
Dim DictHeaders As Scripting.Dictionary
. This is the error User Defined Type Not Defined
– Eitel Dagnin
Mar 8 at 8:54
Sorry! you need to check
Microsoft Scripting Runtime
on your libraries– Damian
Mar 8 at 8:55
Sorry! you need to check
Microsoft Scripting Runtime
on your libraries– Damian
Mar 8 at 8:55
Okay, I found the
Scripting Runtime
library now I am getting an error on this line: Set DictIds = New Scripting
and the error is for New Scripting
. The error message is Expected user-defined type, not project
– Eitel Dagnin
Mar 8 at 9:02
Okay, I found the
Scripting Runtime
library now I am getting an error on this line: Set DictIds = New Scripting
and the error is for New Scripting
. The error message is Expected user-defined type, not project
– Eitel Dagnin
Mar 8 at 9:02
You cant write that fast... Sorry, it's Scripting.Dictionary by the way, are there columns on the main sheet that won't on the data sheet?
– Damian
Mar 8 at 9:12
You cant write that fast... Sorry, it's Scripting.Dictionary by the way, are there columns on the main sheet that won't on the data sheet?
– Damian
Mar 8 at 9:12
Yes, there are 5 columns not visible in the question. These 5 columns appear on the source sheet but not on the data sheet.
– Eitel Dagnin
Mar 8 at 9:19
Yes, there are 5 columns not visible in the question. These 5 columns appear on the source sheet but not on the data sheet.
– Eitel Dagnin
Mar 8 at 9:19
|
show 5 more comments
I don't know if I got the true issue of your goal. However, since your Selection
parts in your code should be avoid, why don't make something like the following?
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Range(Cells(currentRow, 5), Cells(currentRow, 9)).FormulaArray = "=VLOOKUP(RC3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
Thank you for the answer :) I am getting strange results. Please refer to my question as I have attached a screenshot of the results for your answer.
– Eitel Dagnin
Mar 8 at 9:11
Toy have to adjust the formula yourself. For instance, don't you have to complete theC3
cell address?? With the name of the sheet? The#N/A
result simply means Excel isn't finding the text on the table.
– Pspl
Mar 8 at 11:26
add a comment |
I don't know if I got the true issue of your goal. However, since your Selection
parts in your code should be avoid, why don't make something like the following?
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Range(Cells(currentRow, 5), Cells(currentRow, 9)).FormulaArray = "=VLOOKUP(RC3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
Thank you for the answer :) I am getting strange results. Please refer to my question as I have attached a screenshot of the results for your answer.
– Eitel Dagnin
Mar 8 at 9:11
Toy have to adjust the formula yourself. For instance, don't you have to complete theC3
cell address?? With the name of the sheet? The#N/A
result simply means Excel isn't finding the text on the table.
– Pspl
Mar 8 at 11:26
add a comment |
I don't know if I got the true issue of your goal. However, since your Selection
parts in your code should be avoid, why don't make something like the following?
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Range(Cells(currentRow, 5), Cells(currentRow, 9)).FormulaArray = "=VLOOKUP(RC3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
I don't know if I got the true issue of your goal. However, since your Selection
parts in your code should be avoid, why don't make something like the following?
Set myRng = find_Col("Product")
For currentRow = myRng.Rows.count To 1 Step -1
Range(Cells(currentRow, 5), Cells(currentRow, 9)).FormulaArray = "=VLOOKUP(RC3,myTable,2,3,4,5,6,FALSE)"
Next currentRow
answered Mar 8 at 8:45
PsplPspl
934417
934417
Thank you for the answer :) I am getting strange results. Please refer to my question as I have attached a screenshot of the results for your answer.
– Eitel Dagnin
Mar 8 at 9:11
Toy have to adjust the formula yourself. For instance, don't you have to complete theC3
cell address?? With the name of the sheet? The#N/A
result simply means Excel isn't finding the text on the table.
– Pspl
Mar 8 at 11:26
add a comment |
Thank you for the answer :) I am getting strange results. Please refer to my question as I have attached a screenshot of the results for your answer.
– Eitel Dagnin
Mar 8 at 9:11
Toy have to adjust the formula yourself. For instance, don't you have to complete theC3
cell address?? With the name of the sheet? The#N/A
result simply means Excel isn't finding the text on the table.
– Pspl
Mar 8 at 11:26
Thank you for the answer :) I am getting strange results. Please refer to my question as I have attached a screenshot of the results for your answer.
– Eitel Dagnin
Mar 8 at 9:11
Thank you for the answer :) I am getting strange results. Please refer to my question as I have attached a screenshot of the results for your answer.
– Eitel Dagnin
Mar 8 at 9:11
Toy have to adjust the formula yourself. For instance, don't you have to complete the
C3
cell address?? With the name of the sheet? The #N/A
result simply means Excel isn't finding the text on the table.– Pspl
Mar 8 at 11:26
Toy have to adjust the formula yourself. For instance, don't you have to complete the
C3
cell address?? With the name of the sheet? The #N/A
result simply means Excel isn't finding the text on the table.– Pspl
Mar 8 at 11:26
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55059246%2fvba-vlookup-multiple-columns-and-fill-to-end-of-range%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Isn't the output ending the same as the source table with all the data? If so... Why don't you just use a excel formula VLOOKUP+MATCH?
=VLOOKUP($B2,SHEETDATA!$B:$J,MATCH(G$2,SHEETDATA!$B$2:$J$2,0),0)
– Damian
Mar 8 at 8:28
Where do you use
currentRow
inside yourFor...Next
statement?– Pspl
Mar 8 at 8:30
@Damian Thank you for the reply.. I'm trying to avoid hard-coded cells as much as possible - in the event headers are shifted on the source sheet. Then also, the source sheet number of rows will not always bee the same as the data sheet, it is at the moment for the purpose of this demonstration.
– Eitel Dagnin
Mar 8 at 8:34
@Pspl Than you for the reply. After the code with the
For Loop
, I included what the possible formula could look like.– Eitel Dagnin
Mar 8 at 8:35
1
@SJR Once again, I do apologize. I had it as
find_Header
in the question at the end of the function. I have updated it tofind_Col
– Eitel Dagnin
Mar 8 at 8:43