Search related range for number between 2 values (vba, Excel) - excel

I'm learning vba and I have an excel table which looks like this:
Range |max | min| discount%
R1 |0 | 9| 0
R2 |10 | 19| 10
R3 |20 | 100| 20
From another excel sheet, I have a field quantity purchased from which I want to retrieve the range coming from this table.
E.g
if qty = 6 then R1, if qty = 56 then R3
and so on
This is normally not so difficult with a vlookup when my table is static. My problem is the fact that the number of ranges can change (due to a macro I wrote). Here it's 3 ranges, but we can have more or less ranges with different values. Can someone please help?

When you're trying to evaluate multiple things you can use "And" in VBA Its just like the excel version, both expressions must return true for you to receive a True answer.
This should get you going in the right direction,
Basic logic
a = b : a equals b
a <= b : a is less than or equal to b
a >= b : a greater than or equal to b
a < b : a is less than b
a > b : a is greater than b
a <> b : a is not equal to b
Sub ranger()
If Range("A1") > 1 And Range("A1") < 3 Then
MsgBox True
Else
MsgBox False
End If
End Sub
Put 2 in cell A1

Related

VBA macro to subtract one variable number (dynamic) from a fixed number

I am after a dynamic macro that subtracts numbers in C2 onwards from B2 onwards and puts them in D2 onwards.
Numbers in C2 onwards are fixed, although the user will put numbers in B2 onwards. The length of Column C (Hours Charged) changes dependent on the sheet that has been imported. The code is as follows:
Dim O As Long
O = Cells(Rows.Count, "C").End(xlUp).Row
Cells(O + 1, "C").Formula = "=SUM(C2:C" & O & ")"
Cells(O + 1, "C").Interior.Color = RGB(208, 247, 197)
Cells(O + 1, "C").Font.Bold = True
The sheet looks something like this (the first column is B, the last is D):
Hours Budgeted | Hours Charged | Variance
0 | 85 | 0
0 | 31 | 0
0 | 20 | 0
0 | 100 | 0
0 | 75 | 0
To summarise, when a user inputs a value in the Hours Budgeted (B) column, i want it to automatically subtract from the Hours Charged (C) column and display in the Variance (D) column.
The reason why this can't just be a '=C2-B2' is because I have a macro inputting all this data, as well as a separate macro that 'Resets' the sheet (removing all data and formulas).
Thanks all,
Jake.
The following code should do the trick, just add it after the code you posted.
For i = 2 To O
Cells(i, "D").FormulaR1C1 = "=RC[-1]-RC[-2]"
Next i
FormulaR1C1 lets you insert cells references that are relative to the cell you're putting the formula into, so R[2]C[3] would insert a reference to a cell three rows down and three columns to the right.

Excel sum if meets condition

I currently have two columns that look like this:
value | condition
50 | Y
60 | N
30 | Y
10 | Y
I cant seem to make use of IF function to get a sum of all the rows. Basically the aim here is to only sum the values if condition is Y and display the total in a cell. And if condition column is N, it will see value as 0. I want to be able to do this without the need of creating an additional column even though I understand this is easily done with a brand new column.
as Nick mentioned, you can use Sumif:
A | B
1 value | condition
2 50 | Y
3 60 | N
4 30 | Y
5 10 | Y
sumif structure:
=sumif(Range, Criteria, Sum_Range)
sumif for table above:
=sumif(B2:B5,"Y",A2:A5)
Excel formulas are not case-sensitive and there is no difference between A1:A5 and A2:A5 because the table titles are not important but start row and end row is important in both Range and Sum_Range.

How to create complex nested If statement in Excel?

I have an If formula in Excel as seen below:
=IF((Q2="O")*AND(R2="O")*AND(S2="O")*AND(T2="O")*AND(U2="O"),"O","X")
Basically, if cells Q2 to U2 is O the cell with formula will have O written in it. Otherwise it will have X. Now I want to change it into a nested If statement due to new conditions.
These conditions, in order are:
If any one of cells Q2 to U2 = X, cell = X
If any one of cells Q2 to U2 = date format, cell = ∆
If Q2 to U2 = O, cell = O
If none of the conditions are met, the cell will have value "FALSE". (Default appears)
Each of the cells have this condition to follow,
If any one of cells Q2 to U2 = -, ignore that cell and count the other cells to get final result.
I tried switching to Or in my original formula to test out conditions 1 and 3.
=IF((Q2="O")*or(R2="O")*or(S2="O")*or(T2="O")*or(U2="O"),"O","X")
But it doesn't work. Plus I'm not sure how to do condition 5 as well. Any help?
Is it possible to do something so complex just by using Excel formula? Or do I need to go into VBA?
Things like this are usually easier if you tackle the problem in order of priority. It looks like 1 has the highest priority:
=IF(COUNTIF(Q2:U2,"X")>0,"X","Does not contain X")
COUNTIF(Q2:U2,"X") returns the number of occurrences of X in the range Q2:U2.
In place of "Does not contain X", we can first check for condition 2:
=IF(SUMPRODUCT(--ISNUMBER(Q2:U2))>0,"∆","Does not contain X or dates")
A date in excel is literally a number with some decorative formatting. I am using ISNUMBER to find the numbers and SUMPRODUCT to count the identified cells in the range. If there are more than 0 (at least 1), then it will become ∆.
In place of "Does not contain X or dates" now, we could check for Os. I would count the Os and add the cells with - (conditions 3 and 5 together) and see if they add up to the total cells in Q2:U2 (which is 5 in this case):
=IF(COUNTIF(Q2:U2,"O")+COUNTIF(Q2:U2,"-")=5,"O","FALSE")
When combined, it would become:
=IF(COUNTIF(Q2:U2,"X")>0,"X",IF(SUMPRODUCT(--ISNUMBER(Q2:U2))>0,"∆",COUNTIF(Q2:U2,"O")+COUNTIF(Q2:U2,"-")=5,"O","FALSE"))
Since all these involve counts, it might be easier setting up helper columns, something like:
| Q | R | S | T | U | V | W | X | Y | Z
1 | | | | | | Count of X | Count of dates | Count of O | Count of - | Final value
2 | | | | | | A | B | C | D | E
A will be:
=COUNTIF(Q2:U2,"X")
B will be:
=SUMPRODUCT(--ISNUMBER(Q2:U2))
C will be:
=COUNTIF(Q2:U2,"O")
D will be:
=COUNTIF(Q2:U2,"-")
E will be:
=IF(V2>0,"X",IF(W2>0,"∆",X2+Y2=5,"O","FALSE"))

