Change the order of table column in Excel - excel

Well, its probably not bit easy anymore still here it comes.
I want to order the column with table content in Excel in specific order.
i.e I want all the columns with Prefix ('Product'/'product') to come at end in alphabetical order except 'Product_ID' to be first among them and everything else remains the same.
i.e Demo
Cust_ID | Name | Product_Quantity | product_Name| Product_ID | Price_per_quantity
1 | Rohit | 4 | Pen | A23 | $2
2 | Tim | 3 | Pot | P41 | $3
to
Cust_ID | Name | Price_per_quanity | Product_id | product_Name | Product_Quantity
1 | Rohit | $2 | A23...(respective columns data)
I wish to have a generalized way for n columns (with/without) using VBA script which contains more columns.
Also (2nd question) To reverse the columns irrespective of there value which is solved by fellow SO members.

Assuming a is in A1, insert a row at the top and populate with:
=COLUMN()
copied across above all populated columns. Select all populated columns and sort by Row1 Largest to Smallest.

Follow these steps
Insert a top row for dummy purpose with values 1, 2, 3, 4
Copy all data including this dummy row -> paste special -> transpose in some other location
Sort the transposed data using "Largest to smallest" with "Expand" option
Now again copy the data, this time without the first dummy column -> paste special -> transpose.
Phew...
Picture attached.

Select the Cells you want to sort. Right Click on them, choose Sort -> Custom Sort
Click on Options and choose Left to Right. And set the settings as in the picture:
And press Ok.

This answer is an addendum to the response given by #pnuts, which, if possible to use, is far simpler. If you cannot sort by column for some reason, one way to achieve your result is to take the transpose of the input (i.e. swap rows and columns), sort alphabetically by row, then transpose back to get the original format. Here is a step by step guide for how to do this:
Highlight a 4x3 region of the spreadsheet where you want the transposed data to go. Then enter a transpose array formula, which is =TRANSPOSE($A$1:$D$3) in the example above. Note carefully that the cell ranges are absolute ($) so that it doesn't change as Excels copies it over the range. Also remember to press CTRL + ALT + ENTER, rather than just ENTER, to tell Excel that you are entering an array formula. Next copy this data to a new location (values only), and sort in descending order by the letter column:
The final step is to take the transpose of this sorted data to obtain your final result:
Again, this involved using the TRANSPOSE function with an array formula.
Now you have your original data sorted by column.

Related

named range using an if statement with array formula for dependent dropdown

