Objective: Export data from one sheet into a CSV created in Drive.
Currently the code is creating the spreadsheet with correct naming convention.
Issue: Data is not merging from the sheet into the created CSV.
The spreadsheet contains 1 cell with the word "undefined".
function exportCSV() {
var ui = SpreadsheetApp.getUi()
var app = SpreadsheetApp;
var ss = app.openById('REDACTED');
var exportSheet = ss.getSheetByName('Export');
var placementSheet = ss.getSheetByName('Placement Builder')
var csvName = placementSheet.getRange('B12').getValue();
var fileName = csvName + ".csv";
var csvFile = convertRangeToCsvFile_(fileName);
var folderId = placementSheet.getRange('B11').getValue();
DriveApp.getFolderById(folderId).createFile(fileName, csvFile, MimeType.CSV);
function convertRangeToCsvFile_(csvFileName) {
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Export').getActiveRange();
try {
var data = ws.getValues();
Logger.log(ws);
var csvFile = undefined;
if (data.length > 1) {
var csv = "";
for (var row = 0; 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] + "\"";
}
}
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);
}
}
}
Related
dears
I need your support to edit this function as I need to copy data with formatting
This is the equation I working on
function copyRows()
{
var copySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet1');
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet2');
var dataRange = dataSheet.getDataRange();
var dataValues = dataRange.getValues();
for(var i = 1; i < dataValues.length; i++)
{
if(dataValues[i][29] === 'done')
{
copySheet.appendRow([dataValues[i][0],
dataValues[i][1],
dataValues[i][2],
dataValues[i][3],
dataValues[i][4]]);
}
}
for(var i = 1; i < dataValues.length; i++)
{
if(dataValues[i][29] === 'done')
{
var clearRow = i+1;
dataSheet.getRange('A' + clearRow + ':AC' + clearRow).clear();
}
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.
I have an spreadsheet with 4 sheets that I need in .CSV format. By now, I have a script that sends me the .csv files to my email, but I need to automacally save it into a google drive folder, do you have any ideas ?
This is my actual script:
function Csv(){
var ss = SpreadsheetApp.openById('spreadsheetID');
var url1 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet1";
var url2 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet2";
var url3 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet3";
var url4 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet4";
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
var blob1 = UrlFetchApp.fetch(url1, params).getBlob();
blob1.setName("File1" +".csv");
var blob2 = UrlFetchApp.fetch(url2, params).getBlob();
blob2.setName("File2" +".csv");
var blob3 = UrlFetchApp.fetch(url3, params).getBlob();
blob3.setName("File3" +".csv");
var blob4 = UrlFetchApp.fetch(url4, params).getBlob();
blob4.setName("File4" +".csv");
MailApp.sendEmail("myemail#gmail.com", "Subject", "Body", {attachments: [blob1,blob2,blob3,blob4]});
}
Thanks!
you can check out the below script. Hope it will help you to manage your sheets as you expected.
/*
* script to export data in all sheets in the current spreadsheet as individual csv files
* files will be named according to the name of the sheet
* author: Shotez
*/
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{name: "export as csv files", functionName: "saveAsCSV"}];
ss.addMenu("csv", csvMenuEntries);
};
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + new Date().getTime());
for (var i = 0 ; i < sheets.length ; i++) {
var sheet = sheets[i];
// 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
folder.createFile(fileName, csvFile);
}
Browser.msgBox('Files are waiting in a folder named ' + folder.getName());
}
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 = 0; 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);
}
}
After running the script just check your google drive for the folder which is containing the .csv files.
I've created (actually, modified) a script to export a CSV file for a specific range within a Google Sheet. It is working well:
function convertRangeToCsvFile_(csvFileName,delimiter) {
// Get the selected range in the spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var ws = sheet.getRange("F3:G501");
try {
var data = ws.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 = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(delimiter) != -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(delimiter) + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
However, I now want to set it up so that the script iterates over three different ranges of cells and concatenates them all into one big long CSV. I'm trying to do this using a for loop, however when I do so the script returns an error:
TypeError: Cannot find function getValues in object 0.
From what I can tell, this might be some kind of scope issue, but I can't for the life of me find anything that helps me solve it. Here is my broken code:
function convertRangeToCsvFile_(csvFileName,delimiter) {
// Get the selected range in the spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var ranges = [sheet.getRange("F3:G501"),sheet.getRange("H3:I501"),sheet.getRange("J3:K501")];
try {
for (var ws in ranges) {
var data = ws.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 = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(delimiter) != -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(delimiter) + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
I've tried adjusting where the for loop starts and ends (originally it did not take in the var data = ws.getValues(); line, which of course caused an "undefined" error.)
But despite my best efforts, I can't find any information out there that addresses this question in a way that my (very inexperienced) brain can parse!
Any input is much appreciated.
You are looping ranges as an object and not an array therefore the first key you find is 0
Loop with an incremental for loop instead:
var ws;
for (var w =0; w < ranges.length; w += 1) {
ws = ranges[w];
The rest I haven't checked but if you've changed nothing else should be fine.
Please bear with me as I'm a newbie, but I have formed a list of the ID's of the spreadsheets that I have in a folder which I have stored on a sheet in 1 column. I am trying to execute a script that will go into each of those spreadsheets and delete sheets of a given name if they are in there. So far this is what I have but I'm not sure where I screwed up:
function cleanAllOld () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('fileList');
var numberFiles = sheet.getLastRow();
for (var i=0; i<numberFiles; i++) {
try{
// File to be cleaned
var fileID = sheet.getRange(2+i, 1, numberFiles-1).getValues();
var destination = SpreadsheetApp.openById(fileID[i]);
var sheet1 = destination.getSheetByName('Copy of CALC');
var sheet2 = destination.getSheetByName('Copy of Print');
var sheet3 = destination.getSheetByName('Copy of Markbook');
if (destination.sheet1 == null) {
} else {
destination.deleteSheet(sheet1);
}
if (destination.sheet2 == null) {
} else {
destination.deleteSheet(sheet2);
}
if (destination.sheet3 == null) {
} else {
destination.deleteSheet(sheet3);
}
}
catch (e) {
Logger.log(e);
}
}
}
FIXED SCRIPT
function cleanAllOld () {
var ss = SpreadsheetApp.openById('...');
var sheet = ss.getSheetByName('fileList');
var numberFiles = sheet.getLastRow();
for (var i=0; i<numberFiles; i++) {
// File to be cleaned
var fileID = sheet.getRange(1, 1, numberFiles).getValues();
Logger.log('fileID[i][0]: ' + fileID[i][0]);
var destination = SpreadsheetApp.openById(fileID[i][0]);
var sheet1 = destination.getSheetByName('Copy of CALC');
var sheet2 = destination.getSheetByName('Copy of Print');
var sheet3 = destination.getSheetByName('Copy of Markbook');
if (sheet1 === null) {
} else {
destination.deleteSheet(sheet1);
}
if (sheet2 === null) {
} else {
destination.deleteSheet(sheet2);
}
if (sheet3 === null) {
} else {
destination.deleteSheet(sheet3);
}
}
}
The getValues() method returns a two dimensional array. You are getting an error msg from:
var destination = SpreadsheetApp.openById(fileID[i])
Try using:
var destination = SpreadsheetApp.openById(fileID[i][0])
Add a second index with a zero.
Resolved the issue, I have bolded the corrected line below
function cleanAllOld () {
var ss = SpreadsheetApp.openById('...');
var sheet = ss.getSheetByName('fileList');
var numberFiles = sheet.getLastRow();
for (var i=0; i<numberFiles; i++) {
// File to be cleaned
**var fileID = sheet.getRange(1, 1, numberFiles).getValues();**
Logger.log('fileID[i][0]: ' + fileID[i][0]);
var destination = SpreadsheetApp.openById(fileID[i][0]);
var sheet1 = destination.getSheetByName('Copy of CALC');
var sheet2 = destination.getSheetByName('Copy of Print');
var sheet3 = destination.getSheetByName('Copy of Markbook');
if (sheet1 === null) {
} else {
destination.deleteSheet(sheet1);
}
if (sheet2 === null) {
} else {
destination.deleteSheet(sheet2);
}
if (sheet3 === null) {
} else {
destination.deleteSheet(sheet3);
}
}
}