Put a = before text jump - google-apps-script

Hello I made this script to export the data from a column to a .txt on my google drive
function maquinasBonusHunt() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var range = sheet.getRange('G3:G' + sheet.getLastRow());
var rows = range.getValues().filter(([g]) => g.toString() != "");
var fileName="maquinas.txt";
var folderName="Videos";
var data = rows.splice(0);
var str = data.map(function(e) {return e.join()}).join("\n");
var separador = [" - ", " = "];
var content = str;
// get list of folders with matching name
var folderList = DriveApp.getFoldersByName(folderName);
if (folderList.hasNext()) {
// found matching folder
var folder = folderList.next();
// search for files with matching name
var fileList = folder.getFilesByName(fileName);
if (fileList.hasNext()) {
// found matching file - append text
var file = fileList.next();
var combinedContent = content;
file.setContent(combinedContent);
}
else {
// file not found - create new
folder.createFile(fileName, content);
}
}
}
Everything is fine but, I need to put a "=" before they jump to other text like y show you on the screenshot.
https://i.stack.imgur.com/xvXDA.png

I believe your goal as follows.
You want to add = to the last character of each row.
In order to achieve your goal, I would like to propose the following modification.
Pattern 1:
In this pattern, = is added when join is run.
From:
var str = data.map(function(e) {return e.join()}).join("\n");
To:
var str = data.map(function(e) {return e.join()}).join("=\n") + "=";
Pattern 2:
In this pattern, = is added after filter was used.
From:
var rows = range.getValues().filter(([g]) => g.toString() != "");
To:
var rows = range.getValues().filter(([g]) => g.toString() != "").map(([v]) => [v + "="]);
References:
join()
filter()
map()

Related

Method template.copy is not working - Google Script

I am facing a problem that is leaving me without a real solution.
I want that the script create a new Google Doc copy from a template, then transfer data from Sheet toward the new Doc.
The script is running without a bug, but fail to create a copy of the document as it supposed to do.
function transferData() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Tour de ContrĂ´le");
var templateId = "119ORijiWNQEdpG4KqjNCYzilbf_ob7SMdOPXUK3woMQ";
var folder = DriveApp.getFolderById("166g1akWuHR3MtoDzbh9ydMhEpr4euCts");
var data = sheet.getDataRange().getValues();
for (var i = 3; i < data.length; i++) {
if (data[i][12] === true) {
var nom = data[i][3];
var nFonction = data[i][6];
var template = DocumentApp.openById(templateId);
var newDoc = template.copy("Mouvement_" + nFonction + "_" + nom + "_EMBA");
newDoc.getAs(MimeType.GOOGLE_DOCS).getFile().moveTo(folder);
var docBody = newDoc.getBody();
var matricule = data[i][4];
var compta = data[i][16];
var division = data[i][1];
var fonction = data[i][6];
var respDoss = sheet.getRange("GDD!B3").getValue();
var endosGDD = sheet.getRange("GDD!B6").getValue();
var sign = sheet.getRange("GDD!B7").getValue();
docBody.replaceText("{Nom}", nom);
docBody.replaceText("{Matricule}", matricule);
docBody.replaceText("{NFonction}", nFonction);
docBody.replaceText("{Compta}", compta);
docBody.replaceText("{division}", division);
docBody.replaceText("{Fonction}", fonction);
docBody.replaceText("{RespDoss}", respDoss);
docBody.replaceText("{EndosGDD}", endosGDD);
docBody.replaceText("{Sign}", sign);
}
}
}
There's no DocumentApp.openById(templateId).copy() method. To make a copy of a doc you should use Driveapp instead.
You should change these lines of code
var template = DocumentApp.openById(templateId);
var newDoc = template.copy("Mouvement_" + nFonction + "_" + nom + "_EMBA");
newDoc.getAs(MimeType.GOOGLE_DOCS).getFile().moveTo(folder);
For these ones:
var template = DriveApp.openById(templateId);
var newDoc = template.makeCopy("Mouvement_" + nFonction + "_" + nom + "_EMBA", folder);
makeCopy(name, destination)
With SpreadsheetApp you can make a copy of a spreadsheet but you can't choose the folder where it will be created (it's created in the same folder where your spreadsheet "file" is located).
copy(name)
Finally, I modified const googleDocTemplate = DriveApp.getFolderById by const googleDocTemplate = DriveApp.getFileById
It worked.
Thanks for your help.
function transferData() {
//Here we store the sheet as a variable
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Tour de ContrĂ´le");
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('119ORijiWNQEdpG4KqjNCYzilbf_ob7SMdOPXUK3woMQ');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('166g1akWuHR3MtoDzbh9ydMhEpr4euCts');
const respDoss = sheet.getRange("GDD!B3").getValue();
const endosGDD = sheet.getRange("GDD!B6").getValue();
const sign = sheet.getRange("GDD!B7").getValue();
const rows = sheet.getDataRange().getValues();
//Logger.log(rows)
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Generated date', if so we skip it
//if (row[16] === true);
//Here we check if the value in column Q (index 17) is true, if not we skip this row
if (index >= 4) {
if (row[17] !== true){
return;
}
}
Logger.log(rows);
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`Mouvement_${row[6]}, ${row[3]}_EMBA` , destinationFolder);
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId());
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
...