Stumped after looking for a bit...
I have a spreadsheet with items like so:
A B C
+------+----------------------+--------------+
| Code | Desc | Type | 1
+------+----------------------+--------------+
| 1 | Main item | Activity | 2
| 1.1 | Sub item | Sub-activity | 3
| 1.2 | Another sub item | Sub-activity | 4
| 2 | Another main item | Activity | 5
| 2.1 | Yet another sub item | Sub-activity | 6
+------+----------------------+--------------+
I want to create a dropdown based on Activity. I can do this in a typical cell (with ctrl + shift + enter for array formula):
={if(c2:c6="Activity",a2:a6,"")}
But I can't figure out how to put that formula into a named range properly. When I hit ctrl + shift + enter, no braces appear. When it's without braces, it doesn't seem to work, either (it shows the value as {...}).
Is there a way to make this work?
Thanks in advance
In the end, this wasn't possible via a named range; I ended up doing a variant of dependent dropdowns with offsets as well as two pivots, based on the blog page from Darren's comment above as well as this link. May be overkill, but at least I know how I got to it.
Setting up the first dropdown data source and data validation for the dropdown
For the first list, I created a pivot from the dropdown data source with row of column "Type" and values of count "Type" (the values aren't that relevant, but I found it useful to just know how any elements to expect for later dependent items). This pivot is in the standard default pivot location on a new sheet, where the header row starts on A3. Using a pivot also sorts it by default alphabetically (which I wanted). Turn of all total columns.
I then created a named range ("costCategory") with the following formula:
=OFFSET('PivotSheet'!$A$4,0,0,COUNTA('PivotSheet'!$A$4:$A$100),1)
That basically makes a list of the items and removes any blanks. It's not as dynamic as I'd like, but I think it's very unlikely I'll ever get beyond ~100 items on the list so I decided to live with it.
I created another named range ("emptyList") with the following formula:
={""}
So that I could also lock the first dropdown if the second, dependent one is selected (to prevent weird non-matching data issues).
For the table rows that needed the dropdowns, I put in the data validation for a list with this formula:
=IF(ISBLANK($B3),costCategory,emptyList)
where $B3 is the second, dependent dropdown location.
Setting up the second, dependent dropdown data source and data validation
5. I created another pivot from the same data source, with rows of "Type" and "Desc", and values of count of "Type" (again, the values not a big deal). The pivot layout was set to tabular, repeating labels, no totals or subtotals. I put this pivot next to the other one, with the first header row starting at E3. It also alpha sorts.
I put in helper columns to determine where the list starts for a particular parent of the dependent dropdown, and the number of rows of that list. It uses the same arbitrary long ranges approach as in the first dropdown - just put in a number of rows unlikely to be exceeded in the pivot. In col C, for getting the first row where the dependent data starts, I put this formula:
=ROW(INDEX('PivotSheet'!$F$4:$F$200,MATCH($A3,'PivotSheet'!$E$4:$E$200,0)))
In col D, for getting the number of cols where there is dependent data, I put this formula:
=(LOOKUP(2,1/('PivotSheet'!$E$4:$E$200=$A3),ROW('PivotSheet'!$F$4:$F$200))-ROW(INDEX('PivotSheet'!$F$4:$F$200,MATCH($A3,'PivotSheet'!$E$4:$E$200,0))))+1
Finally, in the column with the dependent dropdown (col B), I used the following data validation rule:
=OFFSET('PivotSheet'!$F$1,$C3-1,0,$D3,1)
Which basically takes the range that's found in the helper cols to make the dropdown list.
When these formulas are extended, they increment (A3 to A4, B3 to B4, etc.) so that they all still work even as you add rows to the listobject table.
Create a helper column in column D and write simple formula
=IF(C2="Activity",A2,"")
Once you have column D , you can create a list from column D ignoring the blank cells which is what you want.
P.S. If you're not concerned about the blank cells use the formula in column E2 and drag below which will give you consecutive values that you want to see in your list.
=IFERROR(SMALL($D$2:$D$6,ROW()-1),"")

Return all the cell whose next one contains a value range

I need to return in a cell all the cell values where the cell next to it contains a value range.
For example, if I have a table like this:
|Name |Evaluation
|------|------
| John | 3
| Sue | 4
| Jim | 2
| Andy | 6
| Tim | 1
| Bruce| 4
I'm looking for a formula to have all the names whose evaluation is >= 4, so, if applied to the table it should give as output in a single cell:
Sue
Andy
Bruce
I've already tried VLOOKUP, INDEX, MATCH and FIND functions but they all return a single value (the first cell that match) and not all of them.
If possible, I'm looking for an Excel Formula and not for VBA (this way I can share it easily with my working group that, as myself, is not very proficient in VBA).
Thank you very much!
=IF(B1>=4,A1,"") write the command in c1 column and drag the C1 column to the end of the column till the end name
(assuming you write first name in A1 column and Evaluation in B1 )
I've solved the issue by using (partially) the solution posted by dhS and a support table.
I've created the support table of the same height of the original one. This table goes from F1 till F120 (the end of the original table).
In the first cell i've used the formula
=IF(B1>=4;$B1;"")
In all the subsequent cells (from the second to the final one)
=IF(B2>=4;IF(F1="";B2;F1&CHAR(10)&B2);F1)
This way, in the last cell there will be all the names separated by a return (CHAR(10)).
To anyone who want to use this solution, remember to enable the Wrap Text option on the cell, otherwise you won't be able to visualize the returns.
Thanks to everybody for the help you gave me.

Retrieve unique counts in excel

I'm looking to create a formula that counts the number of sign ups for a given day. My input data is based off an event log, and looks something like this:
AccountName | SignUpDay | EventLogged
acct1 | 06/01/2016 | 06/01/2016
acct1 | 06/01/2016 | 06/05/2016
acct2 | 06/01/2016 | 06/02/2016
acct3 | 06/01/2016 | 06/04/2016
acct3 | 06/01/2016 | 06/06/2016
acct4 | 06/03/2016 | 06/06/2016
The above is dummy data. But lets say I have 10k lines for my input data. For my output, given a specific day I want to look at the input data and return the number of signups for that particular day. What I want to achieve is something like this:
SignUpDay | Count
06/01/2016 | 3
06/02/2016 | 0
06/03/2016 | 1
I know I could probably do something like this in R, but I'm working within what I have right now, which is excel. Anyone have any ideas on how to achieve this?
With Excel's FREQUENCY() and an Array formula:
Assuming
your sheet is set up with AccountNames in A2:A100
your SignupDates are stored in B2:B100
the current Date you want to subset for is in F2
then enter:
=SUM(IF(FREQUENCY(MATCH(IF(B$2:B$100=F2,A$2:A$100,""),IF(B$2:B$100=F2,A$2:A$100,""),0),MATCH(IF(B$2:B$100=F2,A$2:A$100,""),IF(B$2:B$100=F2,A$2:A$100,""),0))>0,1))-1
and press CTRL+SHIFT+ENTER to enter this as an array formula.
With your list of sequential dates in, for example, F2:Fn, you may try this array-entered formula:
G2: =SUM(1/COUNTIF(AccountName,AccountName)*(SignUpDay=F2))
AccountName and SignUpDay should refer only to the existing data range (no blanks). If there are blanks, a more complex formula would be required. If you use a table, with structured addressing, the names can adjust automatically.
Also, the formula assumes that the same account will not sign up on more than one day. If that might be the case, a more complex formula would be required.
eg:
=SUM(1/COUNTIF(SignUpTable[[AccountName ]],SignUpTable[[AccountName ]])*(SignUpTable[ [ SignUpDay ] ]=F2))
To array-enter a formula, after entering
the formula into the cell or formula bar, hold down
while hitting . If you did this
correctly, Excel will place braces {...} around the formula.
EDIT: If your data does not fit into the above constraints, I would suggest one of the solutions linked to by #pnuts, in his comments, where you add an additional column to your data with the formula:
=IF(SUMPRODUCT(($A$2:$A2=A2)*($B$2:$B2=B2))>1,0,1)
and then construct a Pivot table with SignUpDay in the Rows area, and this new column in the Values area. A disadvantage of the Pivot Table solution is that dates with zero signups will not be represented in the table.
In Excel 2013+ it is possible to generate Unique Counts in the Values area, but you mentioned you are using Excel 2010, so that is not a possibility.

I want to give an ID to each row. How do I do this with a formula?

I want each row in the table to have unique number.
Here is my story:
1. I create table and give IDs to rows - 1, 2, 3, 4, 5.
2. I sort and filter rows by values in other columns.
3. I add new row and want to give number to it. I do not see that next number is 6.
Is there any way to automate the process?
With =ROW() - but if you want the results to remain attached to the rows even with sorting it would be necessary to select Copy and Paste Special Values the IDs that have already been 'taken'.
As implied in other answers, if you use any formula to generate an ID, it will be re-evaluated whenever you modify the list (e.g. using sort or inserting a new row in the middle). To assign an ID that persists, it needs to somehow become a raw value in a cell rather than the result of a formula. Two approaches for achieving that are:
Put a formula in one column to generate IDs, but then use Copy and Paste Values to put the results of the formula into another column. Use that second column as the persistent ID rather than the first.
Write some VBA to generate an ID and place the value into the ID cell. This could then be linked to a button, perhaps labelled "Add new row".
The actual generation of a unique ID can be as simple as getting the row number or as sophisticated as an RFC4122 Universally Unique ID (see this other SO topic).
Take any empty column, for example column L is empty. Write 1 in L1 and extend it to the end of your file. Then copy and paste that column wherever you need it.
if your data looks like this:
A B
__________________________________
1 | 1
2 | 3
3 | 5
4 | 4
5 | 2
6 | ???
and you want a formula to put in A6, that would automatically be 6?
=MAX($A$1:$A5)+1

Find one cell inside a string and then populate another cell based off of that

I have a basic financial spreadsheet that I am trying to make even nicer. I have a table that looks like this:
| Description | Category | Amount
| 2341234 Chick-fil-a | Eating Out | 5.89
| 11234 Redbox/Georgetown | Entertainment | 1.21
And another table that looks like this:
| Name | Category |
| Chick-fil-a | Eating out |
| Redbox | Entertainment |
I want to find the strings from the first column of the second table in the first column of the first table and automaically populate the second column of the first table. I am pretty sure I can find the position of the string by doing a {=find(2ndSheet!A:A,1stSheetA:A)} or something of the like, but I have no idea how to populate another cell based off of that.
Does it have to be a macro?
This is a bit ugly but seems to work. It handles the situation where your description may not necessarily match the lookup table (for instance, with Redbox | Redbox/Georgetown). Replace the [Lookup_Table] with the absolute range of your lookup table, and enter as an array formula (Control+Shift+Enter):
=INDEX([Lookup_Table],MATCH(TRUE,NOT(ISERR((FIND([Lookup_Table],A2)))),0),2)
As for what it's doing:
=INDEX(
[Lookup_Table],
MATCH(
TRUE,
NOT(ISERR((FIND([Lookup_Table],A2)))),
0),
2)
It's using an INDEX formula with the [Lookup_Table] as the base range. For the row to match, it looks for instances where running the FIND formula using the current cell does not cause an error. So in the case of Redbox, you'd get an array like {#VALUE!, 7}. You then set the values to TRUE/FALSE based on whether they are errors, and then flip them so that non-errors are True. You then match the TRUE condition against that array, and a hit will return the row number in your lookup table. You then use that row number and column 2 to find the corresponding value.
Again, that is not a pretty one (and there is probably a better way to handle all of your cases), but it seems to work in my extremely exhaustive test of three rows :)
Assuming that your first table is starts in column A, substituting this formula starting in B2 should find the value for you.
=VLOOKUP(RIGHT(A2,LEN(A2)-FIND(" ",A2,1)),[Range of Helper Table],2,FALSE)
You'll need to substitute [Range of Helper Table] with the actual range. Make sure you use absolute references using $, for example: 2ndSheet!A$2:B$20. so that you can copy and paste.

Resources