Script AppendRow at the top - javascript

I have this little code to insert data from a form to a specific sheet.
function grabarEnSheets(e) {
//Conectarse con sheets
const libro=SpreadsheetApp.openById("SheetID")
const hoja=libro.getSheetByName("Patrol-Logs")
//Traer respuestas
const respuestaEnviada=e.response;
const respuestas=respuestaEnviada.getItemResponses();
const Nombre = respuestas[0].getResponse();
const Dia = respuestas[1].getResponse();
const Tiempo = respuestas[2].getResponse();
const Evidencia = respuestas[3].getResponse();
const Traje = respuestas[4].getResponse();
//Campos nuevos
var fecha=new Date();
//Guardar respuestas en sheets
hoja.appendRow([fecha,Nombre,Tiempo,Dia,Evidencia,Traje])
}
function darPermisos(){
SpreadsheetApp.openById("sheetID")
FormApp.getActiveForm();
}
And the appendRow adds the data at the bottom of the sheet.
So what I need is to append all entry data from the form and skip the first and second table.

From your following replying in the comment,
I don't know how to make appendRow to start adding the data at the third file, and not at the bottom.
I thought that you might have wanted to append a data row to the 3rd tab on the Google Spreadsheet. If my understanding is correct, how about the following modification?
From:
hoja.appendRow([fecha,Nombre,Tiempo,Dia,Evidencia,Traje])
To:
libro.getSheets()[2].appendRow([fecha,Nombre,Tiempo,Dia,Evidencia,Traje]);
libro.getSheets()[2] means the 3rd tab on the active Spreadsheet.
If you want to use appendRow to the specific sheet, you can also use the following script using the sheet name.
libro.getSheetByName("###SheetName###").appendRow([fecha,Nombre,Tiempo,Dia,Evidencia,Traje]);
Reference:
getSheets() of Class Spreadsheet

Related

Google Sheets Script to duplicate data foreach country code

I have a list of products with their attributes. Example column names are:
id, availability, condition, description, title, price, sale_price
In another sheet "cheat" I have a list of country codes like, FR and DE.
For each of those country codes I want to duplicate the product data and for each of those duplications add the country code in and "override" named column.
Here is a link to an example doc:
https://docs.google.com/spreadsheets/d/1kkcpovmWAcqa3hRBmsw-8g3R1FKIUfNqD5BF6tI4egI/edit?usp=sharing
Any help here is appreciated as I'm struggling to even get started.
I've checked your sample doc sheet and came up with this method below:
Recommendation
I have created a script with custom function named showResult():
function showResult() {
var ss = SpreadsheetApp.getActive();
var products = ss.getSheetByName('products'); //Gets all data on 'products' sheet
var cheat = ss.getSheetByName('cheat'); //Gets all data on 'cheat' sheet
var row = products.getDataRange().getNumRows(); //Counts current # of rows on 'products' sheet
var cheatRow = cheat.getDataRange().getNumRows(); //Counts current # of rows on 'cheat' sheet
var finalResult = [[products.getRange(1,1).getValue().toString(), //Initalize the column titles first on the finalResult array
products.getRange(1,2).getValue().toString(),
products.getRange(1,3).getValue().toString(),
products.getRange(1,4).getValue().toString(),
products.getRange(1,5).getValue().toString(),
'override']]; //Adds the 'override' column
for(var i=2; i<=cheatRow; i++){ //First loop to get each country codes
for(var x=2; x<=row; x++){ //Final loop to add each country codes to the each copy of grouped product values
finalResult.push([products.getRange(x,1).getValue().toString(),
products.getRange(x,2).getValue().toString(),
products.getRange(x,3).getValue().toString(),
products.getRange(x,4).getValue().toString(),
products.getRange(x,5).getValue().toString(),
cheat.getRange(i,1).getValue()
]);
}
}
SpreadsheetApp.getActive().getSheetByName('output').clear().getRange(1, 1, finalResult.length, finalResult[0].length).setValues(finalResult);
}
function onOpen() { //[Optional] Added a custom menu to manually to refresh your 'output' sheet
var ui = SpreadsheetApp.getUi();
ui.createMenu('Refresh output sheet')
.addItem('Refresh', 'showResult')
.addToUi();
}
This script will get all data from 'products' sheet (contains 5 columns):
Then, the script will start adding each country codes from 'cheat' sheet, as seen below, to every group of data from the 'products' sheet:
To run the script, you can click the "Refresh output sheet > Refresh" menu on your Spreadsheet:
To be able to dynamically update your 'output' sheet, you need to create a time-based trigger on the Apps Script editor, like this one that I've created to run the showResult() every 1 minute:
RESULT
On the 'output' sheet, this will be the result:
If there's a new 'product' data, it will be updated to the 'output' sheet as seen here:

