How to add a function referencing another column to libreoffice-calc? - function

Sorry for the simple question, I was expecting this to be a 2 minute job but it has proved much trickier to figure out than I planned, and the 'Function Wizard' has been no help.
I have a spreadsheet of products (one row = one product, columns = product name | stock | RRP etc).
Column D gives cost price excluding vat, I need to add another column giving cost including vat ( column D + 20% ).
I've figured out how to add functions to, and reference specific cels, so I can do it on a cel by cel basis =SUM(D2*(1.2)) but for obvious reasons, I'd rather do this once for the column instead of doing 10k+ products one by one! What am I missing?

The "Fill Down" feature may be useful in your case:
Select the first cell holding your formula and all the cells down your sheet where the formula should get inserted;
Select Menu "Edit" -> "Fill" -> "Down", or hit CTRL+D
This will make Calc to copy the formula into all selected cells, updating the cell references (except if you have absolute references using the dollar sign).
For 10k+ rows, this may take a short time, since Calc will calculate the results, too, but it should work at least.

Related

Possible to filter SUMIF results based on if cells within a range match a specific cell?

I'm trying to automate my time tracking a bit more, and making it a bit more thorough.
Here's a link to my example that I'm working on
Basically, I want to add values in another tab based on the selection in the drop down menu, but filtered by specific weeks of the year.
Explanation:
In the C or D column of tab "Top 2023", calculate minutes based on the minutes in column G and the drop down in column C tab "2023"
Currently, I have that part working. I used SUMIF to look at column C on tab "2023", check if it matches "Work" (or "Off"), then add the hours based on either criteria.
I want to then filter that data based on the week of the year, listed in columns A in both tabs
I want to automate this so I don't need to touch it or manually select what rows are included, only to move the formula down. So if 3 rows on tab "2023" show week 1 in column A, then they're all added to C2 and D2 on tab "Top 2023", so on for the rest of the weeks of the year.
Is this possible? I was playing around with a few formulas trying to make it work (I'm still learning and researching!) in column F on the "Top 2023" tab, but couldn't quite figure it out.
I tried:
My formula to calculate the hours from tab "2023" to tab "Top 2023" is =SUMIF('2023'!C3:C,"Work",'2023'!G3:G) which works fine.
I understand doing G3:G is going to grab the whole column, so I want to filter it down further without having to manually update the G3:G portion every week.
I tried this (I know it doesn't work, and I'm having hard time understanding if it will work): =ArrayFormula(sumifs('2023'!C3:C,"Work",'2023'!G3:G)(FILTER('2023'!A3:A)A2))
Which of course brings back an error, because it doesn't work like that.
this is single cell formula + drag-down and goes in cell C2:
=SUMIFS('2023'!G3:G,'2023'!C3:C,"Work",INDEX(WEEKNUM('2023'!B3:B)),WEEKNUM(B2),INDEX(YEAR('2023'!B3:B)),YEAR(B2))
this is arrayformula within C2 (auto-applies to whole column C):
=BYROW(B2:B,LAMBDA(bx,IF(bx="",,SUM(IFERROR(FILTER('2023'!G:G,'2023'!C:C="Work",WEEKNUM('2023'!B:B)=WEEKNUM(bx),YEAR('2023'!B:B)=YEAR(bx)))))))
change 'Work' to 'Off' within the formula for Colum D (time off) values
also took into account direct 'Date' Columns in both tabs instead of
the helper columns created exclusively to extract WeekNumber.

Array Formula that also runs calculation on each cell's column header

I work at a school and at the end of each semester we need to total up instructional hours for each student in each class, then get the sum for the whole class. We keep our attendance on a Google Sheet each semester, so I can use fancy functions to do this. This function has worked perfectly the last couple years:
=arrayformula(sum(countifs([data range],{"","T","*all *","*no *"})))
I run this at the beginning of a row and it counts all instances where a student (or the entire class) would be counted as present, but doesn't count anything else; just like I need it (students are counted as present if the cell is left blank). I run this function on each row (for each individual student) and then run a quick sum at the bottom of the sheet and it's all good to go.
Well, this worked because our classes were all 1-hour long every day. Starting this semester, they are either 1 hour and 20 minutes or 32 minutes depending on the day of the week (each class has one occurrence that is an hour twenty and one that is thirty-two minutes each week). So the above function no longer works as it just totals how many classes a student showed up for. I now need something that will do that, but also multiply the result of each cell (1 or 0) by either 1.33 or .53 depending on the day of the week. This can be done by referencing each column's header, which has the date attached and running a WEEKDAY parameter nested in an IF parameter like so (using a class that has the longer instance on a Friday for example):
(if((weekday(Z$1))=6, 1.33, 0.53))
I put that together into a function that works:
=countifs(Z2,{"","T","*all *","*no "})(if((weekday(Z$1))=6, 1.33, 0.53))
... but I will have to create a dummy column next to the column that has each date's attendance data, tailor the formula to the column next to it and copy and paste the formula all the way down the column. I should only need to change the formula once per sheet, but I'll still need to create dummy columns next to each date and then run this formula by hand on each column. After all that, then I can sum up each row. It works... but I want something less time-intensive and prone to error.
What I am hoping for is a function that does what I have now (for single cells), but runs each portion of this function on each individual cell across an entire row of data after I add it to the beginning of the row and then, preferably, sums up the total hours at the end (should just be able to add a SUM parameter to the beginning of the function?); all in a one-cell function. I have tried using an array like I had before (in the first formula above), but the problem there (there's probably more than one problem), is that I can't get the function to reference each cell's header and run the IF function, I can only get the array to work on the COUNTIF portion of the function. Maybe this whole thing needs to be a script instead?
I hope what I am asking for makes sense and here is a link to a sample of the data I am using:
https://docs.google.com/spreadsheets/d/12fTE_AMlKtlqc_KToYB5TkvpYwFzON9Q6vvRfnDlr0A/edit?usp=sharing
Thank you for reading and I hope there is a reasonable solution to what I'm asking!
try:
=INDEX(BYROW(B2:N15, LAMBDA(x, SUM(
REGEXMATCH(x, "^$|no .+|all .+|T")*
IF(WEEKDAY(B1:N1)=6, 1.33, 0.53)))))

Countif Formula to exclude Duplicates

I sought help regarding this once, but I failed to outline my problem.
This time I am happy to share the sheet with dummy data in hope it explains my problem a bit better: Link to the sheet
My issue is the following:
In column E I am counting the number of opportunities for a rep (listed in column A). The data I am considering is in a separate sheet named "Pipeline".
I do this with the countif formula and I use additional criteria to filter on date as well. My dates for february are in B4 and G4, because I only want to see opportunities in February.
My formula looks like this:
=countIFS(Pipeline!$A:$A,$A7,Pipeline!$F:$F,">="&$B$4,Pipeline!$F:$F,"<="&$G$4)
This works perfectly fine. However, sometimes I have two opportunities in my pipeline sheet with the same name (these are split opportunities). If an opportunity has the same name it should be counted only once. I can't seem to find an easy way to update my countif formula.
In the dummy sheet I shared above, you can see that Peter has two "New - CC Tech" opportunities. I want this to count as one opportunity. Everything I googled so far suggests using rather complex formulas, which is not so easy as I have multiple criteria in the formula that I need to filter my results (such as name of the rep and dates). Please feel free to suggest a solution within the sheet above and play around with it.
I really appreciate the help!
Try this ('unique' based on A,B and F)
=query(unique({Pipeline!A:B,Pipeline!F:F}),"select count(Col1) where Col1='"&A7&"' and Col3>=DATE'"&TEXT($B$4,"yyyy-MM-dd")&"' and Col3<=DATE'"&TEXT($G$4,"yyyy-MM-dd")&"' label count(Col1) '' ")
or, if you consider that the date could be different between two lines ('unique' based only on A and B, the date could be different but within the limits)
=query(unique({Pipeline!A$2:B,arrayformula((Pipeline!F$2:F>=$B$4)*(Pipeline!F$2:F<=$G$4))}),"select count(Col1) where Col1='"&A7&"' and Col3>0 label count(Col1) '' ")
In this second formula, we construct a matrix with A, B and 0/1 (which is the result of the question: is F within limits), then we apply unique and we query when Col3 is equal to 1 and Col1 the name we are looking for

Find Row Where Sum is Reached from Single Joined Column (not a range of cells)

I'm trying to run a formula to identify in which row a total sum is reached.
I've been able to do that calculation when I have an entire range of cells to work with, however, I'm doing a filter / join calculation because I need to do this from an individual row with all the data instead of an entire range of cells.
Here is an example google sheet (EDITABLE - feel free) where you can see the range and working formula (both below). Help getting this from the single-cell versions on the top would be very helpful. The error I get with both row() & index() formulas is that the "argument must be a range".
If there's another way to do this besides the single-cell I had that doesn't require referencing the range (e.g. using FILTER) then I'm open to it.
My desired result is to be able to pull the get the second column (date) at the point when the sum is reached (can be via the INDEX & MATCH formula I used or an alternative). This will tell me the earliest date that feeds into the desired sum.
Yes unfortunately you can't do that trick with SUMIFS to get a running total unless the column being totalled is an actual range.
The only approach I know is to multiply successive values by a triangular array like this:
1 0 0 ...
1 1 0 ...
1 1 1 ...
so you get just the sum of the first value, the first 2 values, then 3 values up to n.
This is the formula in F5:
=ArrayFormula(match(E14,mmult(IF(ROW(A1:INDEX(A1:ALL1000,COUNT(split(A5,",")),COUNT(split(A5,","))))>=
COLUMN(A1:INDEX(A1:ALL1000,COUNT(split(A5,",")),COUNT(split(A5,",")))),1,0),TRANSPOSE(SPLIT(A5,",")))))
And the formula in F6 is just
=to_date(INDEX(TRANSPOSE(SPLIT(B5,",")),F5,1))
EDIT
You might have guessed that the above formula was adapted from Excel, where you try to avoid volatile functions like Offset and Indirect.
I have realised since posting this answer that it could be improved in two ways:
(1) By using Offset or Indirect, thus avoiding the need to define a range of arbitrary size like A1:ALL1000
(2) By implying a 2D array by comparing a row and column vector, rather than actually defining a 2D array. This would give you something like this in F5:
=ArrayFormula(match(E14,mmult(IF(ROW(indirect("A1:"&address(COUNT(split(A5,",")),1)))>=
COLUMN(indirect("A1:"&address(1,COUNT(split(A5,","))))),1,0),TRANSPOSE(SPLIT(A5,",")))))
which could be further simplified to:
=ArrayFormula(match(E14,mmult(IF(ROW(indirect("A1:A"&COUNT(split(A5,","))))>=
COLUMN(indirect("A1:"&address(1,COUNT(split(A5,","))))),1,0),TRANSPOSE(SPLIT(A5,",")))))

Analyze sheet data to create a summary of values

I have a spreadsheet for employee schedule (you can see a demo in the link below). As you can see in the "original table", I have 2 rows per day and columns for every shift (Shift A, Shift B ... ).
DEMO SHEET
I need to "reverse" the table, extracting every shift for any employee (as you can see in the right side of the demo table "calculated table").
I don't think it's possibile with normal formulas, I tried with JOIN formula and some IFs but it's not a working solution in my opinion.
Any idea on how can I write a custom formula in Google App Script? Do you know any workaround with formulas? Can you tell me where can I found some examples?
Notice that, sometimes, employee can have two shift in a single day.
J7:
=ARRAYFORMULA(TEXTJOIN(" ; ";1;IF(OFFSET($A$5;MATCH($I7;$A$6:$A$25;0);2;2;3)=J$6;$C$5:$E$5;)))
DragFill down and out.
OFFSET to offset the date to 2x3 Data array for the MATCHed date
IF to get Header Rows
TEXTJOIN to Join results.