Google Sheets App Scripts If Else doesn't work - google-apps-script

I have created the following app script in my google sheets but its returning always true. why is that?
if (Dsheet.getRange('A3').isBlank) {
Logger.log('true');
var dest = Dsheet.getRange('A1')
source.copyTo (dest, {formatOnly: true});
source.copyTo (dest, {contentsOnly: true});
} else {
Logger.log('false');
var lastRow = Dsheet.getLastRow()+5;
var dest = Dsheet.getRange('A' + lastRow )
source.copyTo (dest, {formatOnly: true});
source.copyTo (dest, {contentsOnly: true});
}

You have to call the function using ()
if (Dsheet.getRange('A3').isBlank())

Related

Google Sheets - App Script (copyTo - cell content & format)

I have a tracker to count daily productivity.
This is appended to a weekly tracker, in which the sum of the two serves as a running total.
The weekly tracker is appended to a separate sheet to serve as historical data.
TRACKER
DATA
As you can see in the 'DATA' screenshot, the formula is being copied from K12:O12
see function copyTT / source.copyTo
I want to retain cell formatting, and copy only the cell data, not it's formula.
Script;
function mergeTT() {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange("NEW_TTRACKER!J3:O3");
var destSheet = ss.getSheetByName("NEW_TTRACKER");
var lastRow = destSheet.getRange("J7:J11").getValues().filter(String).length;
var destRange = destSheet.getRange(lastRow+7,10,1,6);
source.copyTo(destRange, {contentsOnly: true});
var ws = ss.getSheetByName("NEW_TTRACKER")
ws.getRange('K3:O3').clearContent();
}
function copyTT() {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange("NEW_TTRACKER!J5:O12");
var destSheet = ss.getSheetByName("NEW_TDATA");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo(destRange, {contentsOnly: false});
var sheet = SpreadsheetApp.getActive().getSheetByName("NEW_TTRACKER");
sheet.getRange('J7:O11').clearContent();
}
Thanks in advance.
I've been attempting to get around it playing with different CopyPasteType properties and I'm really not getting anywhere.
About I've been attempting to get around it playing with different CopyPasteType properties, I think that your approach is correct. In your script, how about modifying your script as follows?
From:
source.copyTo(destRange, {contentsOnly: true});
To:
source.copyTo(destRange, { contentsOnly: true });
source.copyTo(destRange, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); // Added
By this modification, the format is also copied.
Reference:
copyTo(destination, copyPasteType, transposed)

How to copy the data to destination range when there is any update in google sheet?

