Get Price from Table in excel using lookup or macro - vba

I have table "PriceList" in excel with below structure
Type Thickness width Height Price
iron 5 7 10 20
iron 10 10 15 24
iron 12 14 17 26
how can i find the price if some-one enters type iron, thickness 10, width 9, height 14 using vlookup or macro. i have tried using vlookup but its not works and later on i found on google that Vlookup only retrieve data with one parameter. Can i do this using macro like we do for selecting sheet data using queries
select * from [sheet1$] where col1=x
Please suggest??
Edit: i have calculated the above using this. Now i am calling this macro on sheet change event like below
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 41 Or Target.Column = 43 Or Target.Column = 45 Or Target.Column = 46 Then
Dim i As Currency
i = Calculate_CorePrice(cell(Target.Row, 46).Value, cell(Target.Row, 45).Value, cell(Target.Row, 41).Value, cell(Target.Row, 43).Value, "RWJ Doorset Schedule", "ED15")
cell(Target.Row, 134).Value = i
End If
End Sub
if i debug the function itself with hard-coded values, it is working but if i call the function as in above way, it does not return value and i am not able to debug sheet_change event.
How can i debug this event.

Assuming your columns are A, B, C, etc. You can use an Index/Match formula as an array (enter with CTRL+SHIFT+ENTER).
If the user enters the type, thickness, width, and height in W1, X1, Y1, and Z1, you can use:
=Index($E$2:$E$10,Match(W1&X1&Y1&Z1,$A$2:$A$10&$B$2:$B$10&$C$2:$C$10&$D$2:$D$10,0))
It's convoluted, but basically the Match part is you are looking for W1 in the range A2:A10, then whatever is in X1, you will search B2:B10, etc.

It seems I am just a bit late with my answer and #BruceWayne beat me to it. Still, I will add my solution as well as there is a nice little illustration to it:
Basically, it is the same proposal has been already proposed. Just use an array formula and the & sign to combine all criteria into one. In the end a criteria will look like this iron101015 (for example). And it will be compared to all the combinations in the table.

The best would be to loop through the data, using an if statement to check the data tables. (This could be placed in a sub or in a function depending on how you want the data to be retrieved)
Function GetPrice(Type As String, Thickness As Integer, Width As Integer, Height As Integer)
Dim ItemRow As Range, SearchColumn As Range
'Dim Price As Double 'Use variable if this were a sub
Set SearchColumn = Range(Cells(2,1),Cells(ActiveSheet.UsedRange.rows.count,1))
For Each ItemRow In SearchColumn
If ItemRow.Value = Type AND ItemRow.Offset(0,1).Value >= Thickness AND ItemRow.Offset(0,2).Value >= Width AND ItemRow.Offset(0,3).Value >= Height AND ItemRow.Offset(-1,1).Value < Thickness AND ItemRow.Offset(-1,2).Value < Width AND ItemRow.Offset(-1,3).Value < Height Then
'Price = ItemRow.Offset(0,4).Value
GetPrice = ItemRow.Offset(0,4).Value
Exit For
End If
Next ItemRow
End Function
Edit: Given your comment on another answer, I've adjusted the code to find the value as i believe you are looking for

Related

Need to add diagonal cells with an additional cell for each subsequent diagonal

I need help getting the sum of specific cells in a diagonal format. My issue is that each subsequent diagonal grows by 1 cell. I was thinking I use a For loop, but I don't know how to add an additional cell to the summation for each iteration of the loop. The picture below shows an example of the format the data will be in that I need to sum. Any ideas? Thanks for the help.
Here's a function that asks for the range and the count of values to add. You can probably adjust the code to get rid of the need to add count altogether, but it's a start.
Just for clarity, you'd enter into your sheet like this:
=AddDiagonal(D4,0)
=AddDiagonal(D7,1)
=AddDiagonal(D10,2)
...
Function
Function AddDiagonal(rng As Range, cnt As Long) As Double
Dim x As Long
Dim answer As Double
For x = 0 To cnt
If x = 0 Then
answer = answer + rng.Offset(x, x)
Else
answer = answer + rng.Offset(x * -3, x * 1)
End If
Next
AddDiagonal = answer
End Function

Macro query spread over multiple-sheets