Master Data Sheet from a folder without Blank spaces between pulled files

I know there has been a lot said on the topic of a Master Sheet already. However as I haven't found the relevant answer to my question, I was hoping you could be so kind and help. The issue is very trivial I have a script that looks into the specific folder and grabs the data from those sheets. I just don't know how to modify it so that it doesn't retrieve the empty cells too ( due to the import range function sitting in the subfiles). So in the nutshell, it would be great if the code will only retrieve a range of data, for column "A" <> ""
function myFunction() {
var folder = DriveApp.getFolderById("xcv");
var filesInterator = folder.getFiles();
var file;
var fileType;
var ssID;
var combinedData = [];
var data;
while(filesInterator.hasNext()){
file = filesInterator.next();
fileType = file.getMimeType();
if(fileType === "application/vnd.google-apps.spreadsheet"){
ssID = file.getId();
data = getDataFromSpreadsheet(ssID);
combinedData = combinedData.concat(data);
} // if ends here
} // while loops ends here
Logger.log(combinedData.length);
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Master");
ws.getRange("A2:BK").clearContent();
ws.getRange(2,1,combinedData.length,combinedData[0].length).setValues(combinedData);
}
function getDataFromSpreadsheet(ssID) {
var ss = SpreadsheetApp.openById(ssID);
var ws = ss.getSheetByName("ABC");
var data = ws.getRange("A2:KB" + ws.getLastRow()).getValues();
return data;
}
Try this:
function getDataFromSpreadsheet(ssID) {
var ss = SpreadsheetApp.openById(ssID);
var ws = ss.getSheetByName("ABC");
var data = ws.getRange("A2:KB" + ws.getLastRow()).getValues().filter(r => r[0] != ''});
return data;
}
Array.filter()

Add another row content to the .txt