Hi everyone,
My goal is to copy the entire row of data from source data to destination range whenever the users select Transfer or Update in column E. Based on my script, it only works perfectly for Employee No 1 (Peter).
For example, when I select transfer in cell E4, the entire row of data from cell A4 to cell F4 will be copied to destination range (Row 1 in destination range as shown in the screenshot above). When I update certain cell, say cell C4, and select Update in cell E4, the entire row will be copied again to the 2nd row of destination range as shown in the screenshot above.
However, when I select Transfer of Update in cell E5 or cell E6 the data been copied to destination range will still be the data from Peter (Row 3 in destination range as shown in the screenshot above).
I'm not sure how to fix this in my script and really hope to get some helps from you guys.
This is the access to my google sheet for easier reference: https://docs.google.com/spreadsheets/d/1vfJYOAJT1Lqoj7uYQYftQ39Rl22FR9RWz04d1qYmRkg/edit?usp=sharing
This is my script:
function onEdit(e){
const dt = Utilities.formatDate(new Date(), 'Asia/Singapore', 'HH:mm:ss');
var ss = SpreadsheetApp.getActiveSheet ();
var direction = SpreadsheetApp.Direction
var aLast = ss.getRange("H"+(ss.getLastRow()+1)).getNextDataCell(direction.UP).getRow()
var destRange = ss.getRange(aLast+1,8);
if (e.range.columnStart == 5 && e.range.rowStart >= 4) {
if (e.value == 'Update' || e.value == 'Transfer') {
e.range.offset(0, 1).setValue(dt);
if(e.range.rowStart = 4) {
var order1 = ss.getRange ("A4:F4");
order1.copyTo (destRange, {contentsOnly: true});
} else if (e.range.rowStart = 5){
var order2 = ss.getRange ("A5:F5");
order2.copyTo (destRange, {contentsOnly: true});
} else if (e.range.rowStart = 6){
var order3 = ss.getRange ("A6:F6");
order3.copyTo (destRange, {contentsOnly: true});
}
source.copyTo (destRange, {contentsOnly: true});
} else {
e.range.offset(0, 1).setValue('');
}
}
}
Really appreciate for any helps and advice.
Try something like this:
function onEdit(e){
e.source.toast('entry');
const sh=e.range.getSheet();
const hr=1;
if(sh.getName()=='Your sheet name' && e.range.columnStart==5 && e.range.rowStart>hr && (e.value=='Update' || e.value=='Transfer')){
const dt=Utilities.formatDate(new Date(), 'Asia/Singapore', 'HH:mm:ss');
let src=sh.getRange(e.range.rowStart,1,1,6).getValues();
src[0][5]=dt;
const desrow=getColHeight(8,sh,e.source)+1;
sh.getRange(desrow,8,1,6).setValues(src);
sh.getRange(e.range.rowStart,6).setValue(dt);
}
}
function getColHeight(col,sh,ss){
var ss=ss||SpreadsheetApp.getActive();
var sh=sh||ss.getActiveSheet();
var col=col||sh.getActiveCell().getColumn();
const rcA=sh.getRange(1,col,sh.getLastRow(),1).getValues().reverse()
let s=0;
for(let i=0;i<rcA.length;i++) {
if(rcA[i][0].toString().length==0) {
s++;
}else{
break;
}
}
return rcA.length-s;
}

Copy Spreadsheet to a new file, specify tabs

I am copying a new instance of my spreadsheet without formulas into a folder. I found a script that works great here:
Copy an entire Spreadsheet, Just Preserve the Values.
I was trying to define a specific tab to copy but no luck.
var sheet = ss.getSheetByName('tab to dowload');
and
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheets()[2]);
function myFunction() {
var spreadsheetId = "###"; // Please set the source Spreadsheet ID.
var destFolderId = "###"; // Please set the destination folder ID.
// Copy each sheet in the source Spreadsheet by removing the formulas as the temporal sheets.
var ss = SpreadsheetApp.openById(spreadsheetId);
var tempSheets = ss.getSheets().map(function(sheet) {
var dstSheet = sheet.copyTo(ss).setName(sheet.getSheetName() + "_temp");
var src = dstSheet.getDataRange();
src.copyTo(src, {contentsOnly: true});
return dstSheet;
});
// Copy the source Spreadsheet.
var destination = ss.copy(ss.getName() + " - " + new Date().toLocaleString());
// Delete the temporal sheets in the source Spreadsheet.
tempSheets.forEach(function(sheet) {ss.deleteSheet(sheet)});
// Delete the original sheets from the copied Spreadsheet and rename the copied sheets.
destination.getSheets().forEach(function(sheet) {
var sheetName = sheet.getSheetName();
if (sheetName.indexOf("_temp") == -1) {
destination.deleteSheet(sheet);
} else {
sheet.setName(sheetName.slice(0, -5));
}
});
// Move file to the destination folder.
var file = DriveApp.getFileById(destination.getId());
DriveApp.getFolderById(destFolderId).addFile(file);
file.getParents().next().removeFile(file);
}
Explanation:
Your goal is to pass selected sheets, based on their name, to the newly created file.
You can do that by defining a list with the selected sheets:
var selected_sheets = ['Sheet1','Sheet5'];
and then instead of using ss.getSheets() which gets every sheet, use this to get the sheet object of the selected sheet names:
var tempSheets = selected_sheets.map(sn=>ss.getSheetByName(sn))
.map(function(sheet) {
var dstSheet = sheet.copyTo(ss).setName(sheet.getSheetName() + "_temp");
var src = dstSheet.getDataRange();
src.copyTo(src, {contentsOnly: true});
return dstSheet;
});
Solution:
Please modify this list: var selected_sheets = ['Sheet1','Sheet5']; and replace Sheet1, Sheet5 to the name of your sheets. You can also have one sheet: e.g. var selected_sheets = ['Sheet1'];.
function myFunction() {
var spreadsheetId = "###"; // Please set the source Spreadsheet ID.
var destFolderId = "###"; // Please set the destination folder ID.
// Copy each sheet in the source Spreadsheet by removing the formulas as the temporal sheets.
var ss = SpreadsheetApp.openById(spreadsheetId);
var selected_sheets = ['Sheet1','Sheet5']; // Add the sheets you want to copy here!
var tempSheets = selected_sheets.map(sn=>ss.getSheetByName(sn))
.map(function(sheet) {
var dstSheet = sheet.copyTo(ss).setName(sheet.getSheetName() + "_temp");
var src = dstSheet.getDataRange();
src.copyTo(src, {contentsOnly: true});
return dstSheet;
});
// Copy the source Spreadsheet.
var destination = ss.copy(ss.getName() + " - " + new Date().toLocaleString());
// Delete the temporal sheets in the source Spreadsheet.
tempSheets.forEach(function(sheet) {ss.deleteSheet(sheet)});
// Delete the original sheets from the copied Spreadsheet and rename the copied sheets.
destination.getSheets().forEach(function(sheet) {
var sheetName = sheet.getSheetName();
if (sheetName.indexOf("_temp") == -1) {
destination.deleteSheet(sheet);
} else {
sheet.setName(sheetName.slice(0, -5));
}
});
// Move file to the destination folder.
var file = DriveApp.getFileById(destination.getId());
DriveApp.getFolderById(destFolderId).addFile(file);
file.getParents().next().removeFile(file);
}