Wording my question is slightly tricky so I've included screen-shots to make this easier. I have 2 separate spreadsheets which are currently not linked together in anyway. What I've been asked to do is:
For the drop-downs which have a * next to them, have this * drop-down get converted into a acronym (I.e. If it's Home Visit *, then this will be converted to HV), and have it automatically entered into Cell Position X. Please refer to Image 1 then Image 2)
So the user would click on Sheet one, select the relevant drop-down field and then assign how much time that task took. The second sheet would then update itself with this information - it would insert the users name, program and activities. This is where it gets very tricky. Based off the drop-down selection, if it is asterisked (*), then based off the field-type it will convert it into a set acronym which would then be placed in one of the data fields based off the entry date that has been provided.
I designed both spread-sheets and they have macros in the background, but I can't seem to work out how to best perform this. Would you suggest a transpose function which checks firstly the date criteria and then an INDEX(MATCH) function to match the criteria against a pre-defined name-range which converts Home Visit etc. to HV automatically? I'm also unsure of how to insert delimiters for each new entry that is read. If anyone can provide help I would be very grateful.
I'm not 100% sure I understand your question, but here goes:
What about adding a Worksheet_Change event to look for changes in the drop-down's cell, and then converting it to an acronym?
Place the following code inside the sheet of interest:
Private Sub Worksheet_Change(ByVal Target As Range)
'If Cell A1 is changed, put the acronym into A2
If Target.Row = 1 And Target.Column = 1 Then
Cells(2, 1) = GetAcronym(Target.Value)
End If
End Sub
Function GetAcronym(TheText As String) As String
Dim result As String
Dim x As Long
'Always grab the first letter
result = Mid(TheText, 1, 1)
'Get the other letters
For x = 2 To Len(TheText) - 1
If Mid(TheText, x, 1) = " " Then result = result & Mid(TheText, x + 1, 1)
Next x
GetAcronym = UCase(result)
End Function

Excel If Cell Is Highlighted on VLOOKUP

I have two sheets in excel, one is an order form the other is a production sheet based off the order form.
I am using VLOOKUP to query the order form for the quantity of a given item ordered.
However, sometimes this quantity is highlighted on the order form, indicating that the item in question actually gets produced 2 extra amounts (for free samples).
So for example, in the production form I have:
ITEM|QUANTITY TO PRODUCE
In the order form I have:
ITEM|QUANTITY TO ORDER
I use VLOOKUP to get the match, and this works, but if a cell in QUANTITY TO ORDER is highlighted yellow, then I need the VLOOKUP value to be added by two.
How can I do this? Is there a way to do this automatically, without a macro? My client doesn't want to be manually activating things, they just expect the sheet to work.
Thank you.
VLOOKUP can't do that. What you need to do, is treat a cell's background color as data... and a cell's background color isn't data.
But... this link explains how to do that and what the implications are.
Create a workbook-scoped name (Ctrl+F3) called BackColor referring to =GET.CELL(63,OFFSET(INDIRECT("RC",FALSE),0,-1)), and then add a column immediately to the right of the column where the user highlights cells, and make that column have a formula such as =BackColor<>0 so that it contains TRUE for any highlighted cell in the column immediately to its left.
Hard-coding the extra 2 units into your formula isn't going to be maintenance-friendly, so enter that 2 in a cell somewhere and define a name called ExtraUnits for it.
Then modify your formula to
=[the original VLOOKUP]+IF([lookup the BackColor Boolean], ExtraUnits, 0)
This will add ExtraUnits to the looked up units, for all highlighted cells.
The only drawback is that, as I said above, a cell's background color isn't data as far as Excel is concerned, so your user must trigger a recalculation - just changing cells' background color will not do that, but pressing F9 will.
The below code was found at http://www.mrexcel.com/forum/excel-questions/215415-formula-check-if-cell-highlighted.html
Function CellColorIndex(InRange As Range, Optional _
OfText As Boolean = False) As Integer
'
' This function returns the ColorIndex value of a the Interior
' (background) of a cell, or, if OfText is true, of the Font in the cell.
'
Application.Volatile True
If OfText = True Then
CellColorIndex = InRange(1,1).Font.ColorIndex
Else
CellColorIndex = InRange(1,1).Interior.ColorIndex
End If
End Function
To use the function:
=IF(CELLCORINDEX(A1,FALSE)>0,1,0)
This lets you check the color of the cell , or the text. But you will need to use the Index-match code found here http://www.mrexcel.com/forum/excel-questions/447723-vlookup-returns-cell-address.html in order to match it up.
Also, like the above answer states, highlighting a cell doesn't count as a data change, so even though you can get this info without a macro, if someone updates the cell's highlight status, it will not update the cells using this formula unless automatically.
Sounds like you may need to rethink the Highlighting being the trigger of the +2 samples. I'm with the above answer that recommends adding a column maybe True/False or Yes/No that is checked to see if they get samples.
What I did is this:
I created a user defined function:
Function getRGB3(rcell As Range, Optional opt As Integer) As Long
Dim C As Long
Dim R As Long
Dim G As Long
Dim B As Long
C = rcell.Interior.Color
R = C Mod 256
G = C \ 256 Mod 256
B = C \ 65536 Mod 256
If opt = 1 Then
getRGB3 = R
ElseIf opt = 2 Then
getRGB3 = G
ElseIf opt = 3 Then
If B <> 0 Then
B = -2
End If
getRGB3 = B + 2
Else
getRGB3 = C
End If
End Function
This made it so all the highlighted cells (in yellow) got a value of 2 when referred to, so on the order form it goes like ITEM|QUANTITY TO ORDER|CUSTOM FUNCTION VALUE| and the third column (custom function) is 2 for each corresponding yellow cell next to it, if not, it is just zero.
Then I do a second VLOOKUP to add the CUSTOM FUNCTION VALUE to the original, and then I have added two. :)

Resize pivot chart when selecting different less/more values