SUMIF minimum-so-far condition

I am trying to set up a smart conditional summing within Excel. But the range of functions available doesn't appear to provide what I am looking for.
I have two columns of numbers. In A, I have what we'll call indentation levels. In B, I have values.
For any particular row that has child indentations, I want to use a formula in B that will calculate the sum of values in B from the next row down to the next instance of that row's A value if the corresponding value in A is the minumum it has been so far.
e.g.
row | A | B | calc'd
--------------------
1 | 0 | 9 | y
2 | 2 | 2 |
3 | 1 | 7 | y
4 | 2 | 3 |
5 | 2 | 4 |
6 | 0 | 5 | y
7 | 1 | 5 |
So, for row 1, the sum range will be rows 2 through 5. This part, I can do with an OFFSET MATCH.
The SUMIF should include row 2, as A2 is the minimum value in A2:A2.
Likewise, it should include row 3, as A3 is the minimum value in A2:A3.
But it should not include rows 4 or 5 in the sum, because their A-column values are not the minimum "so far". (These values have already been "summed up" into row 3.)
How do I create a ranged sumif with this "minimum-so-far" condition?
I found a solution to this. Not quite as clean as I wanted, but it does the trick:
Add a helper value to column C, which is the "parent row" is will sum into.
For example, C5 {=MAX(ROW($9:5)*(A$1:A4<A5))} (note: array function).
Making the final equation for B1 =SUMIF(C2:Cn,"="&ROW(),B2:Bn) (where n is the upper limit of the working range).
As written here, inserting lines messes things up, but it can all be expanded with OFFSETs for row insertability.

How to copy and process data in the columns based on texts in the Header but header is not in first row

I am new to Excel and been told that I may find the solution in VBA.
I am working on a system generated report from which I need to remove few columns, but the report contains some important information in first 25 rows. After this information, we get 15 to 40 rows of actual report data (number of rows varies by centres).
I need to process this actual data by removing blank columns, sorting by A to Z, and then inserting the ‘Average’ in the last column.
Currently, I am copying actual report data, trim down unnecessary columns, make the necessary changes, applying VLOOKUP with last month’s report to verify opening and closing counts are matching or not (they almost always do, but why to take chances?) and then pasting it at the same location. Can it be done using VBA?
Format of report
> For the period 01-11-2011 to 30-11-2011
> *Parameter Selection List
>From 01-11-2011
>Date 30-11-2011
> Partner SAM
>Code TWO
>Location 999
>Report For All
>Code : TWO
>Location : ABC
Product Name |LastCount|AddedInPeriod |Left In The Period |Net Total | Average
SUPER GLUE |123456 |0 | 0 | 234567 |
CRICKET BAT |345678 |0 | 0 | 346899 |
NICON |2345 |0 | 0 | 2456 |
OLD STICKS |45689 |0 | 0 | 56778 |
Total |517168 |0 | 0 | 640700 |
Product Name is in Column B, Column C is blank, Last Count is in Column D, Header AddedInPeriod is mearged in Column D and F but data is in Column F, same is with Left In The Period(Header is merged inColumn G and H,but data is in column H), Col I is blank, Net Total is in J, Col K is blank and Average is in Col L
Data below the headers Product name, Last Counts and Net Total is necessary, rest of the range should be removed. (Please note, few cells are merged)
Final Report should look like this
For the period 01-11-2011 to 30-11-2011
*Parameter Selection List
From 01-11-2011
Date 30-11-2011
Partner SAM
Code TWO
Location 999
Report For All
Code :TWO
Location : ABC
Product Name|Last Count |Net Total|Average
CRICKET BAT |345678 |346899 |346288.5
NICON |2345 |2456 |2400.5
OLD STICKS |45689 |56778 |51233.5
SUPER GLUE |123456 |234567 |179011.5
**Total |517168 |640700 |578934**
How to do that?
Here is a function that will get the letter of the column with the header you suggest.
Function Letter(oSheet As Worksheet, name As String, Optional num As Integer)
If num = 0 Then num = 1
Letter = Application.Match(name, oSheet.rows(num), 0)
Letter = Split(Cells(, Letter).Address, "$")(1)
End Function
just create a new variable, and pass the header to the function, i.e.,
newvar = letter(sheets("Sheets1"), "SUPER GLUE", 4)
where the 4 is, where you indicate the row where the header can be found, in this instance I put row 4. Once you have the letter, then use
Sheets("Sheet2").Range(newvar & "4:" & newvar & Range("A1").End(xlDown).Row).Copy Destination:=Sheets("Sheet2").Range("A1")
This will take the information from the particular column, with the column header, and paste it into sheet2 A1

Resources