Related
Spreadsheet
So Basically i'm building a sheet to monitor my NW, my problem is simple, i need the 2023 column to adapt to whatever last number on that row there is, for income i just sum values, but for example the total amount in my bank account is different every month, i just need 2023 column to track that, i update the 31 of each month.
With the formula you can see in the screenshot i have some problem, if i input the number alright, if the value is defined by other formulas it won't show up. Any solutions?
THANKS
Only formula present in the row
Another formula from the comments that seems to not work
I tried =INDEX(X:Y;1;COUNTA(X:Y)) but it won't update if the last number in the row is generated by other formulas.
You can use this formula to find the last value of each row in the range D2:O26. Adapt it as needed!
=BYROW(D2:O26,LAMBDA(e,XLOOKUP(1,INDEX(1/(e<>"")),e,,0,-1)))
Explanation:
BYROW creates an array formula in each row of the range. To each row, here denoted as e, the specified lambda function is applied.
INDEX(1/(e<>"")) returns an array with 1 in places where cell is not empty, and #N/A for empty cells.
XLOOKUP finds the index of the last occurrence (parameter search_mode set to -1) of 1 (first parameter) in the array returned by INDEX and returns corresponding value in the row.
You haven't show what formula in columns Jan-Dec causes you problems. If formula produce values 0 in case you don't what them to count, you can use countif to filter them out:
=INDEX(D13:O13,1,COUNTIF(D13:O13,">0"))
Same as your solution, this only works if columns are filled sequentially - if there are no gaps in each row, e.g. Jan and Mar are filled while Feb is blank.
If you need a more general solution, you may go with series of nested if(isblank(). Here is an example for the first three months, to get an idea:
=INDEX(D13:O13,1,IF(ISBLANK(F13),if(ISBLANK(E13),1,2),3))
I can't figure out how to solve my issue in google spreadsheet.
I have a column with some packages we want to release on our website on specific random dates. Not all fields in these column are populated, some are empty. For the populated ones I want to assign a random number between a range (A,B) which I take from other fields and have a max number of duplicates (the number of duplicates I take from another field).
For example I have 60 packages and I need to assign them between 1 and 31 (days of current month) so that means I will have 2 duplicates/day and I will put my duplicate field value to 2. But these 60 packages are shown in 80 rows for example, 20 rows empty, so those must not have any number assigned to them.
I have tried a few solutions with RANDBETWEEN and SORT etc but I did not manage to make it work. Now I switched to writing a custom function but I have never written one in google app scripts before, so if any of you guys have experience with this I would highly appreciate.
Random dates
Use this formula to get random dates between start date and end date appended randomly and duplicated only twice.
=ArrayFormula(IF(A2:A="",,
VLOOKUP(A2:A,
{SORT({ FILTER(A2:A,A2:A<>""),
RANDARRAY(COUNTA( FILTER(A2:A,A2:A<>"")),1) },2,1),
TRANSPOSE(SPLIT(REPT(TEXTJOIN(";",1,($E$1+SEQUENCE(DATEDIF($E$1,$E$2,"D"),1,1)))&";",$E$5),";"))},3,0)))
Sort chronologically
01 - paste in G2.
=SORT(QUERY(UNIQUE(QUERY({B2:B},"Select * where Col1 is not null ")), "where Col1 is not null"),1,1)
02 - paste this formula in H2 and drag down.
=IF(G2="",,TEXTJOIN(", ",1,FILTER($A$2:$A,$B$2:$B=G2)))
I have a list of days and times in column A. Column B is a dollar value for each time value.
I want to get a specific time for each day and list the price in the next column. I have this right now:
The formula for column J is this:
=filter(A11:B,(mod(A11:A,1)*24)>=4.5,(mod(A11:A,1)*24)<=4.6)
This formula filters 4:30AM and the price associated with it.
Formula for column L is this:
=filter(A11:B,(mod(A11:A,1)*24)>=9.5,(mod(A11:A,1)*24)<=9.6)
Which filters only 9:30AM for each day and the price that goes with it.
As you can see, the dates stop matching when column J is 8/12/2021 and column L is 8/13/2021. This is because column L didn't have 9:30AM for 8/12/2021 so it skipped to 8/13/2021.
How can I make so that one of the columns skip a date if the other column doesn't match that time? I don't know if I explained that well but in the example above, column J should skip 8/12/2021 because column L didn't have 8/12/2021.
Another way of dealing with this issue is perhaps using UNIQUE and FILTER formulas but I'm not sure how that could be done. Any help would be greatly appreciated!
Here's a link to the spreadsheet: https://docs.google.com/spreadsheets/d/1TvP0_UsYJbLb5bscx2e4nTEnSkP5roBZpP8aIGdl414/edit?usp=sharing
I'm not 100% sure, but if you need to filter values so the time element is 09:30 and 04:30, then hide values where a date only occurs once (ie. no 09:30 value or no 04:30 value), you could use:
=arrayformula(filter(
filter(A11:B,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5)),
countif(int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))),int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))))>1)
)
Adjust >1 at the end to whatever logic you need (=2, <>1 etc).
You can also add sort() around everything if you need to.
Explanation:
It turns out that mod(A11,1)*24 doesn't round particularly well, so I suggest round(mod(A11:A,1)*24,2).
Therefore to filter the date/times for 9.30am and 4.30am, you can apply:
round(mod(A11:A,1)*24,2)=9.5
and
round(mod(A11:A,1)*24,2)=4.5
like this:
=arrayformula({filter(A11:B,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))})
filter is usually AND but to get OR condition it's filter(A:B,(A=1)+(A=2))
This gets the dates only:
=arrayformula(int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))))
Then this counts how many times a date appears:
=arrayformula(countif(int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))),int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5)))))
Combining the elements gets the solution.
I'll add a tab to your sheet.
You could filter each list on finding a match for each date (integer part of datetime) in the other list:
In J:
=filter(A11:B,(mod(A11:A,1)*24)>=4.5,(mod(A11:A,1)*24)<=4.6,isnumber(match(int(A11:A),int(filter(A11:A,(mod(A11:A,1)*24)>=9.5,(mod(A11:A,1)*24)<=9.6)),0)))
In L:
=filter(A11:B,(mod(A11:A,1)*24)>=9.5,(mod(A11:A,1)*24)<=9.6,isnumber(match(int(A11:A),int(filter(A11:A,(mod(A11:A,1)*24)>=4.5,(mod(A11:A,1)*24)<=4.6)),0)))
Note
Plz see Aresvik's answer for a possibly better approach to rounding, but note that 4:30 (3/16) actually has an exact representation as a binary decimal so rounding errors aren't an issue here.
I'm using Google Sheets to create a financial record.
What i'm trying to do is create a formula that takes 3 columns in my data range in to consideration. The three columns are a date, a word and a number.
The first part of the formula will check that the date is the current month (not within 30 days, but the current month). The second part will check whether the word "Yes" is present in the second column, and if those two are true, then it will take the average of column 3 for all other rows that are also completely true.
Column C is Date
Column W is Word
Column Y is Number
I've tried a number of methods, the first one was to use a average IF function, where i used a filter to check the dates, and then the word Yes in the criterion. This resulted in a number, although it was incorrect, as the formula first gathered the sequence of Yes and No's, once it had the sequence it applied it to the third column but it started from my earliest entry (not my current month). This code is below.
So alternatively i tried another method. Which was using a query function. Although i'm stuck on how to compare the month of a date to the current today() month. This gives no results, even though the current month is 8, and the dates month is also 8. I've also inputted this code below.
=AVERAGEIF(filter(W8:W800,month(C8:C800)=month(today())),"Yes",Y8:Y800)
=query(query(A8:Z800,"select month(C)+1, W, Y where W ='Yes'",0),"select Col1, Col3, Col4 where Col1 ='"&month(today())&"'",1)
results explained in background
Your nesting is a bit off. If you're using FILTER, use plain AVERAGE instead of AVERAGEIF, and make sure you're grabbing the right column to aggregate. Lastly, don't forget to wrap in IFERROR to handle your empty case.
=IFERROR(AVERAGE(FILTER(Y8:Y800, MONTH(C8:C800)=MONTH(TODAY()), W8:W800="Yes")), 0)
if you have multiple criterions you need to use AVERAGEIFS instead of AVERAGEIF
=ARRAYFORMULA(AVERAGEIFS(C2:C, B2:B, "yes", MONTH(A2:A), MONTH(TODAY())))
I'm writing a spreadsheet to keep track of a small business' financials. They operate a few Rooms for rent, and the structure of the document is made so that each sheet holds a year's worth of booking for all the rooms.
Essentially, each row is defines a specific date, while each rooms spans a few columns (reason is that they don't just want to track whether or not a room is booked, but also record names of clients & other remarks), among which the daily calculated income (some factors alter the daily rate each room will generate).
So this is all fine and dandy, and I've created named ranges for each month of the year, and for each room.
For example, rows 6:36 will represent the month of January, while columns C:I will represent Room 1. Room 2 will span J:P and so forth.
Now, in another sheet, I wanted to make a dashboard which lists the earning for each room, per month. It's a very simple table with 12 rows (one for each month) and 10 columns (1 for each room) where I planned to sum up all the earnings.
So my issue is that I can't find a way to retrieve a specific column of a named range for a room ('vertical named range'), which is also limited in a named range for a month ('horizontal named range'). I had read about using ARRAYFORMULA(INDEX(named_range, ,wished_column)) but that only works for a single named range. My knowledge of these two functions being non-existent, I didn't manage to extend it to a 2-named-range version...
(I mean I did try something along the lines of ARRAYFORMULA(INDEX(January, , INDEX(Room1, , 3))) but that didn't work)
So because there isn't a one-to-one relation from the Dashboard cells to the Rooms cells, my current only solution is to manually reference everything, which you'll understand is inefficient and time-consuming...
My question, in fine, is: How can I retrieve a range that results of the intersection of 2 (or more) named ranges ? Once I have that resulting range, I know it will be very easy to use INDEX().
Define a named range Base as
A:Z
Define a range named Horizontal as
6:36
Define a range named Vertical as
C:I
Then the intersection of the vertical and horizontal ranges is given by:
index(Base,row(Horizontal),COLUMN(Vertical)):index(Base,row(Horizontal)+rows(Horizontal)-1,COLUMN(Vertical)+columns(Vertical)-1)
This can be verified by using it in a function e.g.
=countblank(index(Base,row(Horizontal),COLUMN(Vertical)):index(Base,row(Horizontal)+rows(Horizontal)-1,COLUMN(Vertical)+columns(Vertical)-1))
gives the result 7 * 31 = 217 in my sheet because I haven't filled in any of the cells.
The Offset version of this would be:
=countblank(offset(A1,row(Horizontal)-1,COLUMN(Vertical)-1):offset(A1,row(Horizontal)+rows(Horizontal)-2,COLUMN(Vertical)+columns(Vertical)-2))
or more simply:
=countblank(offset(A1,row(Horizontal)-1,COLUMN(Vertical)-1,rows(Horizontal),COLUMNS(Vertical)))
So this works well in OP's case where you have two fully overlapping ranges like this:
Partial Overlap
Suppose you have two partially overlapping ranges like this:
You can use a variation on the standard overlap formula (This is one of the early references to it as used with a date range)
max(start1,start2) to min(end1,end2)
So the previous formula becomes
=countblank(index(Base,max(row(index(Partial1,1,1)),row(index(Partial2,1,1))),max(COLUMN(index(Partial1,1,1)),column(index(Partial2,1,1)))):
index(Base,min(row(index(Partial1,1,1))+rows(Partial1)-1,row(index(Partial2,1,1))+rows(Partial2)-1),min(COLUMN(index(Partial1,1,1))+columns(Partial1)-1,column(index(Partial2,1,1))+columns(Partial2)-1)))
and the offset version is
=countblank(offset(A1,max(row(offset(Partial1,0,0)),row(offset(Partial2,0,0)))-1,max(COLUMN(offset(Partial1,0,0)),column(offset(Partial2,0,0)))-1):
offset(A1,min(row(offset(Partial1,0,0))+rows(Partial1)-2,row(offset(Partial2,0,0))+rows(Partial2)-2),min(COLUMN(offset(Partial1,0,0))+columns(Partial1)-2,column(offset(Partial2,0,0))+columns(Partial2)-2)))
I have tested this on ranges C2:F10 and D3:G11 which gives the result 24 as expected.
However, if there is no overlap, this can still give a non-zero result, so a suitable test needs adding to the formula:
=if(and(max(row(index(Partial1,1,1)),row(index(Partial2,1,1)))<=min(row(index(Partial1,1,1))+rows(Partial1)-1,row(index(Partial2,1,1))+rows(Partial2)-1),
max(column(index(Partial1,1,1)),column(index(Partial2,1,1)))<=min(column(index(Partial1,1,1))+columns(Partial1)-1,column(index(Partial2,1,1))+columns(Partial2)-1)),"Overlap","No overlap")
Perhaps the best approach in Google Sheets is to go back to the full version of the Offset call OFFSET(cell_reference, offset_rows, offset_columns, [height], [width]) . Although this is rather long, it will return a #Value! error if there is no overlap:
=Countblank(offset(A1,
max(row(offset(Partial1,0,0)),row(offset(Partial2,0,0)))-1,
max(COLUMN(offset(Partial1,0,0)),column(offset(Partial2,0,0)))-1,
min(row(offset(Partial1,0,0))+rows(Partial1),row(offset(Partial2,0,0))+rows(Partial2))-max(row(offset(Partial1,0,0)),row(offset(Partial2,0,0))),
min(COLUMN(offset(Partial1,0,0))+columns(Partial1),column(offset(Partial2,0,0))+columns(Partial2))-max(COLUMN(offset(Partial1,0,0)),column(offset(Partial2,0,0)))
))
Notes
Why did I have to introduce some more indexes (indices?) in the second formula to make it work? Because if you use the row function with a range in an array context, you get an array of row numbers which isn't what I want. As it happens, in the first formula you are not using it in an array context, so you just get the first row and column of the given range which is fine. In the second formula, Max and Min try to evaluate all the rows in the array, which gives the wrong answer, so I have used Index(range,1,1) to force it to look only at the top left hand corner of each range. The other thing is that both index and offset return a reference, so it is valid to use the construct Index(...):Index(...) or Offset(...):Offset(...) to define a new range.
I have also tested the above in Excel (where as mentioned the Index version would be preferable). In this case Base would be set to $1:$1048576.
Although in Excel you have the Intersect Operator (single space) so it's not necessary to use an Index or Offset formula at all e.g. the first example above would simply be:
=COUNTBLANK(Vertical Horizontal)
and if there is no overlap the formula returns a #NULL! error.
"I've created named ranges for each month of the year, and for each
room. For example, rows 6:36 will represent the month of January,
while columns C:I will represent Room 1. Room 2 will span J:P and so
forth."
What I suggest is that if "January" is defined for columns C to whatever (the last column of the last room), then that's all you need.
You haven't shown us the layout of the dashboard. But let's assume that at the very least you're interested in the income generated by each room.
=query({January},"select sum(Col3) label sum(Col3)'' ")
In this image, the range called "January" is highlighted. Note that it does NOT include the header. Note also that it can be many columns wide; in this example, I've just made up a few columns, but your range should cover all the columns for rooms 1 to n.
Syntax: QUERY(data, query, [headers])
Data: This formula queries the range called "January". That range can be on the same sheet, on on another sheet (such as your Dashboard). Reminder: in this screenshot, "my version of "January" is highlighted.
Query to count Number of People: "select sum(Col3) label sum(Col3)'' "
Query to sum the income earned: "select count(Col2) label count(Col2)'' "
Col2 & Col4 = Number of People for Room#1 and Room#2 respectively.
Col3 & Col5 = Income for Room#1 and Room#2 respectively.
[headers]: You can ignore them.
This formula delivers just the value of the query; even though it includes a "label", the label will not print.
Modify and adapt these formulae to create the other information required for your Dashboard.