When creating the pivot chart using VBA, I set the size of the chart depending on the number of different values that I have in the chart. With pivot charts you have the option to select only some values of the chart. So for example if I have this chart:
And then I select only 2 I get this:
This is too big and sometimes it can be even bigger. What I would like is to resize it automatically when a user select less so that it automatically become smaller. So I would like it to be something like this:
Is there any way to change the width automatically using VBA?
You may want to take a look at these: resize (mrexcel) & Count number of series (stackoverflow)
In these sources there are some code snippets for getting the number of series in a chart and resizing charts to a fit to a range in the worksheet
Im by no means an expert coder, but with the code and concepts in the above you may be able to do something like this to a given ChartObject:
'get the number of series in a given ChartObject:
numberOfSeries = ChartObject.Chart.SeriesCollection.Count
'you can use this to specify a width in cells/as a range. For the purpose of this example I
'eventually want the chart to cover 1 cell width for each series, + 1.
myChartWidth = numberOfSeries + 1
'Give the chart a name. Smarter people may supply a solution that reference the ChartObject
'directly, but I am not that clever
ChartObject.Name = "Your Chart"
'I will use A1 as reference for setting width, change as you see fit
Sheet1.Shapes("Your Chart").Width = Sheet1.Range(Sheet1.Cells(1, 1), Sheet1.Cells(1, myChartWidth)).Width
'I assume you want to fix the height, adjust to your requirements
Sheet1.Shapes("Your Chart").Height = Sheet1.Range("A1:A10").Height
'If you want to also place the chart top left corner in the in the top left of A1, you can do the following
Sheet1.Shapes("Your Chart").Left = Sheet1.Cells(1, 1).Left
Sheet1.Shapes("Your Chart").Top = Sheet1.Cells(1, 1).Top
You probably want to place and size it differently, but I hope the ideas or the linked sources can get you closer to a solution
Finally I found a solution using the change event. So when I select different values I check how many values I have and then resize my chart depending on the values quantity.
Here is an example of what I used (I have 2 different pivot tables in my sheet)
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo GetOut
If Target.PivotTable.Name = "PivotTable1" Then
Sheets("PerPublication").Shapes(1).Width = (Target.PivotTable.RowRange.Count * 50) + 100
End If
If Target.PivotTable.Name = "PivotTable2" Then
Sheets("PerPublication").Shapes(2).Width = (Target.PivotTable.RowRange.Count * 40) + 40
End If
GetOut:
If Err.Description <> "" Then
Err.Clear
End If
End Sub

Excel VBA: How do you format Charts in Excel with New Data?

I'm trying to make a macro that formats a chart in Excel 2003 where the data changes. Basically, I have a 20 X values and Y values at all times; however, the values are data specific (I'm making stock price charts that will change depending on the stock I'm analying). I'm trying to make my Y-Axis cross the X axis at the value in cell B8; is there anyway to do this with a macro? Because I can't link where the axes cross to a cell. Also, I want to change the axis minimum to cell B8 as well. Also I want the macro to adjust the cart to look logical automatically depending on the data I put in there (ie logical intervals).
The chart type here is a Scatter plot, where the desription is: "Scatter with Data Points Connected by Lines Without Markers". Thank you very much.
I don't think it's possible to dynamically link the intercept value to a cell - this is just based on the fact that the UI for selecting the intercept value requires an explicit value, rather than allowing you to select a cell.
Within VBA, however, once you have read the desired value from the cell, do
ActiveSheet.ChartObjects("Chart 1").Axes(xlValue).CrossesAt = value
(with your chart name)
This is approximately what you need (no time here to test and get the details exact):
ActiveChart.Axes(xlValue).CrossesAt = Range("B8").value
You might also have to set
ActiveChart.Axes(xlCategory).Crosses = xlAxisCrossesCustom
and play around a little with whether to use Value or Category.
"to adjust the cart to look logical automatically depending on the data I put in there (ie logical intervals)."
That one is a lot of fun. Here's a VBA function that does the hard part of calculating a pretty interval between the ticks.
Public Function prettyVal( _
xMin As Double, _
xMax As Double, _
minBins As Integer) _
As Double
'' returns an aesthetic interval size to _
use for a plot axis or histogram bin. _
marc#smpro.ca 2010-09-01
Dim pretties
pretties = Array(1, 2, 5, 10)
Dim maxBin As Double ''maximum size of bin
Dim xScale As Double ''scale factor
With WorksheetFunction
maxBin = (xMax - xMin) / minBins
xScale = 10 ^ Int(.Log10(maxBin))
prettyVal = xScale * .Lookup(maxBin / xScale, pretties)
End With
End Function
You'll want to use it in a worksheet. Use the floor and ceiling of the min and max with the pretty value for significance. This makes them also pretty. Something like this in the worksheet:
minimum plot value minVal 120
maximum plot value maxVal 980
minimum num of bins minBins 10
pretty bin size binsize 50 =prettyVal(minVal,maxVal,minBins)
low axis value minEdge 100 =FLOOR(minVal,binsize)
high axis value maxEdge 1000 =CEILING(maxVal,binsize)
number of bins numBins 18 =(maxEdge-minEdge)/binsize
Enjoy.