Autofill formulas in multiple sheets - google-apps-script

I have a problem to address, I have a Gsheet with many sheets that have columns with many formulas, for example I have a sheet AD that in the column A, N, O, P, Q, R, S , T , U, V , W , Y and Z have formulas. I have solved it with the script that I put here but it takes too long.
The thing is that in this Gsheet I have more sheets with as many formulas as the AD sheet, I have a MAIL etc sheet that has formulas in skipped columns, how can I optimize the script so that it copies formulas in the column that has formulas and drags them to the last column with data?
`
function autoFill(){
var spreadsheet = SpreadsheetApp.getActive();
var hojaAD = spreadsheet.getSheetByName('AD');
var copiaA2 = hojaAD.getRange('A2');
var destinationRangeA = hojaAD.getRange(2,1,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaA2.copyTo(destinationRangeA);
var copiaO2 = hojaAD.getRange('O2');
var destinationRangeO = hojaAD.getRange(2,15,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaO2.copyTo(destinationRangeO);
var copiaP2 = hojaAD.getRange('P2');
var destinationRangeP = hojaAD.getRange(2,16,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaP2.copyTo(destinationRangeP);
var copiaQ2 = hojaAD.getRange('Q2');
var destinationRangeQ = hojaAD.getRange(2,17,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaQ2.copyTo(destinationRangeQ);
var copiaR2 = hojaAD.getRange('R2');
var destinationRangeR = hojaAD.getRange(2,18,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaR2.copyTo(destinationRangeR);
var copiaS2 = hojaAD.getRange('S2');
var destinationRangeS = hojaAD.getRange(2,19,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaS2.copyTo(destinationRangeS);
var copiaT2 = hojaAD.getRange('T2');
var destinationRangeT = hojaAD.getRange(2,20,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaT2.copyTo(destinationRangeT);
var copiaU2 = hojaAD.getRange('U2');
var destinationRangeU = hojaAD.getRange(2,21,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaU2.copyTo(destinationRangeU);
var copiaV2 = hojaAD.getRange('V2');
var destinationRangeV = hojaAD.getRange(2,22,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaV2.copyTo(destinationRangeV);
var copiaW2 = hojaAD.getRange('W2');
var destinationRangeW = hojaAD.getRange(2,23,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaW2.copyTo(destinationRangeW);
var copiaY2 = hojaAD.getRange('Y2');
var destinationRangeY = hojaAD.getRange(2,25,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaY2.copyTo(destinationRangeY);
var copiaZ2 = hojaAD.getRange('Z2');
var destinationRangeZ = hojaAD.getRange(2,26,hojaAD.getLastRow()-1); //el 2 es la fila y el 1 la column
copiaZ2.copyTo(destinationRangeZ);
}
`
I have tried to make a script but it is slow

Grouping columns as suggested by #GiampaoloFerradini.
Instead of 12 discrete columns, the function applies to three discrete groups:
Column A
Column O-W inclusive
Column Y-Z inclusive
Column X is omitted; just as it is not part of the discrete columns in the OP script.
function autoFill(){
var spreadsheet = SpreadsheetApp.getActive();
var hojaAD = spreadsheet.getSheetByName('AD');
// CopiaA2
var copiaA2 = hojaAD.getRange(2,1)
// Logger.log("DEBUG: copiaA2 is "+copiaA2.getA1Notation())
var copiaA2LR = hojaAD.getLastRow()
// Logger.log("DEBUG: last row = "+copiaA2LR)
var destinationRangeA = hojaAD.getRange(2,1,(copiaA2LR-1),1)
// Logger.log("DEBUG: destination rangeA = "+destinationRangeA.getA1Notation())
copiaA2.copyTo(destinationRangeA)
// CopiaO2-W2
var copiaOW2 = hojaAD.getRange(2,15,1,9)
// Logger.log("DEBUG: copiaOW2 is "+copiaOW2.getA1Notation())
var destinationRangeOW = hojaAD.getRange(2,15,(copiaA2LR-1),9)
// Logger.log("DEBUG: destination rangeOW = "+destinationRangeOW.getA1Notation())
copiaOW2.copyTo(destinationRangeOW)
// CopiaY2-Z2
var copiaYZ2 = hojaAD.getRange(2,25,1,2)
// Logger.log("DEBUG: copiaYZ2 is "+copiaYZ2.getA1Notation())
var destinationRangeYZ = hojaAD.getRange(2,25,(copiaA2LR-1),2)
// Logger.log("DEBUG: destination rangeYZ = "+destinationRangeYZ.getA1Notation())
copiaYZ2.copyTo(destinationRangeYZ)
}