I need to write an onEdit function for a Google Sheets script

This is the script I want to trigger:
function moveValuesOnly () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Copy!A1:N200");
var destSheet = ss.getSheetByName("Paste");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
}
**// I want moveValuesOnly to trigger once Cell A10 in the Validation tab changes to '2'**
I would greatly appreciate any help as I am a bit green at the moment.
Kind regards,
Brendon
I would suggest to have a read at Simple Triggers and Installable Triggers.
Basically you can create any function and make it trigger using the ScriptApp class and those are called installable trigger.
But there are special functions that don't need to go through ScriptApp to get triggered, you just need to change the name of the function, and that would start enabling the trigger of those functions.
Simple trigger
Just change the name of the function so it will automatically start triggering.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Copy!A1:N200");
var destSheet = ss.getSheetByName("Paste");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
}
Installable Trigger
Create another function to execute on time to create the trigger
function moveValuesOnly(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Copy!A1:N200");
var destSheet = ss.getSheetByName("Paste");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
}
function createTrigger(){
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('moveValuesOnly')
.forSpreadsheet(ss)
.onEdit()
.create();
}
You have specified in your code that only want to trigger when the cell is A10, but this is impossible as of right now. You need to create an if statement making sure the range being edited is the one you care about.
Look at the event objects because that would be input parameter of the trigger functions (e). That object has information about the range and spreadsheet being edited.
Basically make a condition with the e object
function onEdit(e) {
var range = e.range;
var newValue = e.value;
var oldValue = e.oldValue;
var sheet = range.getSheet();
if(sheet.getName() == "<Your sheet name>" && newValue == 2 && range.getColumn() == 1 && range.getRow() == 10){
// Browser.msgBox("Edit entered condition");
//
// Do your stuff here when the condition is satisfied
}
}

copy and paste with google spreadsheet script

I would like to modify the script shown below, so that if re-run, it does not overwrite pre-existing data, but instead writes the rows under it.
(I use the google spreadsheet)
moveValuesOnly fonction () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1 F1: H3 ');
source.copyTo (ss.getRange ("Feuil2 A1! '), {contentsOnly: true});
source.clear ();
}
This version will find the first empty row in the destination sheet, and copy the source data so it starts there.
function moveValuesOnly () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1!F1:H3");
var destSheet = ss.getSheetByName("Feuil2");
// Déterminer l'emplacement de la première ligne vide.
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
source.clear ();
}