I thought this should be a common thing but my search has not returned anything meaningful. I'd prefer an Excel solution, rather than VBA.
I have a proposal sheet with details like number (col D), date etc and a column saying if the proposal got converted (to business).
On the invoice sheet, I have a list of invoices. The requirement is to always refer the proposal number against which this invoice is being raised. For removing human error, the applicable proposal numbers should be available as a drop down. Hence the drop down should only show the proposal numbers against which the invoice can be issued (proposal got converted to business).
This means that non-continuous cells (say, D3, D4, D6, and D10 - where proposal converted is 'yes') from the proposal sheet should be the values available in drop down of data validation in the invoice sheet. How do I achieve this?
Edit:
Adding an image that is representative of the 2 sheets.
My solution involves creating a list using the INDEX MATCH or INDEX SMALL method to pull multiple results from the data that can be used for the dropdown.
I added a couple of extra columns to count the number of times an invoice has been invoiced and then a further Yes/No to make the index formula easier to follow. You'll see that my example only has 2 values to select from as the others have been fully invoiced.
The scary formula in Q1
=IFERROR(INDEX($A$2:$H$1000,SMALL(IF(($H$2:$H$1000="Yes"),ROW($A$2:$H$1000)-1),ROW(1:1)),1),"")
This is an array formula so you must use SHIFTCTRLENTER instead of just ENTER in the formula bar. {} backets will be added if you do it right.
To break it down, INDEX($A$2:$H$1000 is selecting your proposal data and some more rows below (1000). SMALL(IF(($H$2:$H$1000="Yes") is looking at my extra Yes/No column for "Yes". ROW($A$2:$H$1000)-1) is returning the row number minus 1 to account for the fact that our range starts at A2. ROW(1:1) is saying that we want first match in the list and the ),1) returns the vlue in the first column of the range $A$2:$H$1000.
Because ROW(1:1) returns the first result, you will need to autofill down in order to pull more results. As you do this the formula will copy down as 1:1, 2:2, 3:3...ect. I filled down to row 50 to allow for a decent amount of results.
You could set your validation range to Q1:Q50 but then you would have lots of empty space in your dropdown so, have a look at cell R1.
="Q1:Q" & COUNTA(Q1:Q50)-COUNTBLANK(Q1:Q50)
This formula creates a range based on the results in column Q. You can use that value in the data validation range by entering.
=INDIRECT($R$1)
Thus creating the dynamic range that you require.
You don't have to use the extra columns that I added but the formulas are;
=COUNTIF(M2:M1000,A2) to count the number invoiced
=IF(AND(F2="Yes",G2<E2),"Yes","No") to check if it can still be invoiced.
if you do want to use them then I'd recommend formatting your data as a table so that the formulas are copied down automatically on new rows.
Also I'd advise putting the index list on a different sheet so that rows are not deletes etc.
Related
I have a master sheet, that holds all data in a matrix form (Criteria along the top i.e. Level 0,1,2,3,4,5) and criteria along the side (e.g. Organisation, Governance, Finance, Strategy). Within the master sheet, there is data that matches these criteria, and therefore plotted in the matrix. However, there is not data for all criteria, and therefore, there are blanks.
I would like to use this master sheet as the data source, and use the same format, but i would like to divide each section (I.e. Organisation, Governance, Finance, Strategy) into its own sheet and display the data for that criteria only.
I will also want to make this dynamic to ensure that if the criteria was changed in the future, the sheets would still work.
Therefore, I am using the following formula
=(UNIQUE(FILTER('MasterSheetGrid'!D8:I8,'MasterSheetGrid'!D8:I8<>"")))
This formula works well, however the row numbers are not dynamic and the formula may break in future. Therefore, i am wanting to use the following formula
=MATCH($C6,'MasterSheetGrid'!$C:$C,0)
to search for the row number, and then use this formula or output as the numerical row number in the formula above, but i receive an error each time.
>=(UNIQUE(FILTER('MasterSheetGrid'!D" &(MATCH($C8,'MasterSheetGrid'!$C:$C,0)& ":I" &(MATCH($C8,'MasterSheetGrid'!$C:$C,0)& ",'MasterSheetGrid'!D" &(MATCH($C8,'MasterSheetGrid'!$C:$C,0)& ":I" &(MATCH($C8,'MasterSheetGrid'!$C:$C,0)& "<>"")))
Can anyone help?
You can use:
INDEX('MasterSheetGrid'!D:I,MATCH($C6,'MasterSheetGrid'!$C:$C,0),0)
to get the desired row. So then something like:
=LET(DataRange,INDEX('MasterSheetGrid'!D:I,MATCH($C6,'MasterSheetGrid'!$C:$C,0),0),UNIQUE(FILTER(DataRange,dataRange<>""),TRUE))
I am currently automating a dashboard creation and I've hit a bit of a roadblock. I need some code that will go through about 7000 rows of data and return the highest value in a certain column for each specific item. The data is copied from a pivot table and so is broken down into row sections, I have attached a mock of what it looks like.
I need the highest value in Column G for each portfolio, and will need to use the portfolio code (e.g. XY12345 - They are always 7 characters) to map that value to the dashboard.
My issue is, each portfolio has a different number of rows for the values, and some have blank cells between them, and therefore I am stumped. I was hoping to use Column J to count the number of rows for each portfolio (as there are no breaks for the portfolios in this column) and then use a loop to loop through each portfolios rows of values, based off the Column J count, and then return the highest row value for each portfolio. Problem is I'm new to VBA and have been teaching myself as I go, and I've yet to use a loop.
Many thanks,
Harry
If I understand correctly, you're looking for the largest value in Column G.
I'm not sure why you think you would need VBA for this.
Get the maximum value of a column
You mentioned that you're concerned about each column not having the same number of cells but that's irrelevant. as SUM ignores blank cells, so just "go long", or - find the maximum of the entire column.
To return the largest number in Column G you could use worksheet formula :
=MAX(G:G)
The only catch is that you can't place that formula anywhere column G or else it would create a circular cell reference (trying to infinitely add a number to itself). let's pit that formula in cell F1 for now (but anywhere besides column G would do fine).
Find the location of a value
Now that you know the largest value, you can determine where it is using a lookup function such as MATCH or VLOOKUP. Like with so many things in Excel, there are several ways to accomplish the same thing. I'll go with MATCH.
Replace the formula from above (in F1) with:
=MATCH(MAX(G:G),G:G,0)
This will return the row number of the first exact match of the maximum value of Column G.
As for the third part of question: returning the code like X12345 where the value exists, will be a little tricky since your data is not organized in a logical tabular style (tabular meaning, "like a table").
Your data is organized for humans to look at, not for machines to easily read and manipulate it. (See: Office Support: Guidelines for organizing and formatting data on a worksheet)
Basically, when organizing data in rows, all relevant information should be on the same row (not a subjective number of rows behind). Also, you have the number combined with other information.
My suggestion for a quick fix:
Right-click the heading of Column C and choose Insert to insert a blank column.
In C2 enter formula: =IF(B2="",C1,LEFT(B2,7))
Copy cell C2
Select cells in column C all the way to the "end" of your data, where ever that is (not the end of the worksheet). For example maybe you would select cells B2:B1000)
Paste the copied cell into all those cells.
Now, you can again modify the formula in F1:
=INDEX(C:C,MATCH(MAX(G:G),G:G,0))
This will return the value from Column C in the same row that the maximum value of Column G is located.
This is known as an INDEX/MATCH formula.
Hopefully this works for you in the interim until you can organize your data more logically. There's lots of related information and tutorials online.
So, I've searched for an answer to this, but I can't find anything. Hopefully some Excel guru out there has an easy answer.
CONTEXT
I have a sheet that has two columns; a list of airport codes (Col A) and a list of fuel gallons (Col B). Column A has a bunch of duplicate entries, column B is always different. It's basically a giant list of fill-up events for aircraft over time at different airports. The airports can be the same, because it's one row per fill-up event.
PROBLEM
What I want to do is have a formula that takes the enter data set, finds all identical entries in Col A, sums the Col B values for the matches, and spits out the result on a separate sheet with one entry for every set/match.
OTHER STUFF
I do not have a reference list for Column A and I would rather not create one since there are thousands of entries. I would like to just write a formula that does all this at once, using the data itself as the reference.
All the answers I find are "create a reference list on a separate sheet", and it's driving me crazy!
Thanks in advance for any help!
-rt
Sounds that you need a formula version of remove duplicated for column A, and a simple sumif for column B.
Column A
=IFERROR(INDEX(Data!A$1:A$1000,SMALL(IF(
MATCH(Data!A$1:A$1000,Data!A$1:A$1000,0)=ROW(Data!A$1:A$1000),ROW(Data!A$1:A$1000)),ROW())),"")
Array Formula so please press Ctrl + Shift + Enter to complete it. After that you might see a {} outside the formula.
Column B
=SUMIF(Data!A$1:A$1000,A2,Data!B$1:B$1000)
Just change the range for your data.
Reminders: The formula in columnA should starts from Row#1, or you have to add some offset constant for adjustments.
Since the returning value of MATCH() represents the position of the key in the given array. If we wanted it to be equal to its row number, we have to add some constant if the array is not started from ROW#1. So the adjustment of data in Range(B3:B1000) is below.
=IFERROR(INDEX('Event Data'!B$3:B$1000,SMALL(IF(
MATCH('Event Data'!B$3:B$1000,
'Event Data'!B$3:B$1000,0)+2=ROW('Event Data'!B$3:B$1000),
ROW('Event Data'!B$3:B$1000)),ROW())-2),"")
Further more, the range should exactly the same as the data range. If you need it larger than the data range for future expandability, an IFERROR() should added into the formula.
=IFERROR(INDEX('Event Data'!B$3:B$1000,SMALL(IFERROR(IF(MATCH(
'Event Data'!B$3:B$1000,'Event Data'!B$3:B$1000,0)+2
=ROW('Event Data'!B$3:B$1000),
ROW('Event Data'!B$3:B$1000)),FALSE),ROW())-2),"")
Lastly, I truly recommended that you should use the Remove Duplicated built in excel since the array formula is about O(n^2) of time complexity and memory usage also. And every time you entered any data in even other cells, it will automatically re-calculate all formulas once the calculation option in your excel is automatic. This will pull down the performance.
I am sure this question has a really easy answer, but after extensive research I have somehow not found what I was looking for. I am not an excel pro, but do have some experience with it.
Basically I have 2 sets of data that is indexed by customer account number and gives certain values, such as sales, profits, costs etc in the one file and sales rep responsible, amount of times contacted in the other file.
My goal now is to get these two files into one, so that I have the customer ID in the first column and all the data respective to that customer number in the columns next to it on one sheet.
However the customer numbers from the two sheets are not sorted in any way so I cant just copy and paste it and i am dealing with quite a large data set so I cannot just do it manually. additionally there are more customers id's in the first sheet than in the second, since some data is missing for a certain amount of the customers.
How can I basically automatically merge the data belonging to each customer so that it ends up being displayed in one row?
I recommend that you approach the merging of these two lists by creating a 3rd, comprehensive listing, which pulls from your raw data files.
Setting up your new Results Sheet
Assume that one list is in Book1, sheet1, and the other list is in Book2, sheet1. Open up a new excel file. Put the headers along the top. Next, you will create an index which shows all unique customer ID numbers, sorted by number. This will only work if there are no duplicate ID's (except for the ones which refer to the same cusotmer).
Copy the Customer ID column manually from Book1 into the New book. Copy the customer ID's from Book2 manually, underneath the Book1 customers, in the same column in the New book. Highlight the customer ID column. Go to the Data ribbon, then Remove Duplicates. Then rightclick your data and click 'sort'. This will leave you with an ordered customer ID column, and all other fields under the other headings will be blank.
Vlookup Formula
Next, you will use 2 vlookup formulas, similar to what #StaceyBurns recommends below. Vlookup takes a specific unique value, and looks for that value on the leftmost column of a datablock. Then it finds the first time there's a match for that value, and returns a value from a cell on that row, a given number of columns away. So for example:
=VLOOKUP(A1,B1:D5,2,FALSE)
Says: Take the unique value found in A1, look for that value in column B, from row 1:5, and return the 2nd column's result out of the datablock B:D (column C). So if A1 was the same as B3, this formula would provide the result for C3. FALSE means it would try and approximate your value if there's no match.
Assume customer indexes for all files are in column A. Assume also that all other headers are in the same order, let's say from A1:H1. Your formula to use VLOOKUP in the new workbook would be as follows - put this in B2:
=VLOOKUP($A2,[Book1.xlsx]Sheet1!$A:$H,column(),FALSE)
This gives you the matching amount under Sheet1's column B header, where Sheet1!'s customer ID matches the customer ID shown in cell A2 of the New book. However, we need to know whether it was able to properly pick up a value from Book1 - because we know that some data is incomplete. So, let's check if the above result is either a number, or text:
Determining if Results are found in Sheet1
=OR(ISTEXT(VLOOKUP($A2,[Book1.xlsx]Sheet1!$A:$H,COLUMN(),FALSE)),ISNUM(VLOOKUP($A2,[Book1.xlsx]Sheet1!$A:$H,COLUMN(),FALSE)))
This will return TRUE if the result is either a Number, or Text. So it will return FALSE if either no match is found for that ID number on Book1 Sheet1, or if the result is a blank cell. So now we put that inside of an IF statement - if it returns true, we want the result from Book1. If it returns false, we want to attempt to pull the result from Book2, through the exact same formula. This whole thing will look like this:
Final Formula
=IF(OR(ISTEXT(VLOOKUP($A2,[Book1.xlsx]Sheet1!$A:$H,COLUMN(),FALSE)),ISNUM(VLOOKUP($A2,[Book1.xlsx]Sheet1!$A:$H,COLUMN(),FALSE))),VLOOKUP($A2,[Book1.xlsx]Sheet1!$A:$H,COLUMN(),FALSE),VLOOKUP($A2,[Book2.xlsx]Sheet1!$A:$H,COLUMN(),FALSE))
Now, it will try to find the match from Book1 - if there's no match for the ID, or if the match returns a blank value for that header, then it will try to find a match from Book2. If it finds no match there, it will return #N/A! (which shouldn't happen, because that means you've deleted one of the customer ID's that we pulled directly from Book1 & Book2). It might return a blank cell if that data piece is not in either sheet. This formula can be copied from B2 all the way to the bottom right of your data block in your results sheet.
You can use the VLOOKUP function on the first sheet to bring the data from the second sheet in.
So for example, take an empty column on your first sheet and add the VLOOKUP function which looks like this:
=VLOOKUP(cell to lookup,
set of data on 2nd file,
column index on 2nd file of data you want,
TRUE/FALSE Boolean to ask for either close match or exact match )
If your Customer ID is in column A and your second sheet looks like this:
A1 Customer ID
B2 Sales Rep
C3 Number of Times Contacted
then you would do a look up first for the Sales Rep:
=VLOOKUP(A1,Sheet2!$A$1:$C$15,2,FALSE)
Then double click on the bottom right corner of this cell to populate the formula for all your rows.
Then do the same in a new cell for the Number of Times Contacted:
=VLOOKUP(A1,Sheet2!$A$1:$C$15,3,FALSE)
(Note I used C15 as an example in the above VLOOKUP. It should be the number of rows you have on file 2)
More info:
https://support.office.com/en-us/article/VLOOKUP-function-0bbc8083-26fe-4963-8ab8-93a18ad188a1
I am working on a project within an excel database and am trying to match 4 different properties which all have their own columns (A,B,C,D) to find a corresponding value on a different page (Sheet2!). One sheet 2 the values are once again found in their own columns (B,C,D,E) and if all of the values match I then want the value in column A Sheet2! to be displayed in column E on sheet1!
The problem is is that often times the values on Sheet1! will be able to match up with as many as 12 different unique rows on Sheet2! making this incredibly difficult with only intermediate experience in VBA. There can be duplicates that match all of the criteria. And for when this happens I would like to return the first item that matches, as long as a previous match was not made on that item.
To give you more information we have given products different values that designate where they belong based off their velocity. This has split them up into Section#, ShelvingType, Verticle, and Horizontal Location. And we are looking to match these values to the values of our previously existing locations that we have that have corresponding(matching) numbers or text values.
To go into even more detail, on sheet one we have the products with values on where they should go. One sheet two with have pre-existing locations for which products can go that have values that are represntative of that location. So, we want to take the products NEW location values off page one and match the existing location values on page two. The problem is that for every location there are up to 12products that could go there. So, we want to go in order saying that product1 goes in the first location with matched values while product2 goes in the next location with matched values, and so on and so fourth
Edited to remove previous responses
Based on your further elaboration, if I understand correctly, I agree with the comment left by #Aaron Contreras. You should create helper columns which show a 'unique ID' where all criteria match, as well as an additional helper column which increases as more items of the same criteria code are found. This will become the 'ultra-unique' ID for that item.
At this point I don't think array formulas will be possible, though I will leave in the answer which provides the result of the first matching criteria without further eliminating 'previously used' results. This could likely be further refined, but I doubt it would be more elegant than simply using the helper columns shown in my response below. At least, I can't figure out how to do it elegantly.
To summarize my assumptions:
-Your available space is in sheet1; column A contaions something like the location of that available space, and columns B-E contain criteria for anything which will be stored there.
-Your new list of items to be placed in a location is in sheet2; columnA will be where our formula goes, showing the available location to put that item.
Enter on Sheet1
In column F on sheet1, drag down this formula:
=B1&C1&D1&E1
This will create a unique ID key to be searched in the future.
However, as there will be multiple hits for the same criteria on sheet1 (because multiple locations can hold the same thing), we need to make each row 'more unique' by showing how many times that criteria combination has already occurred. This formula will thus go in column G on sheet1, starting in cell G1 and dragged down:
=F1&countif($F$1:F1,F1)
As you drag it down, this will count the nth time that the specific combination of criteria has appeared on sheet1.
Enter on Sheet2
Create the same columns in sheet2, in columns F & G. The formulas will be exactly the same, they will just refer to sheet2 instead of sheet1.
Then the formula in column A in sheet 2, dragged down from A1, would be:
=index(sheet1!A:A,match(G1,sheet1!G:G,0))
This will find the first time that all criteria match from sheet1, for the nth time that this criteria has been used on sheet 2.
Let me know if there is anything here I've missed.
Unfinished array method
Again, array responses are possible, but for your purposes likely unnecesarry; you should probably have a unique ID for all combinations anyway. However, in case you want to use the array method, you can like so (does not account for multiple locations being used; left for reference only if you want to take this up):
In sheet2, enter the following formula [confirmed with CTRL + SHIFT + ENTER instead of just ENTER, every time the formula is changed] on the row 1, with the different criteria (and copied down):
=index(Sheet1!A1:A100,match(1,(Sheet1!B1:B100=B1)(Sheet1!C1:C100=C1)(Sheet1!D1:D100=D1)*(Sheet1!E1:E100=E1),0))
This uses the inherent boolean logic of "TRUExTRUE = TRUE; TRUExFALSE = FALSE; FALSExFALSE = FALSE", to find the first row where there is a match of all criteria. Note that I have not made this go all the way down all columns, as with Array formulas this is a significant resource hog.
Assuming that your data starts from 2nd row (1st row for lables):
{MATCH(A1&B1&C1&D1,B2:B100&C2:C100&D2:D100&E2:E100,0)}
The above is an array formula, so you don't have to input the curly brackets {.
Simply press Ctrl + Shift + Enter after typing the formula
More info