I just got to work the script to export the content of a row to a .txt and put a =, but now i would like to know how i can add the content of other row to the .txt like i will show on the screenshot.
This is the code that i currently have but i dont properly make to work.
function exporttotxt() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var range = sheet.getRange('G3:G' + sheet.getLastRow());
var rows = range.getValues().filter(([g]) => g.toString() != "");
var range2 = sheet.getRange('I3:I' + sheet.getLastRow());
var rows2 = range2.getValues().filter(([i]) => i.toString() != "");
var fileName="exported.txt";
var folderName="Videos";
var data = rows.splice(0);
var data2 = rows2.splice(0);
var str = data.map(function(e) {return e.join()}).join("=") + "=" + data2.map(function(e) {return e.join()}).join("\n");
var content = str;
// get list of folders with matching name
var folderList = DriveApp.getFoldersByName(folderName);
if (folderList.hasNext()) {
// found matching folder
var folder = folderList.next();
// search for files with matching name
var fileList = folder.getFilesByName(fileName);
if (fileList.hasNext()) {
// found matching file - append text
var file = fileList.next();
var combinedContent = content;
file.setContent(combinedContent);
}
else {
// file not found - create new
folder.createFile(fileName, content);
}
}
}
I believe your goal as follows.
You want to create a text by merging the values of colums "G" and "I".
In your situation, how about retrieving the values from the columns "G" and "I" by one getValues? By this, the process cost will be lower and the script becomes a bit simple. When this is reflected to your script, it becomes as follows.
From:
var range = sheet.getRange('G3:G' + sheet.getLastRow());
var rows = range.getValues().filter(([g]) => g.toString() != "");
var range2 = sheet.getRange('I3:I' + sheet.getLastRow());
var rows2 = range2.getValues().filter(([i]) => i.toString() != "");
var fileName="exported.txt";
var folderName="Videos";
var data = rows.splice(0);
var data2 = rows2.splice(0);
var str = data.map(function(e) {return e.join()}).join("=") + "=" + data2.map(function(e) {return e.join()}).join("\n");
var content = str;
To:
var range = sheet.getRange('G3:I' + sheet.getLastRow());
var rows = range.getValues().filter(([g, _, i]) => g.toString() != "" && i.toString() != "");
var fileName="exported.txt";
var folderName="Videos";
var data = rows.splice(0);
var str = data.map(([g, _, i]) => `${g}=${i}`).join("\n");
var content = str;

Google Spread Sheet Export CSV in the same folder

I am using the script below, working very well (thanks to Ted Bell).
But I need to adapt it because I need the CSV file saved in the same folder as the spreadsheet.
Could you please help me with this matter?
The code below creates a new folder each time on My Drive.
The CSV is ok regarding its name and its format: with semicolon delimiter.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{
name: "export as csv file",
functionName: "saveAsCSV"
}];
ss.addMenu("CSV Export", csvMenuEntries);
var a1 = ss.getRange("A1").getValue();
var name = "MyCompanyName_"+a1;
ss.rename(name);
};
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssname = ss.getName();
var sheet = ss.getActiveSheet();
var sheetname = sheet.getSheetName();
//Logger.log("DEBUG: the name of the spreadsheet is "+ssname);//DEBUG
//Logger.log("DEBUG: the sheet name is "+sheetname);// DEBUG
//// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ssname.toLowerCase() + '_' +
sheetname.toLowerCase().replace(/ /g, '_') + '_csv_' + new Date().getTime());
//Logger.log("DEBUG: the folder name is "+folder);//DEBUG
// append ".csv" extension to the sheet name
var fileName = ssname + '_' + sheetname + ".csv";
// convert all available sheet data to csv format
var csvFile = so_4225484202(fileName);
// create a file in the Docs List with the given name and the csv data
folder.createFile(fileName, csvFile);
Browser.msgBox('Files are waiting in a folder named ' + folder.getName());
}
function isValidDate(date) {
return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
function so_4225484202(filename) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var paramsheet = ss.getSheetByName("Parameters");
var linearray = [];
var rowdata = [];
var csv = "";
var fieldvalue = "";
var param = paramsheet.getRange(2, 2, 2);
var paramValues = param.getValues();
//Logger.log("DEBUG: parameters = "+param.getA1Notation());//DEBUG
var fieldDelimiter = paramValues[0][0];
var textDelimiter = paramValues[1][0];
//Logger.log("DEBUG: field delimiter: "+fieldDelimiter+", text delim:
"+textDelimiter);//DEBUG
var rangeData = sheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
//Logger.log("DEBUG: lastColumn: "+lastColumn+", lastRow: "+lastRow);//DEBUG
// Get array of values in the Data Range
var rangeValues = rangeData.getValues();
// Loop through array and build values for csv
for (i = 0; i < lastRow; i++) {
for (j = 0; j < lastColumn; j++) {
var value = rangeValues[i][j];
var theType = typeof value;
if (theType === "object") {
var testdate = isValidDate(value);
//Logger.log("if typeof is object: testdate: "+testdate);//DEBUG
var testtype = typeof testdate;
if (testtype === "boolean") {
// variable is a boolean
//Logger.log("Its a date");//DEBUG
theType = "date";
} else {
//Logger.log("Its not a date");//DEBUG
}
}
if (theType === "string") {
value = textDelimiter + value + textDelimiter;
}
rowdata.push([value]);
};
//Logger.log("DEBUG: rowdata: "+rowdata);//DEBUG
csv += rowdata.join(fieldDelimiter) + "\n";
var rowdata = [];
};
//Logger.log("DEBUG: csv: "+csv);//DEBUG
return csv;
}
You want to create the CSV file in the same folder of the active Spreadsheet.
You want to achieve this by modifying your script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification point:
In order to retrieve the folder of the active Spreadsheet, DriveApp.getFileById(ss.getId()).getParents().next() is used for retrieving the folder.
Modified script:
Please modify the function of saveAsCSV() in your script as follows.
From:
var folder = DriveApp.createFolder(ssname.toLowerCase() + '_' + sheetname.toLowerCase().replace(/ /g, '_') + '_csv_' + new Date().getTime());
To:
var folder = DriveApp.getFileById(ss.getId()).getParents().next();
References:
getId()
getFileById()
getParents()
If I misunderstood your question and this was not the direction you want, I apologize.

