Reorder/reverse column order - google-sheets

I want to change the columns order in google sheet from this:
To this
I know I can do this manually but if I have a lot of columns it's pretty annoying.
There's a simple way to do this?
Thanks in advance!

Building on the idea proposed by Steve in the comment. This works for any arbitrary range, pasted as tested on a range of columns A to D:
=array_constrain(
transpose(sort(transpose({A:D; arrayformula(column(A:D))}), rows(A:D)+1, false)),
rows(A:D),
columns(A:D)
)
Explanation: the 1st argument does the inversion magic by inserting a row of column numbers, transposing, sorting by this row in descending order and transposing back. Then we get rid of this extra row by constraining the result to the original dimensions.
The formula works and is generic enough, but it still feels like a hack. I wonder if someone can come up with a cleaner solution.

Related

Google Sheets - Calculate sum of row results - by using one-liner formula

In some column have formula like below:
=SUM(MMULT(IFNA(FILTER($H$2:$H;$G$2:$G=M2);0);L2))
I have expanded it in 3 rows (A1:A3):
=SUM(MMULT(IFNA(FILTER($H$2:$H;$G$2:$G=M2);0);L2))
=SUM(MMULT(IFNA(FILTER($H$2:$H;$G$2:$G=M3);0);L3))
=SUM(MMULT(IFNA(FILTER($H$2:$H;$G$2:$G=M4);0);L4))
And I'm getting right results.
Then I want to get sum of those. But I need to create all of above in one line.
I mean - I don't want to calculate above separately and then do something like SUM(A1:A3).
I was trying with ARRAYFORMULA() but with no success, yeah, how hard can it be, right?
Have a nice evening!
UPDATE:
If someone will look for the solution, the best one is Mike's solution. Take a look at picture what he has added.
I have just extended it to filter L and M columns and it does not matter how long columns are. Of course L and M columns have to have the same number of elements ;)
=SUM(MMULT(ARRAYFORMULA(--(G2:G=TRANSPOSE(FILTER(M2:M;ISTEXT(M2:M))))*(H2:H));FILTER(L2:L;ISNUMBER(L2:L))))
You should be able to nest the evaluations inside a SUM, like the below and get a SUM of the SUM's so to speak.
=SUM(SUM(MMULT(IFNA(FILTER($H$2:$H;$G$2:$G=M2);0);L2)),SUM(MMULT(IFNA(FILTER($H$2:$H;$G$2:$G=M3);0);L3)),SUM(MMULT(IFNA(FILTER($H$2:$H;$G$2:$G=M4);0);L4)))
There probably is a more efficient way, but why over complicate it. :)
Try this
=sum(mmult(arrayformula(--(G2:G=transpose(M2:M4))*(H2:H)),L2:L4))
the formula =arrayformula(--(G2:G=transpose(M2:M4))*(H2:H)) will give you a matrix as follows, then apply mmult

Converting a multi column range into one column

I have an instance where I would love to be able to get a column of all the unique names in a range. The problem I am having is that the range is multicolumn.
Let's assume my data is in A1:B3
This works fine if I do:
=unique({A1:A3;B1:B3;C1:C3})
But if that range is named and I do
=unique(NamedRange) or =unique(A1:C3)
Then it will spill over the column. Worse if I want to filter or sort the results in the same formula and then run into errors because the formulas want single column/row or the rows/columns don't match anymore.
I don't deal with named ranges a lot, but I did just make a formula today that had 10 columns in it that I stuck into a range like that so that I could do a complex (for me) filter that gave me the difference of two different ranges, similar to: =FILTER({B4:B93;C4:C93;D4:D93;E4:E93;F4:F93}, NOT(COUNTIF(H5:H, {B4:B93;C4:C93;D4:D93;E4:E93;F4:F93}))). I would REALLY love if I could clean that up and make that messy set B4:F instead.
Is there any formula level function that could stick these all in one column?
Usually I am looking to do other things with it like sort and filter and the multiple columns get even messier.
Thanks for your time. I DID try searching for this, but I could not seem to find the answer.
Use FLATTEN:
=UNIQUE(FLATTEN(A1:C3))
or
=UNIQUE(FLATTEN(NamedRange))

Arrayformula Unique Entries

This is the example sheet.
I'm trying to combine options together but sort out duplicates. Right now, ={"Options";ARRAYFORMULA()} is in v1!A1 because every other formula I've thought of is a lot of IF() functions stringed together going through each and every combination. Is there a better way to do this?
EDIT:
The delimiter is , , not a space.
Difficult to do as an array formula, but a fairly simple pull-down formula would be:
=textjoin(",",true,UNIQUE(transpose(B2:2)))

Is there a way to use ARRAYFORMULA to find the most-recent even input of a column?

