问题
Hi Google Apps Script Programmers, Picture making a kind of database for a sandwich shop in Google Sheets, where most sheets are data tables with column 1 being an autonumber field. The first sheet is the main order form named MySubShop. It'll record the order#, cashier, customer, date/time, and have a bunch of checkboxes for the foods. The second sheet is named Lookups and has lookups for bread types and beverage types only because people can only select 1 type of bread and 1 beverage. The rest of the sheets are like database tables and are named like this: Breads, Meats, Cheeses, Condiments, and Sides.
In the main MySubShop sheet, during an order, a user will mainly click on checkboxes next to food items because users can select > 1 topping item. For instance, for cheeses, cheddar and provolone can both be checked. Same with meats, sides, etc.
A button will be clicked to get the values of all of the cells on the MySubShop order sheet and then set those values across all of the other sheets.
Question - The issue is I'd really like to store the values just like a database. Take the cheeses for example. If the checkboxes next to cheddar and provolone are checked, I'd like for Sheets to get those values and then, in the Cheeses sheet, lay out the data like this:
orderID , cheeseID
1 , 1 where 1 would = cheddar
1 , 4 where 4 would = provolone
Unlike a database though, cheddar and provolone are defined by their ranges on the main MySubShop sheet. Chedder is a checkbox in cell G2 and provolone is a checkbox in cell G5. So if G2 is checked TRUE and if G5 is TRUE, then get those values and, on button click, set those values.
Question - I am new to Apps Script and would like some help figuring out some of this code, for instance, for the Cheeses. How to take a TRUE value in cell G2 and change it to a numerical value on the last row of col 2 of the Cheeses sheet.
Any help on this would be very greatly appreciated. Thanks
//GRAB ALL OF AN ORDER'S DATA ON MYSUBSHOP SHEET AND COPY IT TO THE OTHER SHEETS
function setValuesAcrossSheets() {
var mysheet = SpreadsheetApp.getActive().getSheetByName('MySubShop');
//Get the order info
var ordersvalues = [[mySubShop.getRange("B5").getValue(),
mySubShop.getRange("B4").getValue(),
mySubShop.getRange("B3").getValue(),
mySubShop.getRange("B2").getValue()]];
orders.getRange(orders.getLastRow()+1, 1, 1, 4).setValues(ordersvalues);
//increase the order number to get ready for the next order
mySubShop.getRange("B5").setValue(newordernum+1);
//trying to figure out the best way to do this...
var breadvalues = sheet.getRange("c2"); //a listbox that pulls options from another sheet
var meatvalues = ['d5', 'd6', 'd7', 'd8', 'd9', 'd10']; //checkboxes in d5:d10
var cheesevalues = ['g2', 'g3', 'g3', 'g4', 'g5']; //checkboxes in g2:g5
var beveragevalues = sheet.getRange("f8"); //checkboxes in g2:g5
var condimentvalues = ['j2', 'j3', 'j4', 'j5', 'j6', 'j7', 'j8']; //checkboxes in j2:j8
var sidesvalues = ['m2', 'm3', 'm4', 'm5', 'm6']; //checkboxes in m2:m6
回答1:
I made the full application for you.
I added "Number of sandwitch" as a single order can have many similar sandwitch. No need to make many orders for it. If you don't like it, just feed "1" quantity for all orders.
function confirm_order() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ordsht = ss.getSheetByName('MySubShop');
var sumsht = ss.getSheetByName('Orders');
var loksht = ss.getSheetByName('Lookups');
var metsht = ss.getSheetByName('Meats');
var brdsht = ss.getSheetByName('Breads');
var chssht = ss.getSheetByName('Cheeses');
var consht = ss.getSheetByName('Condiments');
var sidsht = ss.getSheetByName('Sides');
var bevsht = ss.getSheetByName('Beverages');
var ordvals = ordsht.getRange("A1:M10").getValues();
//Browser.msgBox(ordvals);
sumsht.appendRow([ordvals[4][1], ordvals[3][1],ordvals[2][1],ordvals[1][1] , ordvals[5][1] ]);//order list
brdsht.appendRow([ordvals[4][1], ordvals[1][2] , ordvals[5][1] ]);//bread
bevsht.appendRow([ordvals[4][1], ordvals[7][5], ordvals[5][1] ]);//beverage
//meat
for (i=4;i<10;i++){
if (ordvals[i][3]==true){
metsht.appendRow([ordvals[4][1], ordvals[i][2], ordvals[5][1] ]);
}//if
}//for
//cheese
for (i=1;i<5;i++){
if (ordvals[i][6]){
chssht.appendRow([ordvals[4][1], ordvals[i][5], ordvals[5][1] ]);
}//if
}//for
//condiments
for (i=1;i<8;i++){
if (ordvals[i][9]){
consht.appendRow([ordvals[4][1], ordvals[i][8] , ordvals[5][1]]);
}//if
}//for
//sides
for (i=1;i<6;i++){
if (ordvals[i][12]){
sidsht.appendRow([ordvals[4][1], ordvals[i][11] , ordvals[5][1]]);
}//if
}//for
//increase the order number to get ready for the next order
ordsht.getRange("B5").setValue(ordvals[4][1]+1);
}
//
See the sheet here
https://docs.google.com/spreadsheets/d/1X97wIEHGxbRIzG4GEOZQOxwM7IPlGCgEHV7qcULLe78/edit#gid=189012034
After configuring the order just click "order"
You can further improve it like
Reset all options after each order, Make sure atleast one option is selected for each item, Limit the number of choices to, say max 3 (not more than 3 can be selected)
If you want, I will do it for you.
I will claim my sandwitch soon!!! Cheers!
回答2:
Try this
//GRAB ALL OF AN ORDER'S DATA ON MYSUBSHOP SHEET AND COPY IT TO THE OTHER SHEETS
function setValuesAcrossSheets() {
var mysheet = SpreadsheetApp.getActive().getSheetByName('MySubShop');
//Get the order info
var ordersvalues = mysheet.getRange("B2:B5").getValues();
if (ordersvalues[0][0]=="TRUE") { ordersvalues[0][0]=1 } else {ordersvalues[0][0]=0}
if (ordersvalues[1][0]=="TRUE") { ordersvalues[1][0]=1 } else {ordersvalues[1][0]=0}
if (ordersvalues[2][0]=="TRUE") { ordersvalues[2][0]=1 } else {ordersvalues[2][0]=0}
orders.getRange(orders.getLastRow()+1, 1, 1, 4).setValues([ordersvalues[3][0], ordersvalues[0][0],ordersvalues[1][0],ordersvalues[2][0] ]);
//increase the order number to get ready for the next order
mySubShop.getRange("B5").setValue(newordernum+1);
If you want to do the same for many loops, you can do it inside a loop to make the code shorter.
Pl. share a copy of the sheet with public edit rights and paste the url here for better understanding
回答3:
Since your checkboxes are displayed in vertical what I would do is to create an hidden column that hosts the food ids.
Approach:
As an example for the Cheeses you can have your cheeses checkboxes in column G from row 5 to row 10. Let's say that in column F which will be hidden I have the ids of my cheeses.
In this way I can relate the checkbox to the cheese id directly without filtering the actual names (that i suppose will exist in a column next to the checkboxes anyways).
Here an example:
let ss = SpreadsheetApp.getActiveSheet(); // MySubShop
let CheesIds = ss.getRange("F8:G12").getValues() // get the rows
.filter(value=> value[1]) // the boolean value to filter the rows
.flatMap(value => value[0]); // the filtered cheese ids
You can reproduce this behavior for all of the others categories and then generate the entries in the corresponding sheets.
If this is not possible in your sheet please excuse my initial assumption.
回答4:
I improved the solution using array. Hope the speed will improve greatly. Try it.
I introduced a "Detail" sheet. Once order is confirmed, it is written to this sheet at one go. You can filter it easily.
For convenience, I have provided query in all other sheets which pull data from the detail sheet.
https://docs.google.com/spreadsheets/d/10yvp5GFfR1b-I5fpuCbuhvkp_dahENowzQQZH6c9QOE/edit?usp=sharing
function confirm_order() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ordsht = ss.getSheetByName('MySubShop');
var sumsht = ss.getSheetByName('Orders');
var detsht = ss.getSheetByName("Detail")
//var loksht = ss.getSheetByName('Lookups');
//var metsht = ss.getSheetByName('Meats');
//var brdsht = ss.getSheetByName('Breads');
//var chssht = ss.getSheetByName('Cheeses');
//var consht = ss.getSheetByName('Condiments');
//var sidsht = ss.getSheetByName('Sides');
//var bevsht = ss.getSheetByName('Beverages');
var ordvals = ordsht.getRange("A1:M10").getValues();
//Browser.msgBox(ordvals);
var ordary=[];
sumsht.appendRow([ordvals[4][1], ordvals[3][1],ordvals[2][1],ordvals[1][1] , ordvals[5][1] ]);//order list
ordary.push(["Bread",ordvals[4][1], ordvals[1][2] , ordvals[5][1] ]);//bread
ordary.push(["Beverage",ordvals[4][1], ordvals[7][5], ordvals[5][1] ]);//beverage
//meat
for (i=4;i<10;i++){
if (ordvals[i][3]==true){
ordary.push(["Meat",ordvals[4][1], ordvals[i][2], ordvals[5][1] ]);
}//if
}//for
//cheese
for (i=1;i<5;i++){
if (ordvals[i][6]){
ordary.push(["Cheese",ordvals[4][1], ordvals[i][5], ordvals[5][1] ]);
}//if
}//for
//condiments
for (i=1;i<8;i++){
if (ordvals[i][9]){
ordary.push(["Condiment",ordvals[4][1], ordvals[i][8] , ordvals[5][1]]);
}//if
}//for
//sides
for (i=1;i<6;i++){
if (ordvals[i][12]){
ordary.push(["Sides",ordvals[4][1], ordvals[i][11] , ordvals[5][1]]);
}//if
}//for
//increase the order number to get ready for the next order
ordsht.getRange("B5").setValue(ordvals[4][1]+1);
detsht.getRange("A"+(detsht.getLastRow()+1)+":D"+(detsht.getLastRow()+ordary.length)).setValues(ordary);
}
//
来源:https://stackoverflow.com/questions/61250546/getting-boolean-values-from-checkboxes-and-appending-them-as-numbers-in-another