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.
Related
I have an API response that I'm trying to place in my spreadsheet.
I managed to figure out how to call it using the following code but it all goes to the first cell. How do I make each value go to a different cell?
function callCandles() {
var response = UrlFetchApp.fetch("https://api-pub.bitfinex.com/v2/candles/trade:1D:tBTCUSD/hist?limit=1000&start=1577841154000&end=1606785154000&sort=-1");
Logger.log(response.getContentText());
var fact = response.getContentText();
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1,1).setValue([fact])
}
This is the correct way to set the values in a sheet. Avoid using for loops with appendRow. It can be extremely slow for a relatively small amount of data.
Suggested solution:
function myFunction() {
var response = UrlFetchApp.fetch("https://api-pub.bitfinex.com/v2/candles/trade:1D:tBTCUSD/hist?limit=1000&start=1577841154000&end=1606785154000&sort=-1");
var fact = JSON.parse(response.getContentText());
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(sheet.getLastRow()+1,1,fact.length,fact[0].length).setValues(fact);
}
Try something like this,
var response = UrlFetchApp.fetch("https://api-pub.bitfinex.com/v2/candles/trade:1D:tBTCUSD/hist?limit=1000&start=1577841154000&end=1606785154000&sort=-1");
Logger.log(response.getContentText());
var fact = JSON.parse(response.getContentText());
var sheet = SpreadsheetApp.getActiveSheet();
fact.forEach(row => {
sheet.appendRow(row);
});
Hope you got some idea.
I've never used Javascript before and i've been trying for ages to do this but with no luck, and I can't find any previous people trying.
I want to copy the text data straight from this txt document in my drive, it is possible to do this fine manually but I want it to be done daily automatically instead.
The text document;
Boxes Made,3
Target Percentage,34
Hourly Rate,2
If I import this into a spreadsheet with these settings its perfect;
Import Settings
And it imports like this;
After Import
Now I need to try and automate this so that a script imports it automatically.
The script I have so far doesn't work, please help.
Current script;
function AutoImporter (Source)
{
var Source = DriveApp.getFilesByName('DailyData.txt');
var TextContents = Source.copyText();
var Target = SpreadsheetApp.getActiveSheet();
Target.appendText(TextContents[1]);
}
--edit
Some guy just sent me a script that seems closer but still didn't work;
function autoCSV() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getActiveSheet();
var r=s.getActiveCell();
var id="DailyData.txt";//<<<<<enter the ID of the text file
var f3=DriveApp.getFileById(id);
var lst1=f3.getBlob().getDataAsString().split('\n').map(function(x) {return x.split(',')});
var ncols=1,i,lst2=[];
for (i in lst1) {if (lst1[i].length>ncols) ncols=lst1[i].length;}
for (i=0;i<ncols;i++) lst2.push('');
for (i in lst1) lst1[i]=lst1[i].concat(lst2.slice(0,lst2.length-lst1[i].length));
s.getRange(r.getRow(), r.getColumn(), lst1.length, ncols).setValues(lst1);
}
You may read text file from Google Drive this way:
'use strict'; // <- Always use strict mode.
function foo() {
var fileName = 'DailyData.txt';
var files = DriveApp.getFilesByName(fileName);
if (!files.hasNext()) {
throw new Error('No file with name:' + fileName);
}
// We take only the first file among all files with such name.
var file = files.next();
var text = file.getBlob().getDataAsString('utf8');
Logger.log(text);
// Now you have to parse the file.
}
Documentation:
DriveApp.getFilesByName returns collection of Files.
File.getBlob returns Blob.
Blob.getDataAsString returns String.
I'm new to google scripts and was able to manipulate some code to work for a project, but it will no longer work as a result of the following:
ReferenceError: "DocsList" is not defined.Dismiss
Here is the code I have:
function report() {
var folder = DocsList.getFolder("FOLDER NAME HERE");
var contents = folder.getFiles();
var file;
var data;
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clearContents();
sheet.appendRow(["URL", "Employer"]);
for (var i = 0; i < contents.length; i++) {
file = contents[i];
var qaDate,qaERName
if (file.getFileType()==DocsList.FileType.SPREADSHEET) {
var dataSheet = SpreadsheetApp.open(file).getSheetByName("data");
var configSheet = SpreadsheetApp.open(file).getSheetByName("Config");
I have a few references to DocsList, I've done some digging and cant figure out how to get something similar to getfolder
Let's start with the first line:
var folder = DocsList.getFolder("FOLDER NAME HERE");
If you go to the documentation, and look at all the methods for DriveApp that have anything to do with folders, you'll see four methods:
getFolderById(id)
getFolders()
getFoldersByName(name)
getRootFolder()
There is only one method that will get just one folder, getFolderById(id). If you are getting the same folder every time, and you can easily get the ID, then use that option. If that is not possible, then you can use getFoldersByName(name), but that gets multiple folders. Even though it gets multiple folders, you can easily get just the first folder.
var folders = DriveApp.getFoldersByName('Folder Name');
var folder = folders.next();
Logger.log('folder: ' + folder.getName());
So, start there, and make that change.
I´m learning how to use the Google Scripts, I saw a video on the youtube and I wrote this code based on the video. It will be a dashboard, but the problem I have is: In this spreadsheet, I have more than one Sheet. How can I "tell" the code which sheet it would have to check? In my case the Sheet ID is 8.
I think this would be the only "mistake" in the code!
Thanks for helping!
function doGet() {
// Identify the spreadsheet where the data is stored.
var ss = SpreadsheetApp.openById('0AjizIuAuEzaydFlsRDRrTkZSekROaWNZNV9QbjRDdUE')
var data = ss.getDataRange();
// Create all the filters
var clienteFilter = Charts.newNumberRangeFilter().setFilterColumnIndex(1).build();
var pedidoFilter = Charts.newNumberRangeFilter().setFilterColumnIndex(2).build();
var necessidadeFilter = Charts.newCategoryFilter().setFilterColumnIndex(3).build();
var entregaFilter = Charts.newCategoryFilter().setFilterColumnIndex(4).build();
var notaconsultorFilter = Charts.newNumberRangeFilter().setFilterColumnIndex(5).build();
var notaentregadorFilter = Charts.newNumberRangeFilter().setFilterColumnIndex(6).build();
var recomendariaFilter = Charts.newCategoryFilter().setFilterColumnIndex(8).build();
var atencaoFilter = Charts.newCategoryFilter().setFilterColumnIndex(9).build();
var servicosFilter = Charts.newCategoryFilter().setFilterColumnIndex(10).build();
var entregadorFilter = Charts.newCategoryFilter().setFilterColumnIndex(11).build();
// Create all the charts
var pieChart = Charts.newPieChart()
.setDataViewDefinition(Charts.newDataViewDefinition().setColumns([11,6]))
.build();
// Create the dashboard
var dashboard = Charts.newDashboardPanel().setDataTable(data)
.bind([clienteFilter, pedidoFilter, necessidadeFilter, entregaFilter, notaconsultorFilter, notaentregadorFilter, recomendariaFilter, atencaoFilter, servicosFilter, entregadorFilter],[pieChart])
.build();
// Create the webapp and bind together the filters and charts
var app = UiApp.createApplication();
var filterPanel = app.createVerticalPanel();
var chartPanel = app.createHorizontalPanel();
filterPanel.add(clienteFilter).add(pedidoFilter).add(necessidadeFilter).add(entregaFilter).add(notaconsultorFilter).add(notaentregadorFilter).add(recomendariaFilter).add(atencaoFilter).add(servicosFilter).add(entregadorFilter).setSpacing(10);
chartPanel.add(pieChart).setSpacing(10);
// Format the dashboard layout
dashboard.add(app.createVerticalPanel().add(filterPanel).add(chartPanel));
app.add(dashboard);
return app;
}
in your code , ss comes for a spreadSheet object, which is -way of speaking - the "parent" of the included sheets.
This class (spreadsheet object) has a couple of methods to get sheets that are described in the documentation, for example getSheetByName('name of the sheet') or getSheets() which returns an array of sheet objects. In this case you can chose which one you use with getSheets()[number]
This is supposed to read in a CSV and then write it to bigquery. When it runs, however, nothing is written, and there are no errors logged. I read that I need to write a csv and then turn it into an Octet Stream. I am not sure whether or not this is compatible with google bigquery.
function test(){
try{
var tableReference = BigQuery.newTableReference();
tableReference.setProjectId(PROJECT_ID);
tableReference.setDatasetId(datasetId);
tableReference.setTableId(tableId);
var schema = "CUSTOMER:string, CLASSNUM:integer, CLASSDESC:string, CSR:string, CSR2:string, INSURANCE:string, REFERRALGENERAL:string, REFERRALSPECIFIC:string, NOTES:string, INMIN:integer, INHR:integer, OUTMIN:integer, OUTHR:integer, WAITMIN:integer, WAITHR:integer, DATETIMESTAMP:float, DATEYR:integer,DATEMONTH:integer, DATEDAY:integer";
var load = BigQuery.newJobConfigurationLoad();
load.setDestinationTable(tableReference);
load.setSourceUris(URIs);
load.setSourceFormat('NEWLINE_DELIMITED_JSON');
load.setSchema(schema);
load.setMaxBadRecords(0);
load.setWriteDisposition('WRITE_TRUNCATE');
var configuration = BigQuery.newJobConfiguration();
configuration.setLoad(load);
var newJob = BigQuery.newJob();
newJob.setConfiguration(configuration);
var loadr = DriveApp.getFilesByName("test.csv");
var x = loadr.next().getBlob();
Logger.log(x.getDataAsString());
var d = DriveApp.getFilesByName("test.csv");
var id = d.next().getId();
Logger.log(id);
var data = DocsList.getFileById(id).getBlob().getDataAsString();
var mediaData = Utilities.newBlob(data, 'application/octet-stream');
BigQuery.Jobs.insert(newJob, PROJECT_ID, mediaData)
}
catch(error){Logger.log("A" + error.message);}
}
Your sourceFormat is wrong for CSV files:
The format of the data files. For CSV files, specify "CSV". For
datastore backups, specify "DATASTORE_BACKUP". For newline-delimited
JSON, specify "NEWLINE_DELIMITED_JSON". The default value is CSV.
https://developers.google.com/bigquery/docs/reference/v2/jobs#configuration.load.sourceUris
On the other hand I think you don't need at all the load.setSourceUris(URIs); since you try to load from local file, and not from Google Cloud Storage. Check this python example https://developers.google.com/bigquery/loading-data-into-bigquery