How can I calculate a new date conditionally based on other information? - if-statement

I have a Google Sheet which is being populated by a Google Form. I am using Google Apps Script to add some extra functionality. Please feel free to access and modify these as needed in order to help.
Based on answers from the Form, I need to return a new date that factors in the time stamp at form submission.
This is a dumbed down example of what I need to do, but let's think of it like ordering a new car and its color determines how long it is going to take.
Car
Color
Toyota
Red
Honda
Blue
Tesla
Green
I need to write a conditional IF statement that determines how many weeks it will take to get the car based on the ordered color.
-
Red
Blue
Green
Toyota
1
3
5
Honda
2
4
6
Tesla
1
1
1
So if you order a Toyota in Red, it will take one week. If you order a Toyota in Green, it will take 5 weeks. If you order a Tesla, it will be really in one week no matter what color. Etc...
I started by writing some language in Sheets to take the Timestamp which is in Column A and add the appropriate amount of time to that:
=IFS(AND(B2 = "Toyota",C2 = "Red"),A2 + 7,AND(B2="Toyota",C2="Blue"), A2 + 21,AND(B2="Toyota",C2="Green"), A2 + 35,AND(B2 = "Honda",C2 = "Red"),A2 + 14,AND(B2="Honda",C2="Blue"), A2 + 28,AND(B2="Honda",C2="Green"), A2 + 42,AND(B2 = "Tesla"),A2 + 7)
And then I dragged that down the length of the entire column so that it would fill in as submissions came in.
However when you fill in the Google Form, it will overwrite what's in that entire row, blowing out what I had in that column.
Now I realized that the code needs to be written in Google Apps Script and returned as a value.
What kinds of modifications need to be made to my IFS statement in order to make it compatible with Google Apps Script?

For easier approach, QUERY would actually solve your issue without doing script as Broly mentioned in the comment. An approach you can try is to create a new sheet. Then have that sheet contain this formula on A1
Formula (A1):
=query('Form Responses 1'!A:C)
This will copy A:C range from the form responses, and then, copy/paste your formula for column Date Needed on column D.
Output:
Note:
Since you only copied A:C, it won't affect column D formula.
Your A:C in new sheet will update automatically, then the formula you inserted on D will recalculate once they are populated.
Add IFNA on your formula for column D to not show #N/A if A:C is still blank.
Formula (D2):
=IFNA(IFS(AND(B2 = "Toyota",C2 = "Red"),A2 + 7,AND(B2="Toyota",C2="Blue"), A2 + 21,AND(B2="Toyota",C2="Green"), A2 + 35,AND(B2 = "Honda",C2 = "Red"),A2 + 14,AND(B2="Honda",C2="Blue"), A2 + 28,AND(B2="Honda",C2="Green"), A2 + 42,AND(B2 = "Tesla"),A2 + 7), "")

Related

Dynamic Google Sheets Column + Row formula

I have a good sheet that I want to grab the header which a date time stamp which will match against another sheet find the entries with that date and suburb and type and give me an average cost.
My formula is =AVERAGEIFS(Sheet1!C:C,Sheet1!A:A, B11:B, Sheet1!F:F, C10) which gives me the average but i've hard coded the header date:
example:
What I want to do is dynamically add the data from the row above with the date time instead of of manually adding it in the formula something like this:
=AVERAGEIFS(Sheet1!C:C,Sheet1!A:A, B11:B, Sheet1!F:F, =CHAR(COLUMN()+64) & 10)
Which would automatically grab the column + row 10 e.g C10, D10, E10.
If i put =CHAR(COLUMN()+64) & 10 in its own cell it works but when I add it to averageifs condition it gives me a parsing error.
Expecting C10, D10, E10 from =CHAR(COLUMN()+64) & 10 which should allow me to dynamically filter data on the date int he header above it.
try:
=AVERAGEIFS(Sheet1!C:C, Sheet1!A:A, B11:B, Sheet1!F:F, INDIRECT(CHAR(COLUMN()+64)&10))

Hour:Minute format on an APEX chart is not possible

