I have a Google Sheet with data. From this data, the data from the sheet is transferred to a different sheet depending on the criteria. Here's an example. All information is entered on sheet 1. On sheet 2, depending on the entry in column I of sheet 1, the data are transferred.
I use the following to copy the data =FILTER(Bestellungen!C:J; Bestellungen!I:I="H1")
On the first sheet the date is also entered but not in order. Now I would like to copy on sheet 2 that yes all copied the sheet by date. I used the following script.
/** #OnlyCurrentDoc */
function sortResponses() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Halle 1");
sheet.sort(1, false);
}
But when I start it comes the following error:
Areas with vertically connected cells cannot be sorted. the cells in the range i1:i2 are connected vertically
Anybody any Idea?
Related
So I want to create and automatic system for scanning (file iterating) a particular folder. What I want the system to do is:
Scan all the sheet files in the folder, and when a certain cell on the first sheet of one of the spreadsheets (they are all sheet files) contains a certain cell value (for example: when cell A1 of the first sheet "Sheet1" contains "Sales Report") to then find the file ID of that particular spreadsheet and insert it into a cell on another fixed spreadsheet.
Could someone give me an idea of what this would like look in the most efficient manner, I've got a few ideas in regards to if/else arguments but I fear I would make it more complicated than it needs to be. Any help would be appreciated, thank you!
This should get you started:
Instructions:
Load into Script Editor and run any function and it will check for any additional authentication requirements so that you can provide that authorization before attempting to use.
Create a sheet name Master so that I can appead spreadsheet name, sheet name and spreadsheet id to that sheet
Get folder Id and paste it into the code where shown
function scanSpreadsheetsInAFolder() {
const ss=SpreadsheetApp.getActive();
const tsh=ss.getSheetByName('Master');//where I store ssname shname id
const folder=DriveApp.getFolderById('FolderId');
let files=folder.getFilesByType(MimeType.GOOGLE_SHEETS);
while(files.hasNext()) {
let file=files.next();
let s=SpreadsheetApp.openById(file.getId());
let sh=s.getSheets()[0];//gets first sheet in spreadsheet
let v=sh.getRange(1,1).getValue();//gets value in A1
if(v=='Sales Report') {
tsh.appendRow([ss.getName(),sh.getName(),ss.getId()]);//append data to master
}
}
}
I'm trying to create a response table with a Google sheet that lets people enter their responses. Then compile that information into another Google Sheet by specified columns at the bottom of the previous response.
I have tried numerous ways but I cannot seem to get the script to work.
Broken Down, I need the Script/Guide to be able to:
Allow multiple people to record their response individually by the given link of Google sheet Form
Give a dynamic Sum Total in the Total Row
Have an Add row Icon so as to let respondent add rows dynamically and make their own choice of inputs
Create a Submit Icon, which records the response to another google sheet
The intended sheet is below
https://docs.google.com/spreadsheets/d/1cQTBONtpLiMbRmtVgSyOT_mShzzwbrX7-w46zy9w9I4/copy?usp=sharing
This may be a simple question that I didn't sound any solution
Please see if this works for you.
Modified enquiry form
1. Allow multiple people to record their response individually by the given link of Google sheet Form
You need to share a copy of your spreadsheet. Do not share the original. In the URL you have posted, replace 'edit' with 'copy'.
The modified enquiry form
2. Gives a dynamic Sum Total in the Total Row as your user records their inputs by using onEdit function.
3. Has an Add row and Delete row Icon so as to let respondent add and delete rows dynamically and make their own choice of inputs. To add a row, the active row number should be 4 or above
4. Creates a Place Order Image, which appends the response to another google sheet
To achieve point 4, you need to create a separate spreadsheet having 1 row only. This serves as the column heading and can be in a form as shown below. This spreadsheet contains the details of responses from all users.
Note: Updating a spreadsheet automatically when the user clicks the Submit button would require you to make the spreadsheet shareable via email addresses with editor access at a minimum. This is potentially an unsafe way of saving user responses.
function sendData() {
var sprsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = sprsheet.getActiveSheet();
var range = sheet.getRange("A2:G4");
var values = range.getValues();
var mainsprsheet = SpreadsheetApp.openById("main sheet id");
// 1. this "main sheet id" should say something like: "1cQTBONtpLiMbRmtVgSyOT_mShzzwbrX7-w46zy9w9I4", you can xopy/paste the id from your address bar in your browser
// ==> https://docs.google.com/spreadsheets/d/1cQTBONtpLiMbRmtVgSyOT_mShzzwbrX7-w46zy9w9I4/edit?ts=5ed39726#gid=0
var targetSheet = mainsprsheet.getActiveSheet();
targetSheet.appendRow(values);
// 2. appendRow() accepts an array like for example this array with strings ["Fabric Code", "Thickness","Width","Length","Finish","Quality type","Quantity"]
// method getValues() returns an array of arrays (or 2D array) like for example this one[["Fabric Code", "Thickness","Width","Length","Finish","Quality type","Quantity"]]
// Think of the outer [..] as row indicator and the inner [..] as the array that holds the columns(fields) of the record.
// i would change your code to: (remove the //s)
// var lr = targetSheet.getLastRow()
// var lc = targetSheet.getLastColumn()
// targetSheet.getRange(lr+1 , 1, values.length, values[0].length).setValues(values)
//Clear the cells (optional)
range.clearContent();
}
I'm trying to create a table with editable cells in a google form that lets people enter their recorded measurements. Then compile that information into a Google Sheet by specified columns.
I have tried the Awesome table but I cannot seem to get the script to work.
Broken Down, I need the Script to be able to:
import a table into google forms
edit the number of columns and rows
allow multiple people to record their measurements individually
Compile the recorded data into a sheet by column.
This may be a simple question that I am overthinking. But I am trying to avoid multiple questions on the same form, and think a table would be way easier.
As talked in the comments, since there is no table item in FormApp, this solution consists in sending a Sheet with a predefined table for users to fill. They will press a button and send the data to a master sheet.
CODE
function sendData() {
//Gets the sheet is being edited
var sprsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = sprsheet.getActiveSheet();
//Gets the data introduced by the user
var range = sheet.getRange("A2:L2");
var values = range.getValues();
//Gets the target sheet
var mainsprsheet = SpreadsheetApp.openById("main sheet id");
var targetSheet = mainsprsheet.getActiveSheet();
//Adds a new row to the target sheet with the collected data
targetSheet.appendRow(values);
//Clear the cells (optional)
range.clearContent();
}
BUTTON
To create the "submit" button to run the function above:
Go to Insert > Drawing
Design your own button
Save and close
Click on the button and then on the 3 dots at the right-top.
Click on "Assign script" and write sendData
You can place the button anywhere and resize it.
NOTES
You might want to send copies of this sheet to the different users to avoid sharing of sensitive data.
REFERENCES
Range Class
Method getValues
Method appendRow
I am working with Google Form results data that is being dropped into a Google Sheet tab and I added a column to calculate the percentage of the quiz scores that are then being pulled onto a tracking tab in the same sheet that calculates their percentage completed. Right now the Percent Column is appearing as a blank field no matter which formula I've tried. I am wondering if there is a different formula would work that would automatically apply to the column when new responses are added? Or would a Google Script be a better option?
I am wanting to keep the raw result data on the same sheet since it is compiling all of the quizzes into one Google Sheet with one tab pulling the Percentages to show completion rate.
I have tried ARRAYFORMULA and the formula that works if you copy it manually to each entry is "=left(C2,find("/",C2)-1)/(right(C2,len(C2)-find("/",C2)))"
Try
=Arrayformula(if(len(C2:C), left(C2:C,find("/",C2:C)-1)/(right(C2:C,len(C2:C)-find("/",C2:C))),))
and see if that works?
This function will add a formula in the last column when a new formresponse will be added to the sheet:
function setFormula() {
var ss=SpreadsheetApp.openById('SHEET_ID');
var sheet=ss.getSheetByName('SHEET_NAME');
var lastRow = sheet.getLastRow();
var formulaRange1 = sheet.getRange(lastRow, sheet.getLastColumn());
formulaRange1.setValue('=IF($A'+lastRow+'="";"";TODAY()-$Q'+lastRow+')');
}
Your formula must be adjusted accordingly. Just make sure that lastRow is inside the string instead of the line number and add a onFormResponse Trigger. I've added this script to the form, not to the spreadsheet.
As of now, it appears that Google Spreadsheets does not allow locking of cell ranges but instead locking has to be done on a sheet by sheet basis in its entirety. I would like to share a sheet with another user and have them enter data on Sheet 1. To prevent tampering, I would like the data duplicated on Sheet 2 (locked by me) with a timestamp of the last change made on Sheet 1. I've been playing with this onEdit() function but it does not give an updated time when I edit Sheet 1 but still only if I edit Sheet 2. I just haven't figured out what I'm doing wrong.
function onEdit(e)
{
var ss = e.source.getActiveSheet();
var rr = e.source.getActiveRange();
//comment 2 lines below if you want it working on all sheets, not just on 2nd one
if(ss.getIndex()!= 2)
return;
///
var firstRow = rr.getSheetByName(Sheet2).getRow();
var lastRow = rr.getSheetByName(Sheet2).getLastRow();
//the last modified date will appear in 12th column
for(var r=firstRow; r<=lastRow; r++)
ss.getRange(r, 12).setValue(new Date());
}
Is there another way I could do this?
You cannot use scripts to prevent the other user from tampering, because
he can go to Tools>Script editor and edit your script so that it
becomes idle, then edit Sheet1, then restore your script.
See the issue tracker for this issue. You cannot protect your scripts
from being edited by other users with whom you share at least one worksheet of your spreadsheet.
On the other hand, leaving scripts aside, you can always see
the history of what was edited by whom and when: File>See revision history.
I see a couple of problems. First, you're trying to use .getSheetByName() on a range object, but that method is only supported by spreadsheet objects. You can run .getSheet() on a range and that will return the sheet the range is in. Secondly, formatting: GAS requires standard Javascript which means that your if and for functions need to have {}. This should work for what you want:
onEdit(e){
if(e.range.getSheet().getSheetName()!="Sheet2"){
var row1=e.range.getRow();
var col2=e.range.getColumn();
var row2=e.range.getLastRow();
var col2=e.range.getLastColumn();
var data=e.range.getValues();//the data to be copied
var copySheet=e.source.getSheetByName("Sheet2");//sheet you want to copy to
var copyRange=copySheet.getRange(row1,col1,row2-row1,col2-col1);// the range data will be copied to
var time=new Date();
var timeRange=copySheet.getRange(row,col);//wherever you want the time signature to be.
timeRange.setValue(time);//inserts time stamp into sheet
copyRange.setValues(data);//copies data to the range
}
}
Just replace row and col with the row and column you want to place the time into. It takes the edited range and copies it to the same location on sheet 2 so it only works if sheet 1 is the only sheet to be edited. Otherwise you'll end up with overlapping data. You could also set a time stamp to be adjusted to the range, meaning put its position as something like (row1,col2+5). That would put it 5 columns right of the edited range.