Self Populating Cell in Google Sheets after a ZAPIER ZAP is run

I live oversees (military) and get emails when I have a package that arrives at my Post Office and is ready for pickup. I have a Zapier PARSER email account and associated ZAP setup that pulls the data from the email and updates a Google Sheets document with its shelf location, tracking number, and a few other important things from the email so the clerks can get my stuff quickly. It works great. In that same workbook, I have another sheet that I update using an app on my phone to scan tracking barcodes to when I physically pick up the package. On the first sheet I have a basic VLOOKUP function that looks for the tracking number in the scanned list to mark it off as PICKED UP (I get a lot of packages )
I have to manually go in and drag the function down when the ZAP creates a new row. it's not difficult, but i want to have it all automatic. that's what computers are for! I created a google script from the SCRIPT editor on my sheet to do it (I think)
function onEdit(e)
{
var row = e.range.getRow(); //Determine the Row # Just added
var sheet = e.range.getSheet(); //Determine the Sheet, probably not needed
var row_string = row.toString(); //Convert the Row Number to a string.
var start_string = "=VLOOKUP(B"; //this is a fixed part of the function I need in the E column of this row.
var end_string = ", 'Scanned Packages Fixed'!A:B, 2, FALSE)"; //This is the fixed part of the function at the end of the row.
var set_lookup_cell = start_string.concat(row_string, end_string); //Smash the strings together to build a full function
sheet.getRange(row,5).setValue(set_lookup_cell); //Put the full function of the string into the proper cell (E)
}
I am not 100% up on how this would get called automatically or if I am missing a way to link it to the sheet itself. When I hit "run" on the code I got this:
TypeError: Cannot read property 'range' of undefined (line 3, file "Code")
I went into my sheet and just added something in the first column of a new row to see what happened, nothing did.
Any help would be super appreciated!
EDIT: Basically, I need Column E of the row to say this
=VLOOKUP(B63, 'Scanned Packages Fixed'!A:B, 2, FALSE) [Where 63 is the row#]
Turns out, the code above does work. I am just not patient and didn't let the sheet update and script run automatically after an update to a row.
Turns out, this isn't triggered when the zap populates the sheet... Only if I do.

How to archive certain rows to another sheet

I am trying to move my team's productivity to another sheet via Apps Script.
On the sheet "Prod" you can see the weekly productivity the team has put in. The "Approved" column has checkboxes where the work can be manually verified.
The second sheet is the "Archives" sheet. Where the Apps Script will move all of the responses from the "Prod" sheet over there.
Apps Script Code
function archive() {
// Get the information
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Prod');
var a = ss.getSheetByName('Archives');
var data = s.getRange('A2:F').getValues();
// Archive the results
for (i in data) {
var write = data[i];
a.appendRow(write);
}
// Clear the results
s.getRange('A2:E').clear();
s.getRange('F2:F').uncheck();
}
The Problem
The code works perfectly fine, however, when it is moving the "Prod" responses over to the "Archives" it includes the empty rows. This is because in the "Approved" column the checkbox is technically false, which means it's included. How would I go about changing the code to only transfer rows that have data in the A column?
Thanks!
I believe your goal as follows.
You want to copy the values from Prod to Archives when the value of column "A" in Prod is not empty.
Modification points:
In your script, all values of var data = s.getRange('A2:F').getValues(); is copied to Archives. So in this case, it is required to check the column "A" of data.
When appendRow() is used in a loop, the process cost will be high. Ref
When above points are reflected to your script, it becomes as follows.
Modified script:
function archive() {
// Get the information
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Prod');
var a = ss.getSheetByName('Archives');
var data = s.getRange('A2:F').getValues();
// Archive the results <--- I modified this part.
var copyValues = data.filter(([a]) => a.toString() != "");
a.getRange(a.getLastRow() + 1, 1, copyValues.length, copyValues[0].length).setValues(copyValues);
// Clear the results
s.getRange('A2:E').clear();
s.getRange('F2:F').uncheck();
}
References:
Benchmark: Reading and Writing Spreadsheet using Google Apps Script
filter()
setValues(values)

Loading data error. Why isn't it loading?

I am trying to set up google sheets to pull data from an API. At first it worked, now it just says "Loading error..." on the cell with the formula.
I have tried it on a new sheet. I have simplified it to one input variable.
function getPrice(item,city){
var url = "https://www.albion-online-data.com/api/v1/stats/prices/"+item+"?
locations="+city;
var jsondata = UrlFetchApp.fetch(url);
var object = JSON.parse(jsondata.getContentText());
return object[0].sell_price_min;
}
The variables are "item" and "city". For which examples include "T1_Wood" item in "Caerleon" city. I'd like to make a table to pull the prices for different items in different cities. Thank you!

Issue with creating an "old-fashioned" mail merge with Google Apps Script

This is a followup to a question I asked yesterday on the Google Apps Script Office Hours Hangout.
The goal of my final script is to create an election process for student elections at the high school where I work using Google Forms. The script has three parts: 1) Create Unique "Voting IDs" (a random 6-digit code) 2) Merge the student data (Name, Homeroom, & Voting ID) on with a template document that will create specific voting instruction for each student. (i.e. an old-fashioned mail merge) 3) Verify the results by checking Voting ID's and removing duplicate votes.
The part of the script that I am having trouble with is the student data merge (step 2). The first dataset is the only one that works. The rest show up as "DocumentBodySection". I have a feeling it is either how I am copying the text from the Document Template or how I am adding the text to the new document.
Spreadsheet w/ Data: https://docs.google.com/spreadsheet/ccc?key=0AierVcXWELCudFI1LU10RnlIVHNsUm11a0dDWEV6M1E
Document Template: (see followup comment for url)
Document Created by Script: https://docs.google.com/document/d/12r2D9SpIVmQYVaasMyMWKjHz6q-ZZyIMEBGHTwlQct8/edit
//Get Settings & Data
ss = SpreadsheetApp.getActiveSpreadsheet();
source_sheet = ss.getSheetByName("Student Data");
settings_sheet = ss.getSheetByName("SETTINGS");
results_column = settings_sheet.getRange("B19").getValue();
source_column = settings_sheet.getRange("B18").getValue();
source_lastrow = source_sheet.getLastRow();
docTemplateID = settings_sheet.getRange("B13").getValue();
docCopyName = settings_sheet.getRange("B14").getValue();
//Merge Student Data with Document
function SendDataMerge () {
// Open docTemplate and Copy Contents to entryTemplate
var docTemplate = DocumentApp.openById(docTemplateID);
var entryTemplate = docTemplate.getActiveSection();
docTemplate.saveAndClose();
// Make a NEW copy of docTemplate
var docTemplate = DocsList.getFileById(docTemplateID);
var docCopy = DocsList.copy(docTemplate, docCopyName);
var docCopyID = docCopy.getId();
// Create Array of Student Data (First, Last, Grouping, VID)
var data = source_sheet.getRange("A2:D"+source_lastrow).getValues();
// Open docCopy for Editing & Clear Contents
var doc = DocumentApp.openById(docCopyID);
var docText = doc.editAsText();
// Run through Student Data
for(var i=0; i<5 /*data.length*/; i++) { //For testing, limit this to 5 entries
var lastName = data[i][0];
var firstName = data[i][1];
var grouping = data[i][2];
var vid = data[i][3];
docText.replaceText('keyLastName', lastName);
docText.replaceText('keyFirstName', firstName);
docText.replaceText('keyGrouping', grouping);
docText.replaceText('keyVID', vid);
docText.appendText('\n*** Appended Text (End of entry) ***');
docText.appendText(entryTemplate);
}
// Save and Close
doc.saveAndClose();
}
I worked around this issue by creating a copy of the template, doing the text replacement and then appending the template elements from the original document into the copy. In particular, I used: var copyTables = templateDoc.getTables(); to fetch and store the tables (as all of my template data was contained in a table) and copyDoc.appendTable(copyTables[0].copy() ); to append the copy (the .copy() at the end seems to work the real magic). This provides the flexibility of updating the template in the friendly Documents interface without having to see a programmer.
I think the problem is with this line:
docText.appendText(entryTemplate);
The variable entryTemplate holds a DocumentBodySection, which is why you are seeing that in the output. If you are trying to append another copy of the original template text you'll need to store that before you enter the loop.
I agree with Eric that appendText(entryTemplate) isn't going to do what you want it to do.
Since you're trying to create one large document with all the students, using a "template" and replacing the text isn't going to work well. I'd suggest instead, creating the "template" in code using the api calls that produce the formatting you want. Then it makes it simple to keep appending new pages of student instructions. Although I think you may run into slowness when the document gets large... I don't know how many students you have.

Categories