Im looking for something to get what is selected in a spreadsheet. I would like the users to select a couple of rows. And get the selected data in the rows in a variable.
I know this is possible with DocumentApp. But can it be done with Spreadsheet, i haven't found anything good.
Docs:
var selection = DocumentApp.getActiveDocument().getSelection();
Spreadsheet:
var selection = SpreadsheetApp.getActiveSpreadsheet().
Can't do the .getSelection(); here, what could i do instead?
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet Name");
//For range
var activerange = sheet.getActiveRange().getValues();
//for cell
var activecell = sheet.getActiveCell().getValue();
You can use getActiveRange or getActiveCell to get data from active range.
Related
I have a dataset of 35 columns and 300 rows. I want to get the range that contains rows only for certain values in column 30 (names). The name for which to filter the data is based on the report file cell B6 in the report sheet that is active. So far I tried this:
var report = SpreadsheetApp.getActiveSpreadsheet();
var tsheet = report.getSheetByName("Transactions");
var areport = SpreadsheetApp.getActiveSheet();
var agent = areport.getRange('B6').getValues();
var criteria = SpreadsheetApp.newFilterCriteria().whenTextEqualTo(agent).build();
var trange = tsheet.getRange().createFilter().setColumnFilterCriteria(30, criteria); // ERROR
var tdata = trange.getValues();
I receive an error Exception: The parameters () don't match the method signature for SpreadsheetApp.Sheet.getRange.
The second part, I only want to get several columns, 5,6,7, 13, 15. I can't create another filter with the Spreadsheet app, so is the only way to make an array and filter out the needed data from there? I'm just trying to think ahead and reduce the amount of calculations.
Try with filter():
var report = SpreadsheetApp.getActiveSpreadsheet();
var tsheet = report.getSheetByName("Transactions");
var areport = SpreadsheetApp.getActiveSheet();
var agent = areport.getRange('B6').getValue();
var data = tsheet.getRange('A1:AI300').getValues();
var tdata = data.filter(function (row) {
return row[29] == agent && row[5] == 'Closed' ; // starts from 0, column A is 0.
});
To select particular columns from tdata do:
var cr_data = getCols(tdata,[5,6,7, 13, 15]);
where getCols() is defined as follows:
function getCols(arr,cols) {
return arr.map(row =>
row.filter((_,i) => cols.includes(++i)))
}
and finally you can copy cr_data to a particular place/sheet like that:
sheet.getRange(1,1,cr_data.length,cr_data[0].length).setValues(cr_data);
Regarding the second part of your question I would like to redirect you to this post:
Best method to extract selected columns from 2d array in apps script
I have a google form with a dropdown (see below)
I have a column on a google sheet that gets updated everyday.
Is there any way that I can automatically link the names from the google sheet to the google form dropdown Question 1 such that each time the sheet gets updated with an additional name - the google form automatically gets updated with the name in the dropdown. I imagine we would need to use Google AppScript. Any guidance in pointing me in the right direction would be appreciated.
A very generic script but you should be able to modify it as you see fit
function updateForm(){
var ss = SpreadsheetApp.openById('----------'); // ID of spreadsheet with names
var sheet = ss.getSheetByName('Names'); // Name of sheet with range of names
var nameValues = sheet.getRange('A2:A10').getValues(); // Get name values
var form = FormApp.openById('---------'); // ID of form
var formItems = form.getItems();
var question = formItems[2].asListItem(); // Get the second item on the from
var names = []
for(var x = 1; x < nameValues.length; x++){
if(nameValues[x][0] != ""){ // Ignores blank cells
names.push(question.createChoice(nameValues[x][0])) // Create an array of choice objects
}
}
var setQuestion1 = question.setChoices(names); // Update the question
}
To update the form when the sheet is edited you can use an installed onEdit trigger. With the addition of logic you can limit the updting of the form to only occour when a particular range has been edited.
In this example the form will only update when an edit has been made to column A of the sheet 'Names'
function updateForm(e){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetName = sheet.getSheetName();
var getCol = e.range.getColumn();
if(sheetName == 'Names' && 1){
var nameValues = sheet.getRange('A2:A10').getValues(); // Get name values
var form = FormApp.openById('---------'); // ID of form
var formItems = form.getItems();
var question = formItems[2].asListItem(); // Get the second item on the from
var names = []
for(var x = 1; x < nameValues.length; x++){
if(nameValues[x][0] != ""){ // Ignores blank cells
names.push(question.createChoice(nameValues[x][0])) // Create an array of choice objects
}
}
var setQuestion1 = question.setChoices(names); // Update the question
}
}
I have a spreadsheet that people will fill out and then hit a submit button. That button creates a PDF and emails that data to people. A portion of that data needs to be compiled in another spreadsheet each time someone submits their data.
I have code that can copy a range and paste it in the spreadsheet.
function CopyDataToNewFile() {
var sss = SpreadsheetApp.openById('abcd1234'); // sss = source spreadsheet
var ss = sss.getSheetByName('Timesheet'); // ss = source sheet
//Get full range of data
var SRange = ss.getRange("A10:L22");
//get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
//get the data values in range
var SData = SRange.getValues();
var tss = SpreadsheetApp.openById('abcd1234'); // tss = target spreadsheet
var ts = tss.getSheetByName('Info'); // ts = target sheet
var TRange = ts.getRange("A1:L13");
var T1Range = TRange.getA1Notation();
//set the target range to the values of the source data
ts.getRange(T1Range).setValues(SData);
}
I have two issues with this code:
I cannot select specific cells of data, I need to select J6 but also the entire 11th row. A bonus would be if it sees a value in say, A14, then it will copy the whole 14th row. But if nothing is in A14 it will not copy that data.
The data overwrites itself each time data is submitted, I need each new addition of data to just show up under the last one.
I have been looking for a solution to this for hours and am not versed in Javascript enough to write anything custom. Thank you!
In the script below you can see how you can select individual cells or entire rows and how you can copy their contents into another sheet.
There's also an example of how you can check if a cell has a value or not.
You can find a solution here how you can copy stuff into an existing sheet without overwriting what's already in there.
function CopyDataToNewFile() {
var sourceSheet = SpreadsheetApp.openById('ID'); // Selects your Source Spreadsheet by its ID
var ssheet = sourceSheet.getSheetByName('Timesheet'); // Selects your Source Sheet by its Name
var J6value = ssheet.getRange(6, 10).getValue(); // Get value from J6 in Source Sheet
var A14value = ssheet.getRange(14, 1).getValue(); // get value from A14 in Source Sheet
var the11thRow = ssheet.getRange('A11:11').getValues(); // Select the entire 11th row in the Source Sheet
var the14thRow = ssheet.getRange('A14:14').getValues(); // Select the entire 14th row in the Source Sheet
var targetSheet = SpreadsheetApp.openById('ID'); // Selects your Target Spreadsheet by its ID
var tsheet = targetSheet.getSheetByName('Info'); // Selects your Target Sheet by its name
var targetFor14thRow = tsheet.getRange('A11:11'); // Selects where your 11th row will be copied to, in this case simply row 11
var targetFor11thRow = tsheet.getRange('A14:14'); // Selects where your 14th row will be copied to, in this case simply row 14
if (!ssheet.getRange(14, 1).isBlank()) { // Conditional: If A14 in Source Sheet isn't empty
targetFor14thRow.setValues(the14thRow); // Then copy the entire 14th row to its target
}
tsheet.getRange(1,2).setValue(J6value); // Copy the value of J6 in the source document to 2A of the Target Sheet
tsheet.getRange(3,4).setValue(A14value); // Copy the value of A12 in the source document to C4 of the Target Sheet
}
EDIT: Use .setValues instead of .copyTo in order to copy entire rows.
After some more research I gathered some more code this is working beautifully now.
function CopyDataToNewFile(targetSheetName,targetSsId, sourceSheetName,sourceSsId) {
var ss = SpreadsheetApp.openById('abcd1234sydfhnsgb').getSheetByName('Timesheet');
var ssd = SpreadsheetApp.openById('abcd1234srymsnzd').getSheetByName('Info');
var therapist = ss.getRange('D6:K6').getValues();
var sourceData10 = ss.getRange('A10:10').getValues();
ssd.getRange(ssd.getLastRow()+1,1,therapist.length,therapist[0].length).setValues(therapist);
if (!ss.getRange(10, 1).isBlank()) {
ssd.getRange(ssd.getLastRow()+1,1,sourceData10.length,sourceData10[0].length).setValues(sourceData10);
}
}
I want help for google script in spreadsheets.
I want to duplicate sheet named template, with names in range J1:N1 which is on the same spreadsheet in 'base' sheet. Also in range J1:N1 maybe different count values. is it possible to change number of duplicated sheets by values which in the range. For example if in this range 3 values copy template sheet 3 times...
After this I want to rename this duplicates with values in J1:N1 values, and copy the name of duplicated sheets on B2 cell on every duplicate. After all shi process hide template sheet.
This is link to spreadsheet:
https://docs.google.com/spreadsheets/d/1R-1mrfPwXGrJp3aVhGBFlalPnJ5r28cW9HuTu2OLmHc/edit?usp=sharing
I used this code, but its create only 1 sheet and with number. I need exactly the name for per sheet which is in the range:
function makeCopies() {
//getting active spreadsheet
var activeSreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//getting basic sheet
var basicSheet = activeSreadsheet.getSheetByName("base");
//getting active spreadsheet
var activeSreadsheet2 = SpreadsheetApp.getActiveSpreadsheet();
//getting template sheet
var templateSheet = activeSreadsheet2.getSheetByName("template");
//setting template sheet as active
activeSreadsheet2.setActiveSheet(templateSheet);
//getting values from selected range
var rangeArr = basicSheet.getRange("J1:N1").getValues();
//going through range values
for(i = 0; i < rangeArr.length; i++){
//preparing name for new sheet
var name = (i + 2) + '. ' + rangeArr[i][0];
//making duplicate of base sheet
var newSheet = SpreadsheetApp.getActiveSpreadsheet().duplicateActiveSheet();
//setting new name for duplicated sheet
newSheet.setName(name)
}
};
I found this code too, but it didnt exactly what i want:
function createEmployeeSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Get the range of cells that store employee data.
var employeeDataRange = ss.getRangeByName("group");
var employeeObjects = employeeDataRange.getValues();
var template = ss.getSheetByName('Template');
for (var i=0; i < employeeObjects.length; i++) {
// Put the sheet you want to create in a variable
var sheet = ss.getSheetByName(employeeObjects[i]);
// Check if the sheet you want to create already exists. If so,
// log this and loop back. If not, create the new sheet.
if (sheet) {
Logger.log("Sheet " + employeeObjects[i] + "already exists");
} else {
template.copyTo(ss).setName(employeeObjects[i]);
}
}
return;
This code creates dynamic count of sheets from range and 1 additional which can't rename because in range its empty cell.
Thanks in advance!
Sheet 2 has all the items and their statuses, while Sheet 1 has only some of the items from Sheet 2. I want to be able to see every time an item mentioned on Sheet 1 is listed as having a status update, i.e. e date, on Sheet 2.
Here's what I have so far, but having trouble calling the right range to work with. Is there a simpler way to do what I want to do?
function statusupdate() {
var activesht = SpreadsheetApp.getActiveSpreadsheet();
var statussht = activesht.getSheetByName("Sheet 2"); //get sheet on which status update occurs
var statusrng1 = statussht.getRangeByName('B');
var statusrng2 = statussht.getRangeByName('C');
var mainsht = activesht.getSheetByName("Sheet 1"); //get sheet where you show a specific thing has been updated, if that thing mentioned here.
var mainrng = mainsht.getRangeByName('F');
if (statusrng1 == mainrng) {
var date = statusrng2.getValue();
var daterng = mainrng.getRangeByName('E');
daterng.setValues(date);
}
}
Spreadsheet formula
You can have the rows in one sheet follow those in another without using a script. For example, say we have a sheet named Items that contains one row for every item we carry, with the item number in the first column.
We can use VLOOKUP() to search for the row containing info about individual items, and select specific columns from it.
For example, this formula would be used in B2, and could be copied to other cells in our sheet:
=VLOOKUP($A2,Items!$A$2:$C$7,COLUMN(),false)
Script
There are a few issues with your script.
.getRangeByName('B') - This method gets a named range. Given the name, I suspect you mean to get column B, and NOT a named range. If that's the case, you could use this instead:
var statusrng1 = statussht.getRange('B:B');
In A1Notation, the range B:B is the entire column B.
You intend to copy values, so there is another step required beyond identifying ranges; you need to first read the values from a range, and then later write them to a different range. For that, you need to use methods like getValues() and setValues().
Here's an updated version of your script, adapted to the example spreadsheet described above.
function statusupdate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//get sheet on which status update occurs
var statusSheet = ss.getSheetByName("Items");
var statusRange = statusSheet.getDataRange();
var statusData = statusRange.getValues();
//get sheet where you show a specific thing has been updated, if that thing mentioned here.
var trackingSheet = ss.getSheetByName("Tracking");
var trackingRange = trackingSheet.getDataRange();
var trackingData = trackingRange.getValues();
// Loop over all rows in the Tracking sheet to update from the Items sheet
// Start with row=1, because row 0 contains headers
for (var row=1; row<trackingData.length; row++) {
var item = trackingData[row][0];
if (item == '') continue; // skip rows without item #
// Look for item in Items sheet
var statusRow = null;
for (var sRow=1; sRow<statusData.length; sRow++) {
if (statusData[sRow][0] == item) {
// Found our match, grab that row
statusRow = statusData[sRow];
break;
}
}
// If we found a matching row, copy the status
if (statusRow) {
// Customize this depending on how your sheets are organized
trackingData[row][1] = statusRow[1];
trackingData[row][2] = statusRow[2];
}
}
// All values have been copied to trackingData, now write to sheet
trackingRange.setValues(trackingData);
}