I am trying to use an arrayformula to join a string of cells in the same row as per picuture. This formula needs to automatically copy down to any new rows that are added. The formula I have so far seems to be the only one that returns at least something. I have googled and tried all sorts of join, textjoin to eliminate delimiters when a cell is empty but I keep getting all sorts of errors.
Also, note in column L I only want part of the cell, the city name, not state and zip code, which is why I added the Left function.
I would also like a header in row D1 "Summary".
Also, another problem I am having with the Arrayformula, is that any new rows that are submitted by my script, get pasted way down the bottom of the sheet, skipping blank rows. I think it sees the array formula as part of the last row even though those rows are blank. The only workaround I have so far is to delete all empty rows after my table, so I have the little [add 1000 more rows at bottom] after my last data row. But this then effects the filter range. The filter range does not seem to update automatically when new rows added. Maybe I need to address each of these issues as a new question in Stakoverflow?
Jobs Database
Delete everything from 'Jobs Database'!D:D (you can always undo it if you aren't happy with the formulas proposed). Then place one of the following two formulas in D1, though I recommend the second of the two.
The following formula will produce results in keeping with what you showed in your post and what is currently in the sheet (though my formula creates a cleaner result, because it addresses more potential issues than your original formula):
=ArrayFormula(FILTER(IF(ROW(A:A)=1,"Summary",B:B&IF(C:C="",," - "®EXREPLACE(TO_TEXT(C:C),"^-",""))&" - "&IF(H:H="",,H:H&" x ")&G:G&IF(I:I="",," - "&I:I)&" - "&IF(J:J="",,REGEXREPLACE(J:J,",$","")&" - ")&IFERROR(REGEXEXTRACT(L:L,"(.+)[\s\w]{8}")&" - ")&"ID: "&A:A),A:A<>""))
This formula is written to accommodate the fact that you've got column-level sorting in place. The FILTER clause surrounding everything inside also assures that the results only run as far down as you have data in Column A. This should eliminate the issue you were having with new rows being added after blanks.
I recommend the layout produced by this second formula, however:
=ArrayFormula(FILTER(IF(ROW(A:A)=1,"Summary",B:B&IF(C:C="",,CHAR(10)&TO_TEXT(C:C))&CHAR(10)&IF(H:H="",,H:H&" x ")&G:G&IF(I:I="",,CHAR(10)&I:I)&CHAR(10)&IF(J:J="",,REGEXREPLACE(J:J,",$","")&CHAR(10))&IFERROR(REGEXEXTRACT(L:L,"(.+)[\s\w]{8}")&CHAR(10))&"ID: "&A:A),A:A<>""))
In my opinion, the use of line breaks between information is cleaner and therefore easier to read.
Both formula options would require selecting all rows, right clicking, choosing "Resize rows" and selecting "Fit to data" for full viewing.
I have added two sheet ("Erik Help 1" and "Erik Help 2") with each of the above formulas in place, respectively).
Related
I'm trying to work on a Google Sheet and make it as user friendly as possible, so when I'm not around others can't screw it up. I have previously copied the formula down the column, but I'm trying to do it in an array formula, that is in the header of the column so people don't need to copy the formula to other cells.
The formula is simply a VLOOKUP, comparing a cell to the left with the code, and retrieving the title and other information later. (I've had this working happily via copying the formula down the column.)
VLOOKUP($F$2:F, 'Lessons NEW'!$E$2:$F,2,false)
My problem comes when trying to do this using an array formula in the header. This also works properly, but doesn't allow me to do somethings needed.
={"Title";
ARRAYFORMULA(
IF($F2:$F<>"",
VLOOKUP($F$2:F, 'Lessons NEW'!$E$2:$F,2,false),
)
)}
Again this works happily.
HOWEVER. my issue is that on some rows I need to manually enter some info.
What I want to happen, is rows in the column that have data, in the array formula's destination to get skipped over and simply ignored during the array formula's output and end up containing what's been manually entered in them. (Some rows in the column will just be random manual entry stuff)
I've tried doing this via checking if there is a code in the cell to the left, and try to make it skip if so, or check if the destination cell has contents already and skip if so. but it seems that if I have anything in the output area of the array formula, it breaks it completely.
Does anyone have any suggestions of how I can accomplish this? Thanks!
Unfortunately there's no direct solution within ARRAYFORMULA. If you can, and ideally there are no in between rows added, you can add a column to the left to be hidden, and contain the formula adapted:
={"",VLOOKUP($F2, 'Lessons NEW'!$E$2:$F,2,false)}
Without ARRAYFORMULA it will be able to expand at any row that doesn't have a handwritten value. You may also protect that whole hidden column (that will mean also that no in between rows will be added by noon authorised people, may be also useful for you)
UPDATE
Sample script for copying the formula. Adapt the ranges and name of the sheet:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
SpreadsheetApp.getUi().createMenu("Custom")
.addItem("Copy Formula","copyformula")
.addToUi()
copyformula()
}
function copyformula(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sh = ss.getSheetByName("Sheet3")
var range = sh.getRange("D1")
range.copyTo(sh.getRange("D2:D"))
}
what you describe contradicts the intended usage of arrayformula. arrayformula is designed to roll out and for that, it needs an empty space. any manual input in that empty space will render the arrayformula out of the game. there are only two solutions for your issue:
not use arrayformula but VLOOKUP formula in every cell
use a script that will inject the formula only if there is no manual input
and one more hybrid solution - have your arrayformula in one column and your manual input in the next column, and then have 3rd column that will gather the data like if manual column is empty output vlookup otherwise output manual input
Collections Sheet
Expenses Sheet
Hi, I would like to get the daily sum/difference of the expenses from the expenses sheet then output to collections sheet using dates as reference/identifier.
I tried this code =MINUS(C8,INDEX(Expenses!20:31,12,2)) but I want it to auto compute when I drag the box. sorry for bad english. thank you
Desired output:
Desired Output
Output at (Net) Cash On Hand Row / Reference Date Column, the output should be August 1 Collection - August 1 Expenses.
The main issue is with the structure of your expense sheet, since you need to use only every second column. For this you can use various methods, something like
=split(substitute(join(";",Expenses!A2:DJ2),"Total:;",""),";")
The join function takes the whole row and joins it into one string, the substitute function removes the Total: from it, along with the trailing ; and the split function separates it again to separate values. This will be an array, automatically spread out to 31(-ish) columns width if entered into a cell like C10 on your Collections sheet.
Then you have two options, simply do =C8-C10 in C9, which you can drag with no problem. You can also hide the row 10 by making the text color white, or even integrate it in that sheet.
My recommendation however is not to do any of that, instead enter the formula
=arrayformula(C8:AG8 - split(substitute(join(";",Expenses!A2:DJ2),"Total:;",""),";")
into C9 on the Collections sheet and it's taken care of, without the need to drag it out. You might need to tweak it, not sure if the AG8 and DJ2 are the correct columns to end them on (should be the last column if every column or every 2 columns is a day). The arrayformula makes sure that the subtractions are done automatically for each pair of values, and expanded automatically into the row. Make sure that there are no values or formulas in D9:AG9, so it can fill up the values automatically and you don't get a #REF error.
I want to create a function that gives me a list of all the nonempty row indices in the example shown below (i.e., 3,4,6,7,8,9,12,15).
After that, I want to select, for example, the third number in this list (i.e., 6).
I can't figure out how to make it happen (I am still fairly new to Google Sheet formulas), so very thankful for your help!
Sheet example:
It is not quite clear to me what you need.
I think you are asking for the # of the 1st row below 3rd empty row
=SMALL(ArrayFormula(IF(B1:B="",,ROW(B1:B))),3)
You can also find the # of empty rows using:
=ArrayFormula(IF(B1:B<>"",,ROW(B1:B)))
Change it to the following to get a list of non-empty rows
=ArrayFormula(IF(B1:B="",,ROW(B1:B)))
In any case, I have also included a couple more useful formulas
the # of the 3rd empty row
=SMALL(ArrayFormula(IF(B1:B<>"",,ROW(B1:B))),3)
and finally, the row content of the above formula
=INDEX(B1:B,SMALL(ArrayFormula(IF(B1:B="",,ROW(B1:B))),3),1)
(if still facing issues, do let us know)
I have a QUERY that seems to be treating AND more like OR. In other words, when the value of Col11=TRUE and the value of Col12=7, the results are displayed as though Col12=8. Am I missing something? I've tried adding quotes around the variables, parentheses around the two criteria. Adding spacing around the =. What else is there?
Col11 is only TRUE or FALSE values and Col12 is only numeric values from 1-8.
=QUERY({$A$3:$AJ},"SELECT Col3,Col10 where Col11=TRUE and Col12=8",0)
Here's a link to my sheet. It's buried in a larger formula in AK2
AK6 is a good example. It shows U U. It should only show U. It is treat X6 as though it's value is 8 when it is actually 7.
I believe I worked out what is happening.
You are getting two 'U's because I think your inner array is returning multiple rows for Col3='R2-D2', one row where Col23=TRUE and Col24=8, and then another row where Col27=TRUE and Col28=8.
I'm not positive, but I think the values in AK don't relate specifically to the values in that specific row, but instead relate to an array queried across all of your data rows. So as the outer ArrayFormula works down the column, the inner array (with multiple VLOOKUP/ArrayFormula/Queries) is still a large subset of the whole data range. That's assuming I've understood your complex formula correctly - my apologies if I've misunderstood something.
I've added a Heroes-TEST sheet to your sheet. It only has ten rows, all of the R2-D2 data from your Heroes tab. The columns are collapsed for visibility. See what happens when you highlight all the row data below Row3 and press delete - and then UNDO. The two 'U's in column AK become one, because there is only one row of data to query through now.
Your original formula is in AK2.
Let me know if this has helped.
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.