Excel Lookup Data Based on Column Name not Cell Name - vba

I am trying to accomplish a strange task in excel and don't know how to go about it. I'm using Excel 2007 at work and I know very basic vba.
I want to automate a process where a person takes three spreadsheets and dumps certain data from them into one master sheet. The three spreadsheets vary every month in their column order, so unfortunately I can't just program vlookups to run and get the data.
I could be wrong, but it seems like Vlookup Match, Index Match Match, etc. wouldn't work either because they are still referencing cells. I basically need something that will find a column based on the text in the column, rather than its location, because the location will change, but the text will always be the same.
I have two ideas but I have no idea if they work and don't really know where to start on implementing them:
Convert the three spreadsheets to tables and reference the headings with table syntax (I haven't been able to get this to work)
Complex VBA that IDs everything
Can anyone help point me in the right direction to accomplish this task? Thanks so much for your help.
EDIT EXAMPLE
My main template that I'm trying to dump things into is just going to have the ID#s and empty columns:
ID# AltID# Deal
1
2
3
4
5
And then another spread sheet might have look like this
ID# AltID# Deal
1 10101 AAAA
2 20202 BBBB
3 30303 CCCC
4 40404 DDDD
5 50505 EEEE
I could of course vlookup, but the problem is next month, those columns in the second spreadsheet won't be in the same place, in the same order. They could be all the way on colum DD or whatever. So I need a formula that looks them up regardless of the columns location. Just matching them by the heading text. I hope that clarifies...

If you combine VLOOKUP with MATCH you can search based on column name, not index. Remember that the MATCH function returns the numeric index of the match. Let's assume that your data looks like the below:
NAME DAY1 DAY2 DAY3
Bob 123 345 567
Tim 456 789 998
A functioning Vlookup to return the DAY2 column for Tim would look like:
=VLOOKUP("Tim", A2:D3,MATCH("DAY2",A1:D1,0),FALSE)
A couple of notes. Where I've hard coded in words, you can use cell references.

Here is one idea:
get the index of the column ID# in Sheet2 MATCH("ID#",Sheet2!$1:$1,0)
convert to a character: CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64)
get the column range:
INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64)))
similarly for column AltID#:
INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64)))
with range of ID# and AltID#, we can do the match+index:
=INDEX(
INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64))),
MATCH(A2,INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64))),0))

Here is an idea to consider:
Give a name to cell ID# e.g "dataJanuary" and use this named-cell as reference using an OFFSET function then you can explore it with vlookup or index-match function or other method.
Next month even if the ID# column is moved to other column or row, it will always reference to the same data since the cell is already named with "dataJanuary".

Related

VBA - Split, copy and paste characters from string into another cell (with conditions)

I'm at the beginning with VBA and struggling with a worksheet that need to be cleaned up.
I have a column with strings that mix zipcodes and city names. I want to extract from column A the zipcode and place in column B, and the city name with underscore in column C.
My (example) input:
A
55442
11211
1
12
11211_brooklyn
1002_new_york
new_york
brooklyn
What I want
A
55442
11211
1
12
11211_brooklyn
1002_new_york
new_york
brooklyn
B
55442
11211
1
12
11211
1002
C
brooklyn
new_york
new_york
brooklyn
I understand how to extract characters with the Left formula but it's not enough.
Any ideas?
Thanks.
B2:
=IF(ISNUMBER(A2),A2,IFERROR(1*LEFT(A2,FIND("_",A2)-1),""))
C2:
=MID(A2, 1+LEN(B2)+ISNUMBER(B2),99)
EDIT - As it appears that there are cases like 00010_alaska; zip codes that include leading zeros, this should be used instead for column C:
C2:
=IF(B2="",A2, IFERROR(MID(A2,1+FIND("_",A2),99),""))
in A column put your source list
in B column (zip code) put formula:
=IFERROR(NUMBERVALUE(TRIM(LEFT($A1,FIND("_",$A1,1)-1))),"")
in C column (city) put formula
=IF(ISNUMBER($B1),RIGHT($A1,LEN($A1)-FIND("_",$A1,1)),$A1)
I went through and used helper columns to determine if the data started with a number. If it did, I figured out if it also had a name in it. I then returned either the full data set or the data set truncated until the city name respectively. Column B:
=IF(ISNUMBER(INT(MID(A1,1,1))),MID(A1,1,IF(ISERROR(SEARCH("_",A1)),LEN(A1),SEARCH("_",A1)-1)),"")
Then I went through and determined if the data started with something other than a number. If it did, it was a city and I used the whole dataset for that record. If not, I tested to see if it had an underscore. If it did, there was a city present. I then used helper columns to determine where that underscore began and returned the city name. I left blanks in the helper columns to get only a single name or not. Then, I concatenated it all to get my final answer. The resulting super formula is this:
=CONCATENATE(IF(NOT(ISNUMBER(INT(MID(A1,1,1)))),A1,""),IF(IF(IF(NOT(ISNUMBER(INT(MID(A1,1,1)))),A1,"")="",IFERROR(SEARCH("_",A1),""),"")="","",MID(A1,IF(IF(NOT(ISNUMBER(INT(MID(A1,1,1)))),A1,"")="",IFERROR(SEARCH("_",A1),""),"")+1,LEN(A1))))
It is ugly, but it will get the job done. I would recommend copying and pasting directly into the worksheet instead of using VBA. But, if you must use VBA, loop through column B and C and apply the formulas provided into the cell formula property. I hope that helps.