I use Oracle APEX (v22.1) and on a page I created a (line) chart, but I have the following problem for the visualization of the graphic:
On the y-axis it is not possible to show the values in the format 'hh:mi' and I need a help for this.
Details for the axis:
x-axis: A date column represented as a string: to_char(time2, 'YYYY-MM')
y-axis: Two date columns and the average of the difference will be calculated: AVG(time2 - time1); the date time2 is the same as the date in the x-axis.
So I have the following SQL query for the visualization of the series:
SELECT DISTINCT to_char(time2, 'YYYY-MM') AS YEAR_MONTH --x-axis,
AVG(time2 - time1) AS AVERAGE_VALUE --y-axis
FROM users
GROUP BY to_char(time2, 'YYYY-MM')
ORDER BY to_char(time2, 'YYYY-MM')
I have another problem to solve it in another way: I am not familiar with JavaScript, if the solution is only possible in this way. Because I started new with APEX, but I have seen in different tutorials that you can use JS. So, when JS is the only solution, I would be happy to get a short description what I must do on the page.
(I don't know if this point is important for this case: The values time1 and time2 are updated daily.)
On the attributes of the chart I enabled the 'Time Axis Type' under Settings
On the y-axis I change the format to "Time - Short" and I tried with different pattern like ##:## but in this case you see for every value and also on the y-axis the value '01:00' although the line chart was represented in the right way. But when I change the format to Decimal the values are shown correct as the line chart.
I also tried it with the EXTRACT function for the value like 'EXTRACT(HOUR FROM AVG(time2 - time1))|| ':' || EXTRACT(MINUTE FROM AVG(time2 - time1))' but in this case I get an error message
So where is my mistake or is it more difficult to solve this?
ROUND(TRUNC(avg(time2 - time1)/60) + mod(avg(time2 - time1),60)/100, 2) AS Y
will get close to what you want, you can set Y Axis minimum 0 maximum 24
then 12.23 means 12 hour and 23 minutes.

Cell formating based on other cell value google sheets

I have 2 sheets the first one is Orders and second one is the ShippingDoc.
At Shipping doc, I have Cell C2. In that cell I choose/write ID from range of A7:A from Orders.
Is there a way if I choose example ID 1 at C2 then automatically A7 at Orders to change background to green. Also if I change the ID to 2 the A8 to be green and to not delete the A7 color.
There is a better way of achieving this using Apps Script. Go to tools->Script editor and there use the following code (explained on the comments in the code):
// Update everytime the value on C2 changes
function onEdit() {
var spreadsheet = SpreadsheetApp.getActive();
// Get C2 value
var C2value = spreadsheet.getSheetByName("ShippingDoc").getRange('C2').getValue();
// If input value is higher than 0
if(C2value>0){
// Ofset to set the background after A7
var number = C2value+6;
// Set background color of appropiate cell
spreadsheet.getSheetByName("Orders").getRange('A'+number+'').setBackground('green');
}
}
Check out more information about how to do amazing things in sheets with simple scripts HERE
I hope this has helped you. Let me know if you need anything or if you did not understand something.
try:
=(REGEXMATCH(""&INDIRECT("ShippingDoc!C2"), ""&A1))*(A1<>"")

Opencart change product price upon user order

I hope my Q will make sense but I am really out of ideas.
I will explain by example: http://www.xtdeco.ro/fototapet/texturat/Bloom-R12241-6
There is a standard product, with some attributes.
What I need to do is make this product configurable, as you may notice the two text inputs. The plan is to calculate the Lățime*Înălțime, multiply by price / sqm, verify against the actual product price (no problem this far) and then add or subtract a value to the product price, or add a option to the product for the current cart that would do the same.
Is there anyone with a idea of how this could be done without hacking to much of the sources?
Thank you.
The easiest way is to not let the user to input his concrete dimensions but to let him choose from prepared one.
If this is a wallpaper and You know the role of this wallpaper is always only 1m wide (just for simplicity) then for example sell only this 1m2 and let the user to enter the amount of pieces which will result in that long piece cut from the role (so 8 piecese (m2) ordered result in 8m long piece of role that is 1m wide). In this case You may change the word pieces or quantity for m2.
If this is a wall print with concrete dimensions (or aspect ratio), let the user choose from some predefined sizes, e.g.
XS (120 x 170 cm) + $0
S (150 x 212.5 cm) + $10
M (200 x 283 cm) + $20
L (250 x 354 cm) + $35
XL (300 x 425 cm) + $50
This may be handled by the product options which is again easier than what are You requesting... Don't You think?
EDIT based on comment:
Then there is only one possibility that comes to my mind:
hide the quantity field (don't remove, make it hidden)
create some JS onChange event handling function, that will listen to onChange, onBlur, onKeyUp (whetever) events on both text fields (for dimensions) and this will calculate the resulting area size in m2 which will be shown to the costumer as well as price per that m2 while price per 1m2 is also known and displayed to the customer
this function will also fill the calculated float value into the hidden quantity field so after adding to the cart the cart should contain smth like
4.73m2 WallPrint1 $18.92
(because I was calculating the price $4 for 1m2, thus 4m2 x 4.73 $/m2 = $18.92)
I'm not sure but maybe You will have to edit some other pieces of code to allow You to add float quantity values into cart annd also to order them...

Filter items with Django Query

I'm encountering this problem and would like to seek your help.
The context:
I'm having a bag of balls, each of which has an age (red and blue) and color attributes.
What I want is to get the top 10 "youngest" balls and there are at most 3 blue balls (this means if there are more than 3 blue balls in the list of 10 youngest balls, then replace the "redudant" oldest blue balls with the youngest red balls)
To get top 10:
sel_balls = Ball.objects.all().sort('age')[:10]
Now, to also satisfy the conditions "at most 3 blue balls", I need to process further:
Iterate through sel_balls and count the number of blue balls (= B)
If B <= 3: do nothing
Else: get additional B - 3 red balls to replace the oldest (B - 3) blue balls (and these red balls must not have appeared in the original 10 balls already taken out). I figure I can do this by getting the oldest age value among the list of red balls and do another query like:
add_reds = Ball.objects.filter(age >= oldest_sel_age)[: B - 3]
My question is:
Is there any way that I can satisfy the constraints in only one query?
If I have to do 2 queries, is there any faster ways than the one method I mentioned above?
Thanks all.
Use Q for complex queries to the database: https://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects
You should use annotate to do it.
See documentation.
.filter() before .annotate() gives 'WHERE'
.filter() after .annotate() gives 'HAVING' (this is what you need)