I have a table of customers to which my company ships products. The problem is that these customers need to be sorted by their area codes, so that the products can be sent to the appropriate shipping companies (we have two partner companies that ship to certain parts of the country). Each company sent us a list of area code numbers to which they can ship and I need to divide the Excel sheet into two sheets, each containing the customers with the area codes compatible with the respective company.
I tried to solve this problem with VLOOKUP function, but it only works on individual row basis, and I need a solution that will find all rows that contain a number from the specified group of area codes.
Another way would be IF function that would put a True or False (one IF function for each company) value in new column and then I could sort by that value, and copy the data into a new sheet. This approach would work, but the IF function would be extremely long and hard to control.
Can you suggest a way to solve this problem?
Edit to incorporate details provided via Comment:
Presently I have about 5,000 rows but in future it might be more though I doubt over 10,000 rows.
A VLOOKUP seems very promising, of the kind =VLOOKUP($B2,F:G,1,0) in C2 copied across and down as required, with a layout as below:
This does not group as you say you require (but do you really need to?) because it seems possible some locations will be served by both shippers. You might resolve this by flagging those rows where both are viable and then by sorting to split into three groups (Shipper1 only, Shipper2 only, both) before transferring the ranges as desired.
Edit in response to OPs comment
If you can be certain there is no overlap between Shippers, a single column with this formula, say in E2copied down, might be preferable:
=IF(ISERROR(MATCH(B2,F:F,0)>0),"Shipper2","Shipper1")
and would not routinely show #N/A. (This assumes no area is outside the range of both shippers.)
Related
I have been searching high and low for a way to solve my dilemma, in different ways, so I am trying to post both of the things I've been trying to do:
The challenge version 1:
I want to extract the entire row with information tied to the name which is the latest entry of that name in the table. So from the table below I would want to collect the entire row which contains the information: "A, Jack Black, 01.01.2029, 10:20". I simply want to copy the entire row to another sheet. But one important factor is that it has to happen automatically.
So i need functions which can check if: Is there another entry with the same name, higher up in the table? If so, DO NOT COPY THE ROW. If there ain't another entry with the exact same name higher up in the table, COPY THE ENTIRE ROW, to another table, within another sheet.
The challenge version 2:
What I really want to do is count the number of unique people(unique names) per. department, and summarize this in another table. Basically this means that "Jack Black" should be counted as 1 person, in department A.
So the result I want, is a table looking like this (the one beneath), where the number of people does not contain any duplicate people (names). OR it does not function with a dynamic table, which updates the information it contains on the fly. I can make this happen if I am copying from a static table, but as stated above, the table is dynamic and updates with new information every minute...
So far i've tried excel's built in filtering, but this does not work automatically. I've also tried using functions like in this guide: https://excel-bytes.com/how-to-extract-a-dynamic-list-from-a-data-range-based-on-a-criteria-without-filters-in-excel/. However every solution i find seems to need criteria for filtering out duplicates or does not function when copying information from a dynamic table.
Does anyone know how to reach my desired result, without implementing criteria for selecting the rows or counting rows as stated above? VBA code is not an option at the moment :(
In advance, THANK YOU, I've really tried solving this, but I feel like this just might break my head wide open soon if I can't solve it. HEEEEELP!
Sincerely
haakonlu
nothing stuck or broken, just I am inspired after a discussion with another Excel author.
His situation:
Read from an existing Excel monster file (column FG), and hard-coded the following
Range("FF:FG").Copy
Potential issue:
data in FF:FG will be pushed to GF:GG every couple of months because newer columns will be inserted in between. (It's a pivot-like design... sorry, but end-users need this appearance, but categories are increasing, summary need to be at right end side)
He has 2 other choices (if he don't want to maintain VBA code every few months):
A: Store "FF","FG" in a Cell (fixed location!), then read the location parameter using VBA
B: Read a second dedicated CSV file (copy/paste from the monster file, consumed by another user so available readily), it only has the 2 columns required..
To me, none is obviously better than the other, just a matter of preference.
Similar but simpler Scene of mine
I produce the monstrous file by lots of Vlookup from manual data sources (inherited the design... and I refactored the design using another automation tool but there is license consideration atm).
In a column there is a formula doing something like
=if(A1="SALES PERSON SICK","void result",(if(A1="MACHINE BROKEN",C2*0.8),"")..
say 5000 rows with this formula
To reduce hard-coding I moved
"SALES PERSON SICK","MACHINE BROKEN" to a reference sheet cell A1,A2, and changed formula to:
=if(A1=Ref!$A$1,"void result",(if(A1=Ref!$A$2,C2*0.8),"")
I feel it's a good practice.
Question: Is method A or B better? Considering column position will move every ~3-6 months, still worth choosing 1 from A/B?
data in FF:FG will be pushed to GF:GG every couple of months because newer columns will be inserted in between
Then you should use named ranges in what you call "monster file" (see Define and use names in formulas) and use them in your VBA.
Eg define a name for Columns FF:FG like CopySource (use a name that describes the data in that columns) and finally you can use that in your VBA code.
Range("CopySource").Copy
Whenever the range moves because new columns are inseted before, the named range moves too, so it still points to the same data.
I made a dummy version (fake names and extremely shortened) of the 2 spreadsheets I'm working with this spread sheets
Background:
I'm automating the data between Contracts and our Accounting Team's template. Note that neither of these spreadsheet's formats can budge so that why I'm stuck. It's a clunky process that I am trying to automate. The main source of data is the "Contracts" tab. Let's say out of the 300 subcontractors projects, in the week of 1/24/2019 my coworker approved 130 of the projects. The logic of what I am trying to accomplish:
In the Contracts tab, if Column R is "Yes"--
In the "Accounting Template" tab (the one with formulas) Column B, pull all the cells of Contracts!A of the vendors we are set to pay.
The same applies to Template! (a nickname for the path) Column M, pull the specific contract ID's of the approved Contract ID's from Contracts!C.
Note I intentionally showed that my fake Puppies program is NOT approved to get their payment, this will help demonstrate how to resolve my issue
My key issue is that the Accounting Template skips every 3 rows for the Project, and the Contracts row has Project day every single row. So, for Template!A5, I am pulling data from Contracts!A2, and Template!A8 I am pulling data from Contracts!A3, etc.
I was able to (sort of) make this work with an offset, row and index match:
=OFFSET(INDEX(Contracts!$C$2:$C$167,MATCH(ROWS(Contracts!$A$2:A17),Contracts!$AB$2:$AB$167,0)),-10,0)
See that negative -10? For each new 3rd row I am starting at template, I'm manually changing it to -10, -12, -14, etc etc. Not exactly sophisticated.
Looking at how offset and row work, it looks as though they heavily rely on the coordinates of cells in the Contracts workbook. However, I ideally am looking to do this:
=IF(Contracts!R2="Yes",OFFSET(INDEX(Contracts!$C$2:$C$167,MATCH(ROWS(Contracts!$A$2:A5),Contracts!$AB$2:$AB$167,0)),-2,0))
However, once I throw a conditional (IF) in the mix, that reorientating the rows of my offset match. Are there better formulas for what I am trying to accomplish? A VBA script that could accomplish this IF, INDEX, MATCH, OFFSET, ROW dream of mine? I'm not married to either of these formulas.
I've perused a few VBAs but nothing seems to have a conditional like IF as a component.
EDIT:
Per a request, adding screenshots. There's also a Google Sheet link:
Contracts tab, purposely hiding irrelevant columns:
Accounting Template Tab:
I'd do it with VBA, but this formula example might help you start. If your issue is basically turning horizontal data into vertical data and you have a fixed interval of 3 rows. You will need to adapt the formulae for your actual set up.
The formulas used are:
F1 and down =IF(MOD(ROW()-1,3)=0,INDEX($A$1:$A$3,(ROW()+2)/3),"")
G1 and down =INDEX($B$1:$D$3,CEILING(ROW(),3)/3,1+MOD(ROWS($G$1:G1)-1,3))
I'm sure there are better ways ...
One of the reports that wastes a bunch of my time at work is the Roster. It's a multi-site, multi-contract listing of every employee currently assigned to a specific client. Currently, it has a little over 6,000 lines by 20-something columns, indexed against 3 different datasets. Not the largest mess in the world, but still a pain. And it's almost all in excel, because I somehow don't have a business case for Access.
But one part of this monster stands apart. One tab per site Site Totals, listing off every time any agent has gone through training. A second tab (again, one per site) Site Data displaying only the most recent training class, and the credentials they had during that class.
That second tab is driven by variations of this array formula - Last_Row is a named range on another tab, and column A is a pivot of the UID column on Site Totals. I've broken it apart for readability:
=IF(INDEX('Site Totals'!B:B,LARGE(($A2=INDIRECT("'Site Totals'!$A$1:$A$"&Last_Row))*
(INDIRECT("'Site Totals'!B1:B"&Last_Row)<>"")*
ROW(INDIRECT("'Site Totals'!$A$1:$A$"&Last_Row)),1))="Trainer",
"",
INDEX('Site Totals'!B:B,LARGE(($A2=INDIRECT("'Site Totals'!$A$1:$A$"&Last_Row))*
(INDIRECT("'Site Totals'!B1:B"&Last_Row)<>"")*
ROW(INDIRECT("'Site Totals'!$A$1:$A$"&Last_Row)),1)))
I know what this formula does, but I don't know how to improve it. This formula needs to be changed, because it currently is on the order of 500 Million calculations (I'm not allowed to delete historical data), and it takes me 3 hours to calculate the workbook ... if it doesn't crash Excel first.
I'm open to VBA and / or custom functions, but would prefer to have native Excel functions. I'm not able to install anything, so any solution must be native Excel, and Must be compatible to Excel 2007.
If your source is a pivot table, try is the GETPIVOTDATA function. You might be able to accomplish what you want without INDIRECT and INDEX.
What i have understood is that every person has/has not attended a training and you want to retrive the name of that training, in case he has not, you want a blank space in the cell. If this description is correct you can try this formua, press ctrl+shift+enter to execute.
=IFERROR(INDEX('Site Totals'!B$1:B$12,MATCH(A2&"Trainer",'Site Totals'!A$1:A$12&'Site Totals'!B$1:B$12)),"")
Here A2 contians the name of the person. I can be more precise with this formula if you can provide some sample data butI would recommend to not to use entire B & Columns in Site Total workssheete as this will definately slow down computing process, instead you can use B1:B8000 or smaller range, to speed up process. Hope that helps.
I'm not even sure how to ask this.
I have a database, where each row is a person. Columns are contact info, phone, etc. One column is 'date visited'. There can be multiple dates visited for each person. I don't want to use a comma or stack them all in one field.
Is there a way to have a 'nested' list (not a drop-down menu - just a list of visited dates for each person), such that one person still only consumes one single row?
Yes,
To accomplish this give each person an ID that is unique and won't change.
Then on a separate sheet, store the ID and date.
main sheet ( ID, Name, Contact Info, phone, ect)
second sheet ( ID, date visited)
In database theory this is called a 'one to many' relationship, and what i'm describing is called 'normalizing your dataset'.
In Excel you can now use formulas to manipulate the data however you need to or can imagine after you split this apart.
As you mentioned in comment, counting all visited dates for a user.
On the main sheet to the right you could use:
=countif(Sheet2!A:A,Sheet1!A1)
This would Count all of the ID's in the second sheet that match the current row's ID on your main sheet.
Notes about using one cell:
Storing all the dates in one cell will eventually max it out, and will make it hard ot view/search as it grows so i highly advise against this approach.
If however you insist on keeping the dates in there, you could count the visits by counting the total number of comma's + 1 liek this =(LEN(G1) - LEN(SUBSTITUTE(G1,",","")))+1 This formula takes the length of all the dates, and the length of dates with commas removed and subtracts them to get a number of occurrences.
Notes about using multiple columns:
This approach has the same idea as the one I suggested, where we are associating a number of dates with the row's identity of a person. However, there are a few key limitations and drawbacks.
The main difference is that when we abstract the dates by transposing them to extend vertically we can manipulate them easier, and make a list of 20 dates for one person much easier to read. By transposing the dates vertically in the second sheet instead of using this approach we also gain the ability to use Excel's built in filter. Just storing large amounts of data is useless by itself. While storing it in a way that you can view and manipulate easy makes everything much more powerful.