How to make a value based reference in Excel - vba

I have an excel sheet which fetches the values from an API and these values changes in real time, I mean the row position changes on daily basis.
Problem is when I reference a particular row to write a formula in another sheet and its value changes tomorrow I get the wrong value because it is a cell-based reference and not a value based.
How to handle such scenario?

Excel has several worksheet functions for that purpose. The most popular is VLOOKUP, where you know the column in which your value resides but not the row - precisely what you seem to explain. Google for "Excel VLOOKUP" or simply look in Excel's own Help.

Related

Excel Named Range Formula - Not Automatic Updating

I have a table in Excel that has column heading names (e.g. data_type1, data_type2, etc.). The data in this table changes based on parameters entered on another sheet, and they are pulled to charts which update dynamically.
As a convenience to a user who might be using this sheet I have added a 'user specified function' (non-vba) which also plots to one of the charts. By user specified function I mean I have three cells with dropdown lists. Two correspond to the table headings and one has a short list of operations that can be applied between the two selected data types (e.g. a user might select 'dataype1', '+', 'datatype2' which would produce a sum of the two in the final column of my table).
The user specified function is achieved by defining a named 'range/function' to match the drop downs with their respective column headers and then calls evaluate. See below:
=EVALUATE("="&ADDRESS(ROW('Raw Data'!XFD5),MATCH(user_in1,'Raw Data'!$A$4:$AF$4,0)) & user_operation & ADDRESS(ROW('Raw Data'!XFD5),MATCH(user_in2,'Raw Data'!$A$4:$AF$4,0)))
I name this 'user1_result' and then enter =user1_result in the final column of my table. This approach is nice because it calculates much faster than doing the same thing through building a UDF in VBA and then applying that UDF to every cell in a fairly long column.
Now here is my hangup, this works fine initially, but if the user makes a parameter change that affects one or both of the selected datatypes, the user specified column does not recalculate on-the-fly with the updated data. If the user re-toggles any of the dropdowns the data does recalculate. I am speculating this is from one of two things:
1) Excel does not recognize that a precedent of 'user1_result' has changed, and so for efficiency sake doesn't bother to recompute the column;
2) The 'Evaluate' function used in the named definition of 'user1_result' is not checked for updating, because it's not a normal function (doesn't show up through intellisense if you try to just add that to a cell).
So I am looking for some either confirmation or refutation of these speculations. In the case of confirmation I am hoping to get some advice on how to force the user specified column to update if its precedents change.
One solution is to have VBA do this checking for me and force the computation, but I would like to leave that as a last resort. So, non-VBA solutions preferred.
For posterity I'll answer the above question based on Mat'sMug's feedback:
Regarding the cause of the problem:
The reason the user specified column does not update is because the 'Evaluate' portion of the 'user1_result' named formula is intended to be used at the application level and not as a worksheet function. Because of this, Excel doesn't bother checking to see if its precedents change and ignores it for recalculation.
The problem's solution:
It was suggested to use VBA to watch for worksheet_change events, however, my problem requires that I do NOT use VBA. So, an alternative workaround that forces Excel to check precedents and recalculate the user specified function uses two steps. This functions as a pseudo worksheet_change stand-in.
First, I use a helper cell that performs a countif with an arbitrary counting condition. I don't need it to change, I just need it to share precedents with the inputs of 'user1_result'. So I have it count the number of cells in the first row of data that are larger than some constant:
=COUNTIF(A5:AK5,">100000")
The result of this computation doesn't matter, but in my case my data have small values and so this returns 0 always.
Second, I use a condition for the computation in the user specified column (the last column in my data table).
=IF($AO$1=$AO$1,user1_result)
Now, anytime my data table updates, the final column using the named function recomputes. Simple, and if using macros is not viable (for example due to a client/user's security concerns), this can sort of substitute for a worksheet change event.
I hope somebody out there gets use from this!

Splitting data between worksheets depending on status of Column A

I have been asked to create a database of volunteers in Excel. The main worksheet (called Data) holds all the information – names, addresses, numbers, reference checks, placements, supervisors, etc. What I am trying to achieve is for the relevant information to be moved from one worksheet to another when the status of the person changes.
There would be 5 categories which the volunteers would fall under (column A labelled ‘Status’)
PROCESSING
ACTIVE
ON HOLD
BARRED
STOPPED/RETIRED
What I want to get is a live database so the information would appear on a relevant worksheet whenever the status on the main spreadsheet changes , but I only want some information to show depending on the category…
Each Worksheet would contain columns A-F from the ‘Data’ worksheet and in addition:
Processing would contain columns X-AE
Active: AF-AW
On Hold: AZ-BC
Barred: AX-AY
Stopped/Retired:- BD-BH
I have searched and searched again but I know nothing about Macros (and my IT department is unable to help) So my question is – is this doable and if so is anyone able to help me?
I hope I am making sense and if not I can email across the dummy database with some made up names to show what it is I am trying to create
You can do this using array formulae. This link shows a simple example which provides the basic formula (explained in detail in the linked article)
=INDEX(range,SMALL(IF(col=value,ROW(range)),ROW(1:1)),COLUMN(A2))
Where range is the range of all your data from your main worksheet and value is the value you want to screen for (this changes for each of your sheets) and col is the column on your main sheet that you want to check the values of. Note it is an array forumla so you have to press control+shift+enter after typing in the formula as explained at the bottom of the link.
You will notice that I have changed the formula to say COLUMN(A2) instead of 2. This is so that you can drag the formula across the columns as well as down the rows. You might need to make this COLUMN(A2)-x where x is an offset because your data don't start in column A.
Note that the same applies for the ROW(1:1) part, if your range doesn't start in row 1 then you will need to offset this by some value as well (i.e. something like ROW(1:1)-y)

Display change in value of a cell in adjacent cell using excel VBA

I have a excel sheet that display's price on certain items in a column by looking up amazon API using excel vba. The price of may change overtime. So I am trying to display the difference in prices each time i run my macro, in a cell adjacent to the cell that displays price.
But I am not sure how to achieve this. Can any body guide me on how to achieve this?
This is just a sample, it must be adapted to your schema and data layout. Say the prices are stored in column A from A1 to A100. Say you already have a macro called RefreshData() that updates column A. In B1 enter:
=C1-A1
and copy down. This macro store the current values in column C before refreshing the data:
Sub DoUpdate()
Range("A1:A100").Copy Range("C1")
Call RefreshData
End Sub
Column B will display the price difference.
Something like this?
Let's say your data are in a range A2:A10
Dim rng as Range
Set rng = Range("A2:A10")
rng.Offset(0,1).Value = rng.Value
Run this before you run your original macro to store the values in an adjacent column before the values change. You may need to make the range dynamic, depending on your needs.
Without seeing you code, I cannot give a detailed answer. However, I ran across a similar problem once, not using Amazon API though, but a sharepoint connection.
If the amazon api is somewhat similar to the sharepoint stuff, I guess it refreshes cells when you click "update", or run the update sub. In that case you will have to either create an array to store the old prices in vba (very slow process), and then write them to your table, or create a separate tab where you store the item-lastPrice combination.
I ended up storing not only current price but all prices and the date/time of the price, to be able to see change over time.
For the copying of data itself using VBA, either of the above methods should work. In my initial code I used vba loops :-p, but copying using excel functionality is much faster.

VBA- Need help to do average rows if data present in the other columns

I have a excel sheet which we may keep adding rows/ deleting them.
And I have an average value present in some cell.I would want the excel formula to identify if there is text in another column to average the columns
So now if I insert another row, I have to manually update the average formula.
Is there a way to have a formula which check if column A is not empty, it should consider the data in column G for the average
There's a lot of approaches to this. My current favourite is a CELL:INDEX(...) expression. For instance, to find the last populated cell in the first continuously populated range between B1 and B5000, I would use (probably as a named range) $B$1:INDEX($B$1:$B$500,MATCH(TRUE, $B$1:$B$500="", 0)-1).
This approach is great because it's non volatile, so it shouldn't bog your worksheet down. It might be vulnerable to $B$500 gradually shrinking if you're only ever deleting rows, though. Alternatives are referencing the whole column ($C:$C), but that's usually dog slow in modern excel, or using OFFSET which never shrinks, but is volatile.

VBA to transfer a figure from one sheet to another based on matching values other col

I am working on a spreadsheet which is being used to transfer a product from one location to another. Each day I will have a new list of products that needs sending to another location and I already have a "pre-populated" sheet that has suitable locations listed for where these products can be sent to.
I've already worked out the formula's to use which defines the location these products can be sent to (through index and match formula) but once this has been completed, I'd like to update the "pre-populated" sheet with the quantity I'm sending these locations so that limits can be deducted accordingly.
Essentially, I want to copy the figure from column G in ("Task") into column I in ("interstore transfer") where the two "REF" columns in either sheet match. The "New Limit" column will then automatically populate with the new limit based on the figure input into Column I. Once its finished working its way down the list in the sheet ("Task") then end.
I've had a rough attempt at this, but I'm coming stuck with defining the appropriate variables and how it should update.
Any ideas to better my approach would be appreciated.
A VBA solution with variables may not be your best approach for this. Variables declared within VBA code usually have a limited lifetime based on their scope, so when the code ends the values in the variable will be lost.
Another alternative may be to set aside another cell as a counter. Perhaps a good place for this would be next to the "New Limit" column?
Cell values are retained even when VBA code isn't running. Of course cell values also are saved when the workbook saves, so when you get a new list of products at the beginning of the day you can compare to or edit the previous day's work.
To get started with this, I'd recommend getting familiar with how to reference cells and ranges. And, there is some useful information here on Stack Overflow on how to reference well in Excel VBA.