Excel vba code to copy names found in multiple worksheets and count how many times they appear

I need some help writing some VBA code.
Basically I have one spreadsheet with 4 worksheets (CLIENT1, CLIENT2, CLIENT3, CLIENT4)
Each worksheet contains a column called CONTACT.
This CONTACT column contains a person name
The CONTACT column can be in a different position in each worksheet ie the CONTACT column in CLIENT1 is in Column D whereas it appears in column E in CLIENT2
I would like some help writing some code that will create a new Worksheet called SUMMARY.
The SUMMARY worksheet would contain in Column A a list of all the names found in the CONTACT column and in Column B it would count the number of times that persons name was found.
So the SUMMARY worksheet would end up looking something like this.
A B
1 John Smith 4
2 Brad Black 2
3 Gary Soth 1
4 Bob Brown 6
5 Sam Drow 2
Hope this makes sense and thanks for your help
Andy
Note : I am just playing with Excel and not using VBA but think you can achieve it without using VBA also.
You can use COUNTIF and solve your problem.
I will show you step by step. I cant attach excel here so adding images. If you wish to have excel which i prepared then just give me your email, I will send it.
This is summary which I got by using the formula (you can see that highlighted :
Client Name column can get value from the sheet where you can combine all your unique client names and use that as base.
Check Client1, 2, 3 & 4 sheets.
Hope this may help you.
Just found that in Excel you can use the Remove Duplicates function to remove all unwanted names. I can then use the count function across all 4 worksheets to get the required information.
Thanks
Andy

Is it possible to write a VBA code that searches for the exact same data or the closest one in the past?

I have two excel wordbooks. One has parameter changes on certain dates and the other has dates on which the juice has been produced. Like this
Spreadsheet 1
date of parameter change %apples %oranges
30/09/2014 55 45
25/09/2014 50 50
20/09/2014 45 55
Spreadsheet 2
date of the created juice %people that liked it %apples %oranges
26/09/2014 88
22/09/2014 91
And I want to copy the % parameters of apples and oranges into the second workbook so that the result looks like
date of the created juice %people that liked it %apples %oranges
26/09/2014 88 50 50
22/09/2014 91 45 55
So basically if a juice is made on 26/09 for example then I want to have the parameters that were used for that juice. Obviously the parameters of 30/09 weren't used but the parameters of 25/09 were used because it's the day before the juice has been made.
Is it possible to create something like this with VBA? Could anyone show me how to do the date searching part at least? It would be so much appreciated!
You can use a VLOOKUP formula for what you would like to do rather than using VBA.
The syntax of a VLOOKUP is as follows:
VLOOKUP(lookup_value, table_array, col_index_num, [range_lookup])
To find an approximate match to the value that you are looking for, you can set the range_lookup parameter to TRUE
If you cannot change the sort order of the information in Spreadsheet 1 then a slightly more complex INDEX(MIN(INDEX())) function pair would do.
     
The standard formula in G2 is,
=IFERROR(INDEX(B$2:B$4, MIN(INDEX(ROW($1:$3)+($A$2:$A$4>$E2)*1E+99,,))),"")
This can be copied or filled both right and down. The IFERROR wrapper shows a blank cell when there are no dates that match your criteria (as in 19-Sep-2014 in the image supplied). The sample as produced on a single worksheet for demonstration's sake but the two tables could in in different worksheets or even different workbooks.
If date of parameter change is in Book2 Sheet1 A1 and date of the created juice is in A1 then in C1:
=VLOOKUP($A2,[Book2.xlsx]Sheet1!$A:$C,COLUMN()-1)
copied across and down may serve provided the date order in Book2 is reversed and both sheets are open at the same time (or the full path would be required).

VBA to check for blank cells in columns based on value in another column

Given
O 1 2 3 A
A 4 5 6 B
B 7 8 9 D
O 3
C 15
T 18
I'm looking for VBA code to validate that when column A contains a value that the remaining columns also contain values and when it doesn't contain a value, that columns 2 & 5 also contain values but 3 & 4 don't.
I've simplified the example, in a real sheet there will be many more columns and rows to check.
I've considered COUNTIF and INDEX/MATCH and array forumlas but from my understanding these all work on single columns at a time.
I want to do something like WHEN A1:An<>"" THEN COUNTBLANK(B:E) ELSE COUNTA (C:D)
Is the best way to use autofilter using blanks in A and then countblank and then a second autofilter for values in A.
Thanks
You can do it with a couple of nested IF formulae as follows:
=IF(A1<>"",
"A not empty, "&IF(COUNTBLANK(B1:E1)=0,
"B:E not blank",
"B:E have blanks"),
"A blank, "&IF(AND(COUNTBLANK(B1)+COUNTBLANK(E1)=0,
COUNTBLANK(C1)+COUNTBLANK(D1)=2),
"Columns 2&5 have values and Columns 3&4 don't",
"but condition not met"))
The reason for going down the VBA route is that I want a generic reusable function as opposed to a formula I copy between cells and sheets changing the columns etc along the way ending up with a lot of duplicate code.
So something that takes a column to test and a value to test it with. Third parameter would be a range of columns to validate, and the fourth parameter the validation.
I don't want any solution to have the columns hard coded and I don't want intermediate totals at the end of rows. This is fairly easily achieved in Excel itself...
The reason for trying to use countblank is that I can apply it to a range.
After a lot of searching I discovered this (the columns don't match the original example)
=SUMPRODUCT((A2:A19<>"")*(B2:D19=""))
=SUMPRODUCT((A2:A19="")*(D2:D19=""))
=SUMPRODUCT((A2:A19="")*(B2:C19<>""))
Nice huh? I just need to convert it into VBA now.
Thanks

Excel countif Pulling apart a cell to do different things

Excel 2007
I have a row of cells with variation of numbers and letters (which all mean something.. not random.)
It's basically a timesheet. If they take a sick day they put in S, if they take a partial sick day they put in PS. The problem is they also put in the hours they did work too. They put it in this format: (number)/PS.
Now if it were just letters I could just do =countif(range,"S") to keep track of how many s / ps cells there are. How would I keep track if they are PS where it also has a number separated by a slash then PS.... I also still need to be able to use that number to add to a total. Is it even possible or will I have to format things different to be able to keep track of all this stuff.
Assuming this is something like what your data looks like:
A B C D E
1 1 2 S 4/PS 8
...then you could do this:
1- add a column that just totals the "S" entries with a COUNTIF function.
2- add a hidden row beneath each real data row that will copy the numerical part of the PS entries only with this function in each column:
=IF(RIGHT(B1,2)="PS",IF(ISERROR(LEFT(B1,LEN(B1)-SEARCH("/",B1)-1)),"",INT(LEFT(B1,LEN(B1)-SEARCH("/",B1)-1))),"")
3- add another column to the right that just totals the "PS" entries by summing the hidden row from step 2.
3- add another column that totals everything by just summing the data row. that will ignore the text entries automagically.
4- have a grand total column that adds those three columns up
If you don't want to see the "S" and "PS" total columns, you can of course just hide them.
So in the end, the sheet would look like this:
A B C D E F G H I J
1 1 2 S 4/PS 8 1 4 11 16
2 4 <--- hidden row
HTH...
My quick take on this is:
pass the cell value into a CSTR function, so no matter what is entered you will be working with a string.
parse the information. Look for S, PS, or any other code you deem to be valid. Use Left or Right functions if you need to look at partial string.
check for number by testing the ascii value, or trying a CINT function, which will only work if the string can be converted to integer.
If you can show a sample of your cells with variation of numbers and letters I can give you more help. Hope this works out.
-- Mike