SOLVED EDIT
Thank you for the help. Solution here.
ORIGINAL POST
I have made a google sheet to describe the issue I am facing linked here (https://docs.google.com/spreadsheets/d/1yK6ZAX8BFnEqiuQO9HIxuY0l62ewDDccj-8EN1r2i2w/edit?usp=sharing).
I will also describe in words, below, the problem I am facing, along with the solutions I have tried.
The data of column A are random single-digit (0-9). I would like column B to show the most recent even number from column A, but only up to a specific row. That specific row is the row corresponding to the row of the cell in column B. In other words, in cell B7, I want to find the most recently entered even number of column A, specifically only on the range A2:A7 (A1 contains a column header).
This is actually a pretty simple formula, and I can get the desired outputs by simply checking if the value in a cell in column A is even and then returning the value of that cell if it is, or the output of the cell above if it isn't. So the formula would look something like: ​=IF(ISEVEN(A7),A7,B6)​
However, my problem is that the length of the data in column A will be growing as more data are entered, and my current solution of using the fill handle to copy the formula to new cells is inelegant and time-consuming. So my desired solution is to use an array formula entered into the first cell of column B (B2), capable of returning the same value as the other formula. The formula I tried to enter to perform this was the following: ​=ARRAYFORMULA(IF(ISEVEN(A2:A),A2:A,INDIRECT(ADDRESS(ROW(A2:A)-1,2))))​
However, as some of my previous work with arrays has taught me, not all formulas iterate as expected down the array. The formula seems to be able to return the correct output on lines which are already even, but it is unable to return the expected most-recently entered even number for all the other lines. It appears that the formula is not able to appropriately interpret the ​value_if_false​ argument of the ​IF​ formula.
I'm a little new to scripting, so I'm still trying to learn, but I also tried to dabble around with custom functions to no avail. I'm still wet behind the ears when it comes to coding, which is why I've been so lenient on the built-in formulas of Google Sheets, but I fear I may have reached the limit of what Sheets formulas can do.
I am open to trying new approaches, but my only real constraint is that I would really like for this to be a one-touch (or even better no-touch) solution, hope that's not too far beyond the scope of this issue. Any assistance would be much appreciated.
EDIT
After rubber-ducking the problem here, I went back and tried to use the OFFSET formula, hoping I could get it to play nicely with the array formula. Alas, I was unable, but I thought I should at least post my progress here for reference.
Attempt with offset
Still working at it!
Doing a vlookup on the row number seems to work for me
=ArrayFormula(if(A2:A="","",vlookup(row(A2:A),{if(iseven(A2:A),row(A2:A)),A2:A},2)))
Note: if there are no even numbers in range for some rows, it will produce #N/A for those rows.

Stacking multiple columns on to one?

I am using Google SpreadSheet, and I'm trying to have multiple sheets containg a list of words. On the final sheet, I would like to create a summative list, which is a combination of all the values in the column. I got it sort working using =CONCATENATE() , but it turned it into a string. Any way to keep it as a column list?
Here is an example as columns:
Sheet1
apple
orange
banana
Sheet2
pineapple
strawberry
peach
FinalSheet
apple
orange
banana
pineapple
strawberry
peach
Updated Answer
I was right there is a much better solution. It's been posted below but I'm copying it here so it's in the top answer:
=unique({A:A;B:B})
Caveat: This will include one blank cell in certain scenarios (such as if there's one at the end of the first list).
If you're not concerned with ordering and a tailing blank cell a simple sort() will clean things up:
=sort(unique({A:A;B:B}))
Otherwise a filter() can remove the blanks like so:
=filter(unique({A:A;B:B}),NOT(ISBLANK(unique({A:A;B:B}))))
The following is the old deprecated answer
I'm confident that this is "The Wrong Way To Do It", as this seems such an absurdly simple and common task that I feel I must be missing something as it should not require such an overwrought solution.
But this works:
=UNIQUE(TRANSPOSE(SPLIT(JOIN(";",A:A,B:B),";")))
If your data contains any ';' characters you'll naturally need to change the delimiter.
The basic way, is just to do it as arrays like so
={A1:A10;B1:B10...etc}
The problem with this method, as I found out is that its very time consuming if you have lots of columns.
I've done some searching around and have come across this article:
Joining Multiple Columns Into One Sorted Column in Google Spreadsheets
The core formula is
=transpose(split(arrayformula(concatenate(if(len(A:Z)>0,A:Z&";",""))),";"))
Obviously you'd replace the A:Z to whatever range you want to use.
And if you want to do some sorting or removing duplicates, you'd simply wrap the the above formula in a SORT() and/or UNIQUE() method, like so..
=sort(unique(transpose(split(arrayformula(concatenate(if(len(A:Z)>0,A:Z&";",""))),";"))))
Hope this helps.
Happy coding everyone :)
You can use this:
=unique({A1:A;B1:B})
Works perfect here!
The unique() function gets rid of blank spaces, but wasn't helpful for me because some of my rows repeat. Instead I first filter the columns by len() to remove blank cells. Then I combine the columns together in the same way.
={filter(A:A, len(A:A)); filter(B:B, len(B:B))}
Much more simple:
={sheetone!A2:A;sheettwo!A2:A}
Use flatten, e.g. flatten(A1:B2). More details in this article.
If the 2d range is not in one piece, one can be created first with the ampersand or similar techniques. Afterwards flatten can be called on the resulting 2d range. The below example is a bit overkill but it is nice when working with dynamic 2d ranges, where the basic solution can't be easily used.
flatten(ARRAYFORMULA(SPLIT(ARRAYFORMULA(A1:A2&";"&C3:C4), ";")))
The article shows also how to easily unflatten a range using the, as well undocumented, skipping clause in a query.
=TRANSPOSE(SPLIT(TEXTJOIN("#",TRUE,TRANSPOSE(A:C),TRANSPOSE(D1:D5)),"#",FALSE,FALSE))
use a preferred delimiter absent in the data (instead of #) if needed
the first 1 (TRUE) parameter means IGNORE EMPTY, which is very important in this case..
the A:C and D1:D5 are the ranges to combine
all values remain there - not using UNIQUE
Try using your CONCATENATE argument with
=ArrayFormula(EXPAND(...))

Resources