Is there any way to make Vlookup in VBA work when 1 value is a Number and the other is a Number as Text format? I do not want to convert the format of any number.
The problem is I sometimes have reports from SAP and there the text formatted numbers are given. But i need to apply Vlookup in VBA and match in my table where numbers are number formatted. I can't convert all numbers to a number format as it takes time and I don't want to slow my macro.
It is possible with an array formula.
I assume the table from A2 to B100 and the number to match at A1
=VLOOKUP(A1,IFERROR(A2:B100*1,A2:B100),2)
This is an array formula and must be confirmed with ctrl+shift+enter.
If you are working with bigger ranges, it will be better to change to INDEX and MATCH like:
=INDEX(B2:B100,MATCH(A1,IFERROR(A2:A100*1,A2:A100),0))
This is an array formula and must be confirmed with ctrl+shift+enter.
However: if the ranges are very big, or by using whole columns, you will slow down excel a lot.
Is there any way to make Vlookup in VBA work when 1 value is a Number and the other is a Number as Text format?
An INDEX/MATCH function pair is likely the most effective method of lookup. Using IFERROR to pass the processing to an alternate MATCH seems viable.
'if the lookup 'numbers' are predominantly numeric
=index(sheet2!a:a, iferror(match(a2, sheet2!b:b, 0), match(text(a2, "0"), sheet2!b:b, 0))
'if the lookup 'numbers' are predominantly textual
=index(sheet2!a:a, iferror(match(text(a2, "0"), sheet2!b:b, 0), match(a2, sheet2!b:b, 0))
I can't convert all numbers to a number format as it takes time and I don't want to slow my macro.
A Text-to-Columns, Fixed Width, Finish converts full columns of text-that-look-like-numbers to true numbers very quickly.
Your question has no sample data or code. Please supply sample setups in future.
I post this answer as a possible simpler answer than the other two IF the text formatted numbers are the one that you are supplying as the lookup value to the Vlookup function.
Worksheet Function:
=VLOOKUP(VALUE(A1), LookupArray, 2, FALSE)
You mention in 'Vlookup in VBA' and macros, so VBA code:
retVal = Application.VLookup(CLng(lookupVal), LookupRange, 2, False)
I faced the same issue and below helped (I had SAP IDs in column 'B', replace the cell values and last row within range), this converts the SAP ID/number from General/Text/green arrowed format to numbers/values, which then can be looked up with numbers
LR1 = Sheet1.Range("B" & Rows.Count).End(xlUp).Row
With Range("B3:B" & LR1)
.Value = Evaluate(.Address & "*1")
End With
Let me know if it helped!!!
Related
I have a table which is populated using VBA.
One colum gives me a text filter when the values are numbers.
The format is "Tal" (Number) for all cells.
The code that creates this column is this:
ThisWorkbook.Sheets("1").Range("BE3").Formula = "=IFERROR(VLOOKUP(D3, Toyota!A:F,6,False), """")"
ThisWorkbook.Sheets("1").Range("BE3:BE" & lastrow1).Copy
ThisWorkbook.Sheets("1").Range("BE3").PasteSpecial xlValues
Essentially a vlookup that gets a number from a different sheet then to preserve the number it copy pastes values.
The value the vlookup fetches is a formula:
=TODAY() - INTEGER(D1)
Which returns the full days since the timestamp.
Yet again it's formatted as number.
So why would this cause the filter to be text filter? And can this be changed?
Answer modified, try returning a 0. It will at least show you if it's the formula that's giving you text values. Based on your latest picture in your comment, most values are text.
= "=IFERROR(VLOOKUP(D3, Toyota!A:F,6,False), 0)"
I have a table in which one column occasionally contains a sequence of numbers separated by commas (Units). I'd like to find a script that will count the amount of values in that cell (Values), then divide the adjacent cell by that amount, ultimately replacing the value of that cell (NeedResult, replacing Values).
I've played around with formulas, but my VBA skills are rudimentary... Any help mucho appreciated!
table image here
Unless you really want it, I'm not sure you need a VBA solution for this. The calculation can be done using Excel's formulas: simply subtract the length of the string from the length of it with commas removed. Your cell formula could look something like this:
=C3/(LEN(B3)-LEN(SUBSTITUTE(B3,",",""))+1)
Split the first cell value on the commas and adjust the ubound dimension of the resulting array.
dim i as long
i = ubound(split(range("b2").value, chr(44))) + 1
range("d2") = cdbl(range("c2").value / i)
Without the compiler directive Option Base 1, a split array is zero-based.
You could use a formula as well
In D2 entered as array formula with Ctrl+Shift+Enter
=IF(ISBLANK(B2),"",C2/COUNT(FILTERXML("<t><s>" & SUBSTITUTE(B2,CHAR(44), "</s><s>") & "</s></t>", "//s")))
long time reader, first time pos(t)er of questions.
I have an Excel 2013 worksheet of about 4,000 unique records (rows) of data. We'll call this the data dump. I've filtered the data dump using any one of about six different data elements (columns). After each filter I save the results to a new worksheet. I clear the filter to start over, and ultimately wound up with about six different worksheets.
I need to be able to account for each unique record in the data dump--each one should (in theory) appear on at least one of the filtered worksheets, and I need to identify any that don't.
My big problem is that the only way to uniquely identify each record is by concatenating a text string out of five consecutive cells in each row. I cannot add a column of concatenated text to these worksheets (for which reasons I'll presently spare you), so essentially I'm trying to build a formula that says the following:
For a given, unique, concatenated string of text of five consecutive cells from one record on this data dump worksheet, identify any exact matching strings from any of the other worksheets and return TRUE if found or FALSE if not.
I will, of course, have to apply this formula to every record in the data dump.
Thoughts or tips? Ultimately I think it comes down to a lot of small moving parts that I could manage individually, but that I'm not confident I could manage collectively.
Any help is appreciated and I'll be happy to clarify where needed. And forgiveness if a similar question has been asked previously--I searched pretty fruitlessly for an answer all afternoon.
Thank you!
You could use Index to create a concatenated range that serves a lookup range to Match(). Match() can concatenate the lookup term. It then returns a number for a match or an error if no match is found. Wrap error trapping formulas around this for the TRUE/FALSE result. Along the lines of
=iferror(match(sheet1!A1&sheet1!B1&sheet1!C1&sheet1!d1&sheet1!e1,index(Sheet2!$a$1:$a$1000&Sheet2!$b$1:$b$1000&Sheet2!$c$1:$c$1000&Sheet2!$d$1:$d$1000&Sheet2!$e$1:$e$1000,0),0),FALSE)
Note that any match will return a number (which will evaluate to a boolean TRUE in summarising formulas) and a non-match will return a FALSE.
This will get you the row number of the match for the first row of original data on sheet1, where the first extract lives on Sheet2 in the first 1000 rows. Use the same principle for the other four sheets and wrap the five formulas into an OR() statement to arrive at a final TRUE or FALSE.
Note that the Index ranges should not encompass whole columns, but only the rows with data. Otherwise the formula will be very slow to recalculate, especially if you use it 4000 times.
Here is one way. If you have your datadump records from A1 downwards.
And assuming you can have your filter sheets similarly. Then adjust your filter ranges so that the formula calls the fixed ranges properly.
You might be able to name them...
This formula need CSE for it to work
Edit by teylyn: This formula is an array formula and needs to be confirmed with Ctrl-Shift-Enter. It
will not work if you only hit the Enter key after editing the formula.
Control-Shift-Enter is sometimes referred to as CSE. People also call
it "array-entering" a formula. Excel will put curly braces around the
formula, which you can see in the formula bar when the cell is
selected.
=OR(
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet1!$A$1:$A$200&FilterSheet1!$B$1:$B$200&FilterSheet1!$C$1:$C$200&FilterSheet1!$D$1:$D$200&FilterSheet1!$E$1:$E$200, 0), FALSE),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet2!$A$1:$A$200&FilterSheet2!$B$1:$B$200&FilterSheet2!$C$1:$C$200&FilterSheet2!$D$1:$D$200&FilterSheet2!$E$1:$E$200, 0), FALSE),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet3!$A$1:$A$200&FilterSheet3!$B$1:$B$200&FilterSheet3!$C$1:$C$200&FilterSheet3!$D$1:$D$200&FilterSheet3!$E$1:$E$200, 0), FALSE),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet4!$A$1:$A$200&FilterSheet4!$B$1:$B$200&FilterSheet4!$C$1:$C$200&FilterSheet4!$D$1:$D$200&FilterSheet4!$E$1:$E$200, 0), FALSE),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet5!$A$1:$A$200&FilterSheet5!$B$1:$B$200&FilterSheet5!$C$1:$C$200&FilterSheet5!$D$1:$D$200&FilterSheet5!$E$1:$E$200, 0), FALSE))
I have put hard returns so you can see what is going on better. Obviously you must collect up the formula
EDIT for new requirement: Ctrl+Shift+Enter required again
=CONCATENATE(
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet1!$A$1:$A$200&FilterSheet1!$B$1:$B$200&FilterSheet1!$C$1:$C$200&FilterSheet1!$D$1:$D$200&FilterSheet1!$E$1:$E$200, 0) & " - FilterSheet1", ""),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet2!$A$1:$A$200&FilterSheet2!$B$1:$B$200&FilterSheet2!$C$1:$C$200&FilterSheet2!$D$1:$D$200&FilterSheet2!$E$1:$E$200, 0) & " - FilterSheet2", ""),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet3!$A$1:$A$200&FilterSheet3!$B$1:$B$200&FilterSheet3!$C$1:$C$200&FilterSheet3!$D$1:$D$200&FilterSheet3!$E$1:$E$200, 0) & " - FilterSheet3", ""),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet4!$A$1:$A$200&FilterSheet4!$B$1:$B$200&FilterSheet4!$C$1:$C$200&FilterSheet4!$D$1:$D$200&FilterSheet4!$E$1:$E$200, 0) & " - FilterSheet4", ""),
(IFERROR(MATCH(A1&B1&C1&D1&E1,FilterSheet5!$A$1:$A$200&FilterSheet5!$B$1:$B$200&FilterSheet5!$C$1:$C$200&FilterSheet5!$D$1:$D$200&FilterSheet5!$E$1:$E$200, 0) & " - FilterSheet5", ""))
My edit for the new requirement just takes the matches found, as #Messy Jesse said, and also appends the sheet name too. If no match is found in a sheet, then ZLS is added to the string. The total string is then concatenated...
I have been working on an attendance sheet and trying to make the monthly reports automatic. I have asked my previous question on the same issue and got the idea to accomplish the task.
But now I have stuck at one place. I have this below formula:
=COUNTIFS(C5:C27,">0", E5:E27,"G", F5:F27,"CAT1")
The value in cell "C" in the above is coming from the below formula (in cell "C")
=IF((COUNTIF(G5:AK5,"p"))>0,1,0)
I had to add this extra column ("C") only to supply input to my fist formula. My question is - "Can we merge the IF function inside the COUNTIFS to get the result in one go and to eliminate the use of an extra column (column C)"?
To perform these cell reference acrobatics you will likely need to switch to an array formula. Array formulas chew up calculation cycles logarithmically so it is good practise to narrow the referenced ranges to a minimum. A 'helper' column such as you've used in column C can generally reduce calculation cycles and make a worksheet more 'user friendly'.
A COUNTIFS function requires that the ranges being examined are not only the same size but also the same shape. Looking at G5:AK5 is not the same as looking at E5:E35 even though they contain the same number of cells¹.
In the sample data below, you formula is in A1 and uses the 'helper column' C. My array formula is in A2 and does not consider column C ahough it incorporated the logic.
The array formula in A2 is:
=SUM(IF(E5:E27 = "G", IF(F5:F27 = "CAT1", SIGN(COUNTIFS(OFFSET($G$5, ROW($1:$23)-1, 1, 1, 31), $I2)))))
Array formulas need to be finalized with Ctrl+Shift+Enter↵. Once entered into the first cell correctly, they can be filled or copied down or right just like any other formula.
¹Some functions not only accept but welcome cell ranges that are the same number of calls but transposed. Offsetting or staggering the ranges is also an option if the cell ranges are the same size. In difficult cases the TRANSPOSE function can be helpful.
I'm relatively new to excel programming. I'm working on making a spread sheet that shows exponential decay. I have one column (A1:A1000) of 1000 random numbers between 1 & 10 using the TRUNC(RAND()*10,0) in each cell. The next Column (B1:B1000) has a logic mask =IF(A1=0,1,0) , where if the value in the A cell is 0, then the B cell shows a 1. Next, to find the number of 0's in the A column, I have the next column taking the sum of B1:B1000, which returns the number of 0's that showed up in the first column. I'm sure there's an easier way to do that, but this seems to work fine.
Here's my problem, hopefully it's clear what I'm asking:
Next, I want to take the sum of the logic column (B) from B1:B(1000- the value of the sum from (B1:1000)) in the cell below the cell that calculates sum(B1:B1000). Is there a way to to algebra in a cell formula to reference a cell? More simply, if I want to refer to A3, for example, is there a way to input something like A(2+1) to get A3? Does this make sense?
You can very easily do, in VBA:
ActiveCell.Formula = "=A" & (2+1) & "+15"
In Excel:
=INDIRECT(ADDRESS(2+1, COLUMN(A1)))+15
This will set the formula to "=A3+15". Generally, this is best done with variables, so remember to do that.
In Excel, and as pointed out by Eric, you can write the referance to the cells just like normal strings thanks to INDIRECT() function.
Just make sure that the string passed to INDIRECT() is a valid cell reference.
For example :
=SUM(INDIRECT("B" & 2+7*(H2-1)):INDIRECT("B"&(2+7*H2)-1))
Here, I sum 7 lines for each week (H2). It gives the sum of B2:B8, B9:B15, B16:B22, etc.
Hope my example will help you figure out how to use it in real situation.