I created a code that merges different g sheet files together into a master spreadsheet from a given folder. Now I'd like to create a filter in the code which filters column 71 (BT) for only criteria "ABC" and merges the data into one. Would you guys help a brother out?
function myFunction() {
var folder = DriveApp.getFolderById("id");
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("QwERTY");
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("XYZ");
var data = ws.getRange("A2:KB" + ws.getLastRow()).getValues().filter(r => r[0] != '');
return data;
}
You can add the following lines of code:
let filterCriteria = SpreadsheetApp
.newFilterCriteria()
.whenTextContains("ABC")
.build();
let filter = ws.getRange(1, 71).createFilter();
filter.setColumnFilterCriteria(71, filterCriteria).sort(71, true);
Assuming, that ws is your working sheet and the criteria you're looking for is when text contains "ABC", then the snippet above will create a filter on the ws sheet on the BT1 cell.
However, please bear in mind that depending on the exact criteria of your filter you can modify the current one by taking a look at the methods available for the FilterCriteriaBuilder Class here.
Reference
Apps Script FilterCriteriaBuilder Class;
Apps Script Filter Class;
Apps Script FilterCriteria Class.
Related
I have a sheet called Audit with cell B1 corresponding to a specific shopID.
I have built a sheet with each shopID called ShopID+PrevAudit (555PrevAudit)
When they complete the audit they click a button that should copy values and format to the corresponding sheet i've created but I'm getting hung up on calling the correct sheet based on a B1 entry.
This is what I had been using but it was static and i want to make this easier on myself. I'm not sure why this is so difficult for me. Thanks for any help you can provide.
function copyaudit() {
var source = SpreadsheetApp.openById('SheetID');
var sourceSheet = source.getSheetByName('Audit');
var sourceRange = sourceSheet.getDataRange();
var sourceValues = sourceRange.getValues();
var tempSheet = source.getSheetByName('555PrevAudit');
var tempRange = tempSheet.getRange('A1:L51');
var destination = SpreadsheetApp.openById('SheetID');
sourceRange.copyTo(tempRange); // paste all formats?, broken references
tempRange.offset(0, 0, sourceValues.length, sourceValues[0].length)
.setValues(sourceValues); // paste all values (over broken refs)
}
Using a JS template string, you can generate the sheet name:
`${destID}PrevAudit`
To put it in context:
function copyaudit()
{
const range = 'A1:L51';
let spreadSheet = SpreadsheetApp.openById('SheetID');
let sourceSheet = spreadSheet.getSheetByName('Audit');
let sourceRange = sourceSheet.getRange(range);
// Get B1
let destID = sourceRange.getValues()[0][1];
let destSheet = spreadSheet.getSheetByName(`${destID}PrevAudit`);
sourceRange.copyTo(destSheet.getRange(range));
}
Do I have script that I am trying to get a specific range (single row ie AB2:AB10) from each sheet in a folder (getfolderbyid("jkhkkkkkkk") to copy to a specific master sheet getsheetbyID("lklklkjllj")
this is what I have but it is looping through all 5000 row of the source data sheet so is very slow
///////////////////////////////////////////
function getGaccountsDatafrom() {
var folder = DriveApp.getFolderById("folderID");
var filesIterator = folder.getFiles();
*var file;
var fileType;
var ssID;
var combinedData = [];
var data;
while(filesIterator.hasNext()){
file = filesIterator.next();
fileType = file.getMimeType();
if(fileType ==="application/vnd.google-apps.spreadsheet"){
ssID = file.getId();
data = getDataFromSpreadsheet(ssID);
combinedData = combinedData.concat(data);
} //if end here
}// while ends here
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DATA");
ws.getRange("A2:AQ").clearContent();
ws.getRange(2, 1, combinedData.length, combinedData[0].length).setValues(combinedData);
}
function getDataFromSpreadsheet(ssID){
var ss=SpreadsheetApp.openById(ssID);
var ws = ss.getSheetByName("DATA");
var data = ws.getRange("CG3:DW3"+ ws.getLastRow()).getValues();
return data;
}////////////////////////////////////////////////////
Hmm... the code is not "looping through all 5000 row of the source data sheet" but iterating files in a folder and getting data from each file separately. That is what makes it run slow, and I do not know if it can be made much faster.
The getDataFromSpreadsheet() function gets too much data because of the superfluous 3 so the result will have blank rows in between. Here is a quick fix:
const data = ws.getRange('CG3:DW' + ws.getLastRow()).getValues();
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()
Hello I made this script to export the data from a column to a .txt on my google drive
function createOrAppendFile() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var range = sheet.getRange('G3:G50');
var rows = range.getValues();
var fileName="test.txt";
var folderName="Videos";
var data = rows.splice(0);
var str = data.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);
}
}
}
The problem is that when I export the data its exporting with the empty lines and on the .txt shows up empty lines that i dont want to have, how i can make it? So I only export the lines that have content.
This is what the .txt looks like https://i.stack.imgur.com/wplZL.png
I think that the reason of your issue might be due to sheet.getRange('G3:G50'). In this case, even when the empty rows are included below the data range in the range of G3:G50, range.getValues() retrieves all rows of G3:G50. If you want to retrieve the values with the data range, how about the following modification?
From:
var range = sheet.getRange('G3:G50');
To:
var range = sheet.getRange('G3:G' + sheet.getLastRow());
And, when you want to remove all empty rows of the column "G", you can also use the following modification.
From:
var range = sheet.getRange('G3:G50');
var rows = range.getValues();
To:
var range = sheet.getRange('G3:G' + sheet.getLastRow());
var values = range.getValues().filter(([g]) => g.toString() != "");
References:
getLastRow()
filter()
I need to copy a sheet on google SpreadSheet to another SpreadSheet document.
I´ve done my research, and I found two methods that do this, however both have problems that I don´t know how to fix.
The first method copies the sheet with format, but it keeps the referenced cells, so I get a reference error in the new document (#ref). I need a function that copies the format and the values (not references).
function copySheet() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheet = source.getSheets()[0];
var destination = SpreadsheetApp.openById("15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ");
sheet.copyTo(destination);
}
This second method copies the values without references, however it copies only values, without format.
function copySheetValues()
{
var source = SpreadsheetApp.getActiveSheet();
var sourcename = source.getSheetName();
var sourceDataRange = source.getDataRange();
var sourceSheetValues = sourceDataRange.getValues();
var sourceRows = sourceDataRange.getNumRows();
var sourceColumns = sourceDataRange.getNumColumns();
var destination = SpreadsheetApp.openById('15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ');
destination.insertSheet(sourcename, 0);
destination.getDataRange().offset(0, 0, sourceRows, sourceColumns).setValues(sourceSheetValues);
}
How do I write a function that keeps the format and copies the values?
Since you seem to know how to get and set values using the whole data range, just use the other methods to get and set all the other parameters.
The script editor autocomplete is a great help in this case to try not to forget one !
I hope the list is complete, it is a bit of a pain to write though !.
code below, if one of them is not useful to you just delete it (in both directions (set and get).
function copySheetValues(){
var source = SpreadsheetApp.getActiveSheet();
var sourcename = source.getSheetName();
var sValues = source.getDataRange().getValues();
var sBG = source.getDataRange().getBackgrounds();
var sFC = source.getDataRange().getFontColors();
var sFF = source.getDataRange().getFontFamilies();
var sFL = source.getDataRange().getFontLines();
var sFFa = source.getDataRange().getFontFamilies();
var sFSz = source.getDataRange().getFontSizes();
var sFSt = source.getDataRange().getFontStyles();
var sFW = source.getDataRange().getFontWeights();
var sHA = source.getDataRange().getHorizontalAlignments();
var sVA = source.getDataRange().getVerticalAlignments();
var sNF = source.getDataRange().getNumberFormats();
var sWR = source.getDataRange().getWraps();
var destination = SpreadsheetApp.openById('15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ');
var destinationSheet = destination.insertSheet(sourcename, 0);
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues)
.setBackgrounds(sBG)
.setFontColors(sFC)
.setFontFamilies(sFF)
.setFontLines(sFL)
.setFontFamilies(sFFa)
.setFontSizes(sFSz)
.setFontStyles(sFSt)
.setFontWeights(sFW)
.setHorizontalAlignments(sHA)
.setVerticalAlignments(sVA)
.setNumberFormats(sNF)
.setWraps(sWR);
}
Edit :
Bryan's answer and your comment made me think of another solution, much more simple and that handles merged cells as well. Here is the code :
function copySheetValuesV2(){
var source = SpreadsheetApp.getActiveSheet();
var sourceName = source.getSheetName();
var sValues = source.getDataRange().getValues();
var destination = SpreadsheetApp.openById('15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ');
source.copyTo(destination)
var destinationSheet = destination.getSheetByName('Copy of '+sourceName)
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues);// overwrite all formulas that the copyTo preserved
}
In both script be sure that the destination sheet name does not already exist. I didn't handle that case although it is quite easy to do with a try/catch structure.
Another route to try that I think Serge was alluding to here.
function myFunction() {
var source = SpreadsheetApp.openById('SOURCE_ID');
var sourceSheet = source.getSheetByName('Sheet1');
var sourceRange = sourceSheet.getDataRange();
var sourceValues = sourceRange.getValues();
var tempSheet = source.getSheetByName('temp');
var tempRange = tempSheet.getRange('A1');
var destination = SpreadsheetApp.openById('DEST_ID');
sourceRange.copyTo(tempRange); // paste all formats?, broken references
tempRange.offset(0, 0, sourceValues.length, sourceValues[0].length)
.setValues(sourceValues); // paste all values (over broken refs)
tempSheet.copyTo(destination); // now copy temp sheet to another ss
}
This is a variation upon Sergei's answer.
This script will copy all visible sheets and export them in to a new spreadsheet with " Final" appended to the document title.
function copySheetValuesV4(){
var sourceSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheets = sourceSpreadsheet.getSheets();
var destination = SpreadsheetApp.create(sourceSpreadsheet.getName()+' Final');
for (var i = 0; i < sourceSheets.length; i++){
var sourceSheet = sourceSheets[i];
if (!sourceSheet.isSheetHidden()) {
var sourceSheetName = sourceSheet.getSheetName();
var sValues = sourceSheet.getDataRange().getValues();
sourceSheet.copyTo(destination)
var destinationSheet = destination.getSheetByName('Copy of '+sourceSheetName).setName(sourceSheetName);
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues);// overwrite all formulas that the copyTo preserved */
}
destination.getSheetByName("sheet1").hideSheet() // Remove the default "sheet1" */
}
}