Related

Undeclared identifier on pinescript for a backtest strategy

I can't find my error in this code. Could you help me? This is supposed to be a test code for backtesting in pinescript version 4. The Error is "undeclared identifier 'macdval' and 'macdsignalVal' ligne 38 and 38
//#version=4
// Paramètres de l'indicateur MACD
fastMA = 12
slowMA = 26
signalMA = 9
// Paramètres de l'indicateur RSI
lengthRSI = 14
overbought = 70
oversold = 30
study("My Script", overlay=true)
macdVal = macd(fastMA, slowMA, signalMA)
macdSignalVal = ema(macdVal, signalMA)
rsiVal = rsi(close, lengthRSI)
// Variables pour stocker les positions d'achat et de vente
buyPrice = 0.0
sellPrice = 0.0
// Vérifier les conditions d'entrée
if crossover(macdVal, macdSignalVal) and rsiVal < oversold
strategy.entry("Long", strategy.long)
else if crossunder(macdVal, macdSignalVal) and rsiVal > overbought
strategy.entry("Short", strategy.short)
// Vérifier les conditions de sortie
if crossover(macdVal, macdSignalVal) or rsiVal > overbought
strategy.exit("Long")
else if crossunder(macdVal, macdSignalVal) or rsiVal < oversold
strategy.exit("Short")
// Afficher les indicateurs sur le graphique
plot(macdVal, color = color.blue, linewidth = 2)
plot(macdSignalVal, color = color.red, linewidth = 2)
plot(rsiVal, color = color.yellow, linewidth = 2)
I searched through the code for the error but could not find it

How do i use the second function i've created?

It's giving me an error ( value on right hand side of assignment is undefined) when i want to call the second function that i've created on line 12
function cosaprox
clc, clear
%d es el incremento y c sera la aproximacion del coseno
d = pi/100;
c = 0;
tol = 0.2;
i = 0;
flag = true;
%Aproximacion del cos
while flag
%Iteracion de la sumatoria
x=facto (2*i)
i+=1
if abs(c - cos(2*pi))>= tol
flag = false
else
endif
endwhile
disp (c)
end
function facto (x)
if x==0;
x=1;
endif
for h = 1:x-1
x = x*h;
endfor
end

Auto Send an Email on Date in Cell

There is no bug in this code, but the code does not do any action.
I am making a code for when reading the date of the current day and relate to the date in a particular column, will send an automatic email.
function sendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(ss.getSheetByName('Orçamento'))
var sheet = ss.getActiveSheet();
var startRow = 2; // First row of data to process
var lastRow = sheet.getLastRow(); // Number of rows to process
var numColumn = sheet.getLastColumn();
// grab column 5 (the 'days left' column)
var data = sheet.getRange(2,6,lastRow-startRow+1,1 );
var numRows = data.getNumRows();
var date_values = data.getValues();
// Now, grab the reminder name column
data = sheet.getRange(2, 2, lastRow-startRow+1, 1);
var reminder_info_values = data.getValues();
//Logger.log(data)
for (i in data) {
var column = data[i];
var date = new Date();
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
//Logger.log(date);
var sheetDate = new Date(column[6]);
//Logger.log(sheetDate);
var Sdate = Utilities.formatDate(date,'GMT-0300','yyyy:MM:dd')
var SsheetDate = Utilities.formatDate(sheetDate,'GMT-0300', 'yyyy:MM:dd')
Logger.log(Sdate+' =? '+SsheetDate)
if (Sdate == SsheetDate){
var obra = column[1];
var descricao = column[2];
var inicio = column[6];
var fim = column[7];
var compra = column[8]; // Contact Method
var subject = "Lembrete de início de Serviço: " +obra;
var message = "O serviço: " + descricao + "tem previsão de data de início em " + inicio + "e previsão de término em : " + fim + "a previsão de compra do material é em: " + compra + ". Fique atento para não atrasar este serviço ";
MailApp.sendEmail({
to: "bruno#formula.eng.br",
subject: subject,
body: message,
});
}
}
}

