I'm new to Google Chrome Extension development and I want to run an apps script from the extension when I click the button from extension. But I'm not sure how to do it and I've checked the guide but couldn't catch the idea. Here are my codes,
script.js
$(document).ready(function () {
$('#btnGet').click(function () {
$(document).load('https://script.google.com/macros/s/AKfycbwpkBW7qKZBeJ011C7j3le4vV8D0SEHu9709mWtEMzJgrJmHnaR/exec');
});
});
Apps Script
function doGet(e){
function newEntry() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var lr = sheet.getLastRow();
sheet.getRange(lr+1, 1, 1, 3).setValues([["First Name", "Last Name", "Email"]]);
Browser.msgBox("New Entry Added!");
}
}
I've managed to run codes from my script.js but I'm not sure how can I run codes from my apps script. How can I run the codes from my apps script?
Short answer
Instead of
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
try
var id = 'spreadsheet-id'; //replace with your spreadsheet id
var sheetName = 'sheet name'; //replace with your sheet name.
var ss = SpreadsheetApp.openByID(id);
var sheet = ss.getSheetbyName(sheetName);
Explanation
The methods that return spreadsheet active objects can be used when the script is being called from the spreadsheet. doGet(e) could interact with a spreadsheet but you should specify which is the one that you want to work on.
References
openByID(id)
getSheetByName(name)
Related
I am copying some data from a sheet on one spreadsheet to a sheet on a separate spreadsheet. I want this function to run everyday, but I only want it to run on the sheets that the user has manually run it on. There are other sheets in the source Spreadsheet that have private information that cannot be shared on the destination Spreadsheet.
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('My Menu')
.addItem('Create Read-Only', 'copyInfo')
.addToUi();
}
// Copies all info to a new sheet in Check Submission
function copyInfo() {
var copySheet = SpreadsheetApp.getActiveSheet();
var sheetName=copySheet.getName();
var pasteSpreadsheet = SpreadsheetApp.openById("1NXmdq6yCKC6oiDAQNXcovj85697__rCeVJiIT_ou_gI")
//Create new sheet if one doesn't exist
var newSheet = pasteSpreadsheet.getSheetByName(sheetName);
if (newSheet != null)
pasteSpreadsheet.deleteSheet(newSheet);
newSheet = pasteSpreadsheet.insertSheet();
newSheet.setName(sheetName);
//Copy and paste data
// Clear the Google Sheet before copy
newSheet.clear({contentsOnly: true});
// get source range
var source = copySheet.getRange("B2:B");
var values = source.getValues();
// get destination range
var destination = newSheet.getRange(1,1,values.length,values[0].length);
// copy values to destination range
destination.setValues(values)
}
I am trying a script to scrape data form a given Sheetname and a given range into 1 main sheet. the problem in this case is that the Spreadsheets (with multiple sheets) are archived in different folders. so I have 1 main folder and in that folder I have archive folders for every year (2012-2022).
I have made script that is going through these folders and get the folder Id's that part is working.
I also have made a script to get the data from the sheet ("Rekenblad") and the range "A11:AY136". I think that also should work.
The part where I connect those 2 function is going wrong. What I would recieve is:
A main file (The script is inside the main file) with:
A sheet (blad1) with a list of all the information of the file
A sheet (blad2) with all data ranges combined. Every time I run this script the data needs to be cleared so I dont have doubles.
The most important is point 2. point 1 is just for me to check if all files are imported correctly and a link so I can easily check those files.
Script looks like this:
function listFolders(folder) {
var sheet = SpreadsheetApp.getActiveSheet().clearContents();
sheet.appendRow(["Name", "URL","ssId", "Type"]);
var folder = DriveApp.getFolderById("FOLDER_ID_PARENT_FOLDER");
var subfolders = folder.getFolders();
while (subfolders.hasNext()) {
//Logger.log(folder);
var name = subfolders.next();
while (subfolders.hasNext()) {
//Logger.log(folder);
var name = subfolders.next();
var files = name.getFiles();
var cnt = 0;
var file;
var ssID
var fileType
var combinedData = []
while (files.hasNext()) {
var file = files.next();
cnt++;
Logger.log(file);
Logger.log(cnt);
data = [
file.getName(),
file.getUrl(),
ssID = file.getId(),
fileType = file.getMimeType(),
];
sheet.appendRow(data);
if (fileType ==="application/vnd.google-apps.spreadsheet"){
ssID = files.getId();
data = GetData(ssID)
data = data.map(function(r){return r.concat([file.getName()]);});
combinedData = combinedData.concat(data);
}
}
var wss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Blad1") ;
ws.getRange("A2:AY").clearContent();
wss.getRange(2, 1, combinedData.length, combinedData[0].length).setValues(combinedData);
}
}
}
function GetData(ssID){
var aa = SpreadsheetApp.openById(ssID);
var wa = aa.getSheetByName("Rekenblad");
var info = wa.getRange("A11:AY136").getValues();
return info
}
I've been struggling to build a specific weekly stock system reports. So to give you a basic overview, I have a mastersheet that I want to generate reports from, triggered by an UI button. The first step however is to create a folder for that week to place the PDF's in. I can create the folder, and I can generate the PDF in my root Google Drive folder, but I can't seem to move the PDF anywhere after that. I have attempted to use .moveTo() but I can't get that to work. Does anyone have any advise?
function onOpen(e)
{
SpreadsheetApp.getUi()
.createMenu('Physical')
.addItem('New folder','newFolder')
.addItem('Generate PDF','generatePDF')
.addToUi();
}
function newFolder(){
var today = new Date();
var week = Utilities.formatDate(today, "Europe/Amsterdam", "w"); //need to find a way to minus 1 for the current week
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId(); //time to create a new folder
var spreadsheetFile = DriveApp.getFileById(spreadsheetId);
var folderId = spreadsheetFile.getParents().next().getId();
var parFolder = DriveApp.getFolderById(folderId)
var destFolder = parFolder.createFolder('Week ' + week);
}
function generatePDF(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var speadsheetFile = ss.getId();
var file = DriveApp.getFileById(speadsheetFile);
var folderId = file.getParents().next().getId();
var pdf = DriveApp.createFile(ss.getBlob())
pdf.moveTo(folderId); //find way to move file either to destination folder or to parent folder
}
Description
These types of situations are hard to test because the circumstances are specific to the OP questioner. However, I believe this will work.
Using the PropertyService Script Properties, store the newly created folderId and then get that id from Script Properties to move the file.
A note of caution, I didn't check for the case if the week changes and a new folder is not created, the pdf will go to the previous week folder.
Regarding creating a button and linking a function to the button see this article Buttons in Google Sheets
Script
function newFolder(){
var today = new Date();
var week = Utilities.formatDate(today, "Europe/Amsterdam", "w"); //need to find a way to minus 1 for the current week
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId(); //time to create a new folder
var spreadsheetFile = DriveApp.getFileById(spreadsheetId);
var folderId = spreadsheetFile.getParents().next().getId();
var parFolder = DriveApp.getFolderById(folderId);
var folderName = 'Week '+week;
// check if folder already exists
var subFolders = parFolder.getFoldersByName(folderName);
var destFolder = null;
if( subFolders.hasNext() ) {
SpreadsheetApp.getUi().alert("Folder "+folderName+" already exists");
destFolder = subFolders.next();
}
else {
destFolder = parFolder.createFolder(folderName);
}
// store folder id to Script Properties
var props = PropertiesService.getScriptProperties();
props.setProperty("foldeId",destFolder.getId());
}
function generatePDF(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get folder id from Script Properties
var folderId = PropertiesService.getScriptProperties("folderId");
if( !folderId ) {
SpreadsheetApp.getUi().alert("Property folderId not found");
return;
}
var pdf = DriveApp.createFile(ss.getBlob())
pdf.moveTo(folderId); //find way to move file either to destination folder or to parent folder
}
Reference
SpreadsheetApp.getUi().alert()
PropetiesService
I want to write a app which generates a spreadsheet in my google-drive with the user input data with google-app scripts.
For doing so I have several JavaScript-functions I want to execute one after the other:
function createSpreadsheet(name){
var ss=SpreadsheetApp.create(name);
var ssID = ss.getID()
}
function writeData(data){
var s = ss.getSheets()[0];
s.getRange('A1').setValue(data);
}
which are called by the frond-end script via:
<script>
function parse_to_backend(){
var name = document.getElementById("user_name").value;
var data = document.getElementById("user_data").value;
google.script.run.createSpreadsheet(name);
google.script.run.writeData(data);
};
</script>
how can I achieve that the writeData knows ssID the ID of the spreadsheet (I can not return values to the frontend with google.script.run and parse it as an argument)?
You want to create new Spreadsheet from HTML side.
You want to put the value to the created Spreadsheet from HTML side.
In your situation, you don't want to put writeData() in createSpreadsheet(). Namely, you want to individually use both functions.
If my understanding is correct, how about this answer? Please think of this as just one of several answers.
At first, the modification point is as follows.
Modification point:
When you run the script as follows,
google.script.run.createSpreadsheet(name);
google.script.run.writeData(data);
Function of writeData() is run before the function of createSpreadsheet() is finished, because google.script.run works by the asynchronous process. In order to avoid this, in this sample script, withSuccessHandler() is used.
About the modified script, I introduce 2 patterns. Please select one of them.
Pattern 1:
In this pattern, file ID is returned from createSpreadsheet() and the value is put to the created Spreadsheet using the file ID.
Code.gs: Google Apps Script
function createSpreadsheet(name){
var ss = SpreadsheetApp.create(name);
var ssID = ss.getId();
return ssID;
}
function writeData(id, data){
var ss = SpreadsheetApp.openById(id);
var s = ss.getSheets()[0];
s.getRange('A1').setValue(data);
}
index.html: HTML and Javascript
<script>
function parse_to_backend(){
var name = document.getElementById("user_name").value;
var data = document.getElementById("user_data").value;
google.script.run.withSuccessHandler((id) => {
google.script.run.writeData(id, data);
}).createSpreadsheet(name);
};
</script>
Pattern 2:
In this pattern, file ID is saved by PropertiesService and the value is put to the created Spreadsheet using the file ID got from PropertiesService. In this case, the file ID is saved to PropertiesService. So the created Spreadsheet can be also used by other action of Javascript using the file ID got from PropertiesService.
Code.gs: Google Apps Script
function createSpreadsheet(name){
var ss = SpreadsheetApp.create(name);
var ssID = ss.getId();
PropertiesService.getScriptProperties().setProperty("ssID", ssID);
}
function writeData(data){
var id = PropertiesService.getScriptProperties().getProperty("ssID");
var ss = SpreadsheetApp.openById(id);
var s = ss.getSheets()[0];
s.getRange('A1').setValue(data);
}
index.html: HTML and Javascript
<script>
function parse_to_backend(){
var name = document.getElementById("user_name").value;
var data = document.getElementById("user_data").value;
google.script.run.withSuccessHandler(() => {
google.script.run.writeData(data);
}).createSpreadsheet(name);
};
</script>
References:
Class google.script.run
withSuccessHandler()
Class PropertiesService
If I misunderstood your question and this answer was not what you want, I apologize.
I have the following code:
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var task = ss.getRange(2,4).getValue(); //ss.getRange("A2").getValue();
var who = Session.getActiveUser();
var date = new Date();
function start() {
var last = ss.getLastRow();
ss.getRange(last+1, 1).setValue(task);
ss.getRange(last+1, 2).setValue(who);
ss.getRange(last+1, 3).setValue(date);
}
function end() {
var last = ss.getLastRow();
ss.getRange(last, 4).setValue(date);
ss.getRange(1,1).setValue(date);
ss.getRange(1,2).setValue(ss.getRange(last+1, 3));
}
in a Google Sheet script. It works on desktop - basically what it does is it will track when a user starts and stops a given task.
The sheet shows up fine in the Sheets app, but the script doesn't run. What needs to happen so that it will run? Is there some way to run the programs on the app?