How to export google sheet as CSV by selected columns

I have a Google sheet want to export as CSV file. But there are 2 columns in the sheet I don't want to export.
For example, in the picturecolumn, I don't want to export column "N" and "P"
Here are the Apps Script code I wrote for export
function menu() {
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('Menu');
var item = menu.addItem('PICC', 'picc');
var item2 = menu.addItem('Export to CSV', 'csv');
item.addToUi();
item2.addToUi()
};
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{name: "Download Primary Time File", functionName: "saveAsCSV"}];
//ss.addMenu("Creating a Timetable", csvMenuEntries);
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('Menu');
var item = menu.addItem('PICC', 'picc');
var item2 = menu.addItem('Export to CSV', 'csv');
item.addToUi();
item2.addToUi()
};
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("sheet1");
// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + new Date().getTime());
// append ".csv" extension to the sheet name
fileName = sheet.getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
var file = folder.createFile(fileName, csvFile);
//File downlaod
var downloadURL = file.getDownloadUrl().slice(0, -8);
showurl(downloadURL);
}
function showurl(downloadURL) {
var app = UiApp.createApplication().setHeight('60').setWidth('150');
//Change what the popup says here
app.setTitle("Your timetable CSV is ready!");
var panel = app.createPopupPanel()
//Change what the download button says here
var link = app.createAnchor('Click here to download', downloadURL);
panel.add(link);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function convertRangeToCsvFile_(csvFileName, sheet) {
// get available data range in the spreadsheet
var activeRange = sheet.getDataRange();
try {
var data = activeRange.getValues();
var csvFile = undefined;
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var row = 1; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
As you can see, I used for loop to export the rows and columns, how can I make change to let the two columns not showing in the export CSV
How about this modification?
Modification points :
Modify convertRangeToCsvFile_().
From data retrieved by getValues(), it removes the columns "N" and "P".
In order to reflect this, please modify as follows.
From :
var data = activeRange.getValues();
var csvFile = undefined;
To :
var data = activeRange.getValues();
data = data.map(function(e){return e.filter(function(_, i){return i != 13 && i != 15})}); // Added
var csvFile = undefined;
If I misunderstand your question, please tell me. I would like to modify it.