Delete row values in more than 1 sheet if exists in another sheet

The code below is from an answer from this post regarding copying row values to a new sheet if it exist in another sheets.
Now, what if instead of copying the duplicate values to sheet 3, I want to delete them from sheets 1 and 2 if it exists in Sheet 3. With the same spreadsheet, I have 3 sheets. The unique value that will be compared on the first 2 sheets is the first column, "ID NUMBER".
Given the values, 784 | John Steep | I.T Department, which exists in all 3 sheets, the same row value should be deleted in Sheet 1 and 2 and retain the same value on Sheet 3.
function copyRowtoSheet3() {
var s1 = SpreadsheetApp.openById("ID").getSheetByName('Sheet1');
var s2 = SpreadsheetApp.openById("ID").getSheetByName('Sheet2');
var s3 = SpreadsheetApp.openById("ID").getSheetByName('Sheet3');
var values1 = s1.getDataRange().getValues();
var values2 = s2.getDataRange().getValues();
var resultArray = [];
for(var n=0; n < values1.length ; n++){
var keep = false;
for(var p=0; p < values2.length ; p++){
Logger.log(values1[n][0]+' =? '+values2[p][0]);
if( values1[n][0] == values2[p][0] && values1[n][3] == values2[p][4]){
resultArray.push(values1[n]);
Logger.log('true');
break ;// remove this if values are not unique and you want to keep all occurrences...
}
}
}
s3.getRange(+1,1,resultArray.length,resultArray[0].length).setValues(resultArray);
}
Can't seem to find the right solution. Tried several scripts but failed to make it work.
Thank you for any advice/suggestion.
Although the other answer works (I didn't test but I guess it does) it uses a lot of spreadsheetApp calls and might be slow if you have a lot of data.
It is possible to get this result using only arrays (if you don't need to keep sheet formatting and/or formulas).
The approach is slightly different as it is easier to keep data instead of removing it.
There are for sure many possible solutions, below is the one I tried : I created a special array that contains only the first column of sheet3 to make the duplicate search simpler.
function removeDupsInOtherSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s1 = ss.getSheetByName("Sheet1").getDataRange().getValues();
var s2 = ss.getSheetByName("Sheet2").getDataRange().getValues();
var s3 = ss.getSheetByName("Sheet3").getDataRange().getValues();
// iterate s3 and check in s1 & s2 if duplicate values exist
var nS1 = [];
var nS2 = [];
var s3Col1 = [];// data in column1 of sheet3
for(var n in s3){
s3Col1.push(s3[n][0]);
}
for(var n in s1){ // iterate sheet1 and test col 1 vs col 1 in sheet3
var noDup1 = checkForDup(s1[n],s3Col1)
if(noDup1){nS1.push(noDup1)};// if not present in sheet3 then keep
}
for(var n in s2){ // iterate sheet2 and test col 1 vs col 1 in sheet3
var noDup2 = checkForDup(s2[n],s3Col1)
if(noDup2){nS2.push(noDup2)};// if not present in sheet3 then keep
}
Logger.log(nS1);// view result
Logger.log(nS2);
ss.getSheetByName("Sheet1").getDataRange().clear();// clear and update sheets
ss.getSheetByName("Sheet2").getDataRange().clear();
ss.getSheetByName("Sheet1").getRange(1,1,nS1.length,nS1[0].length).setValues(nS1);
ss.getSheetByName("Sheet2").getRange(1,1,nS2.length,nS2[0].length).setValues(nS2);
}
function checkForDup(item,s){
Logger.log(s+' = '+item[0]+' ?')
if(s.indexOf(item[0])>-1){
return null;
}
return item;
}
Sheet1
ID NUMBER NAME DEPARTMENT
784 John Steep I.T.
901 Liz Green H.R.
Sheet2
ID NUMBER NAME DEPARTMENT
784 John Steep I.T.
653 Bo Gore Marketing
Sheet3
ID NUMBER NAME DEPARTMENT
784 John Steep I.T.
999 Frank White Sales
121 Abid Jones Engineering
901 Liz Green H.R.
Script
function main() {
var ss = SpreadsheetApp.openById("ID");
var s1 = ss.getSheetByName("Sheet1");
var s2 = ss.getSheetByName("Sheet2");
var s3 = ss.getSheetByName("Sheet3");
var idCol = 1; // Assuming location of ID column is same in all sheets.
var s1RowCount = s1.getLastRow();
for (var i = 2; i <= s1RowCount; i++) { // Start at var i = 2 to skip the
// first row containing the header.
var id = s1.getRange(i, idCol, 1, 1).getValue();
deleteDuplicates(s2, id);
deleteDuplicates(s3, id);
}
}
function deleteDuplicates(sheet, id) {
var idCol = 1; // Assuming location of ID column is same in all sheets.
var rowCount = sheet.getLastRow();
for (var i = 2; i <= rowCount; i++) {
var data = sheet.getRange(i, idCol, 1, 1).getValue();
if (data === id) {
// Use this to test out the function.
Logger.log("Duplicate of ID " + id + " in sheet " +
sheet.getSheetName() + " at row " + i);
// Uncomment the next line when ready.
// sheet.deleteRow(i);
}
}
}
Logging Output
[14-11-04 09:16:04:551 PST] Duplicate of ID 784 in sheet Sheet2 at row 2
[14-11-04 09:16:04:587 PST] Duplicate of ID 784 in sheet Sheet3 at row 2
[14-11-04 09:16:04:727 PST] Duplicate of ID 901 in sheet Sheet3 at row 5

Delete row in other sheets based on 2 values on main file

Is it possible to delete rows on other sheets based on 2 values? Say I have 3 sheets. In the main sheet (sheet 1), there will be 2 columns: Branch and Manager same with the remaining sheets.
SAMPLE SPREADSHEET HERE.
Example data:
SHEET 1: (main sheet)
--- BRANCH --- MANAGER ---
California Tom Chang
Brooklyn Jon Sieg
New York Raq Craig
SHEET 2:
--- BRANCH --- MANAGER ---
California Jane Cali
California Tom Chang
San Francisco James Chao
SHEET 2:
--- BRANCH --- MANAGER ---
California Jane Cali
California Tom Chang
New York Daniel Trevor
What should happen is that:
Branch column values should NOT duplicate in all sheets. So what we need to do is delete the row on sheet 2 and 3 if branch column is equal with the main sheet (sheet1) IF AND ONLY IF the manager is not the same/equal. So in my given data above, Branch California and Manager Tom Chang exists in all sheets therefore it should not be touched. But California branch was repeated in the remaining 2 sheets with a different Manager. Therefore, row California ---- Jane Cali should be deleted on Sheets 2 and 3.
Came upon a script borrowed from this post but can't seem to work. Here:
function removeDupsInOtherSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainsheet = ss.getSheetByName("Sheet3").getDataRange().getValues();
var sheet2 = ss.getSheetByName("Sheet2").getDataRange().getValues();
var sheet3 = ss.getSheetByName("Sheet3").getDataRange().getValues();
// iterate mainsheet and check in sheet2 & sheet3 if duplicate values exist
var nsheet2 = [];
var nsheet3 = [];
var mainsheetCol1 = [];// data in column1 of main sheet
var mainsheetCol2 = [];// data in column2 of main sheet
for(var n in mainsheet){
mainsheetCol1.push(mainsheet[n][0]); //column1
mainsheetCol2.push(mainsheet[n][3]); //column2
}
for(var n in sheet2){ // iterate sheet2 and test col 1 vs col 1 and co2 1 vs co2 1in sheet2
var noDup1 = checkForDup(sheet2[n],mainsheetCol1,mainsheetCol2)
if(noDup1){nsheet2.push(noDup1)};// if not present in sheet3 then keep
}
for(var n in sheet3){ // iterate sheet3 and test col 1 vs col 1 and co2 1 vs co2 in sheet3
var noDup2 = checkForDup(sheet3[n],mainsheetCol1,mainsheetCol2)
if(noDup2){nsheet3.push(noDup2)};// if not present in sheet3 then keep
}
// view result
Logger.log(nsheet2);
Logger.log(nsheet3);
// clear and update sheets
ss.getSheetByName("Sheet2").getDataRange().clear();
ss.getSheetByName("Sheet3").getDataRange().clear();
ss.getSheetByName("Sheet2").getRange(1,1,nsheet2.length,nsheet2[0].length).setValues(nsheet2);
ss.getSheetByName("Sheet3").getRange(1,1,nsheet3.length,nsheet3[0].length).setValues(nsheet3);
}
//Here can't seem to make it work to check if column 2 is not equal to the other sheets
//item is sheet2[n]
// s is mainsheetCol1
// s2 is mainsheetCol2
function checkForDup(item,s,s2){
Logger.log(s+' = '+item[0]+' ?')
Logger.log(s2+' = '+item[1]+' ?')
if((s.indexOf(item[0])>-1) && (s2.indexOf(item[1])>-1))){
return null;
}
return item;
}
Hoping someone could help/guide me. Thank you!
Try this:
function removeDuplicate(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainsheet = ss.getSheetByName("Sheet1");
var sheet2 = ss.getSheetByName("Sheet2");
var sheet3 = ss.getSheetByName("Sheet3");
var masterData = mainsheet.getDataRange().getValues();
var sheetsToCheck = [sheet2,sheet3];
for(var i in sheetsToCheck){
var valuesToCheck = sheetsToCheck[i].getDataRange().getValues();
for(var j=0;j<valuesToCheck.length;j++){
for(var k in masterData){
if(masterData[k][0] == valuesToCheck[j][0] && !(masterData[k][1] == valuesToCheck[j][1])){
sheetsToCheck[i].deleteRow(j+1);
}
}
}
}
}
Code given at Post is not working. I have modified it little bit to make it work.
Here it is,
function removeDupsInOtherSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s1 = ss.getSheetByName("Sheet1").getDataRange().getValues();
var s2 = ss.getSheetByName("Sheet2").getDataRange().getValues();
var s3 = ss.getSheetByName("Sheet3").getDataRange().getValues();
// iterate s3 and check in s1 & s2 if duplicate values exist
var nS1 = [];
var nS2 = [];
var s3Col1 = [];// data in column1 of sheet3
for(var n=0; n<s3.length; ++n){
s3Col1.push(s3[n][0]);
}
for(var n=0; n<s1.length; ++n){ // iterate sheet1 and test col 1 vs col 1 in sheet3
var noDup1 = checkForDup(s1[n],s3Col1)
if(noDup1){nS1.push(noDup1)};// if not present in sheet3 then keep
}
for(var n=0; n<s2.length; ++n){ // iterate sheet2 and test col 1 vs col 1 in sheet3
var noDup2 = checkForDup(s2[n],s3Col1)
if(noDup2){nS2.push(noDup2)};// if not present in sheet3 then keep
}
Logger.log(nS1);// view result
Logger.log(nS2);
ss.getSheetByName("Sheet1").getDataRange().clear();// clear and update sheets
ss.getSheetByName("Sheet2").getDataRange().clear();
var nS1Length = nS1.length;
var nS2Length = nS2.length;
// This is the change needed in code you have copied from,
**if(nS1 != undefined){
data = []
data[0] = nS1;
var range = ss.getSheetByName("Sheet1").getRange(1,1);
range.setValues(data);
}
if(nS2 != undefined){
data = []
data[0] = nS1;
var range = ss.getSheetByName("Sheet2").getRange(1,1);
range.setValues(data);
}**
}
function checkForDup(item,s){
Logger.log(s+' = '+item[0]+' ?')
if(s.indexOf(item[0])>-1){
return null;
}
return item;
}