Google Sheets Macro not pasting formula - google-sheets

Please help with Google sheets macro. Trying simple stuff as a start. Macro needs to clear B2 cell and paste formula (importhtml) as shown below. Then it has to do the same for cell B43 (Potentially will do this in multiple cells on this sheet if it ever works).
Google sheets link:
https://docs.google.com/spreadsheets/d/1O0AJJEd0tGyFXlEPhih8HG9YOWcZNRot_Z7FXPdQrx8/edit?usp=sharing
Strangely it works in B43, but leaves B2 empty.
function Untitledmacro() {
// Clear B2 and then paste formula
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('DATA'), true);
spreadsheet.getRange('B2').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
};
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('DATA'), true);
spreadsheet.getRange('B2').activate();
spreadsheet.getCurrentCell().setFormula('=IMPORTHTML("https://www.investing.com/commodities/real-time-futures","table",1)');
// Clear B43 and then paste formula
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('DATA'), true);
spreadsheet.getRange('B43').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('DATA'), true);
spreadsheet.getRange('B43').activate();
spreadsheet.getCurrentCell().setFormula('=IMPORTHTML("https://www.investing.com/indices/indices-futures","table",1)');
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('DATA'), true);
Added Sheets API, not sure it's needed here though

See if this helps
function clearAndSetformula() {
const sheet = SpreadsheetApp.getActive().getSheetByName('DATA');
const cells = ["B2", "B43"];
const formulas = [
'=IMPORTHTML("https://www.investing.com/commodities/real-time-futures","table",1)',
'=IMPORTHTML("https://www.investing.com/indices/indices-futures","table",1)'
];
cells.forEach((cell, i) => sheet.getRange(cell).clear({ contentsOnly: true, skipFilteredRows: true }).setFormula(formulas[i]));
};
If you need to add more cells/formulas, add them in the proper arrays. Make sure the positions line up so that the first cell in the array cells will have the first formula in the array formulas etc...
I hope that helps?

Related

Copy multiple values into certain cells on Google Spreadsheet

i'm having trouble in copying values from one sheet to another sheet using Google script. When I call the function, it says
Exception: The parameters (String,String,String,String) don't match the method signature for SpreadsheetApp.Spreadsheet.getRange.**
So it doesn't execute.
function BalanceLifeTodayUpdate() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
spreadsheet.getRange('\'All Links\'!IC702','\'All Links\'!IC703','\'All Links\'!IC707','\'All Links\'!IC708').copyTo(spreadsheet.getRange('\'Balance Life Today\'!C404','\'Balance Life Today\'!C405','\'Balance Life Today\'!C409','\'Balance Life Today\'!C410'), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
getRange of Class Spreadsheet is getRange(a1Notation). In your script, 2nd argument is not required to be used. I think that this is the reason of your issue. In your script, how about merging the cells of '\'All Links\'!IC702','\'All Links\'!IC703' and also '\'Balance Life Today\'!C404','\'Balance Life Today\'!C405'? The modified script is as follows.
Modified script:
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
spreadsheet.getRange('\'All Links\'!IC702:IC703').copyTo(spreadsheet.getRange('\'Balance Life Today\'!C404:C405'), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
or
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
spreadsheet.getRange('\'All Links\'!IC702:IC703').copyTo(spreadsheet.getRange('\'Balance Life Today\'!C404'), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
Reference:
getRange(a1Notation) of Class Spreadsheet
Added:
From your following reply,
but I have more cells to be copied. For example: 'var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); spreadsheet.getRange(''All Links'!IC702',''All Links'!IC703',''All Links'!IC707',''All Links'!IC708').copyTo(spreadsheet.getRange(''Balance Life Today'!C404',''Balance Life Today'!C405',''Balance Life Today'!C409',''Balance Life Today'!C410'), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); };'
When there are only 2 pairs of source and destination ranges, I thought that the loop can be used. So, how about the following modification? If your ranges are more existing, in order to reduce the process cost, Sheets API might be suitable.
Sample script:
function BalanceLifeTodayUpdate() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// This is from your updated script.
var ranges = [
{ src: '\'All Links\'!IC702:IC703', dst: '\'Balance Life Today\'!C404' },
{ src: '\'All Links\'!IC707:IC708', dst: '\'Balance Life Today\'!C409' }
];
ranges.forEach(({ src, dst }) => {
spreadsheet.getRange(src).copyTo(spreadsheet.getRange(dst), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
});
}

Google Sheet script: PASTE_CONDITIONAL_FORMATTING option not working with copyTo method

I am trying to copy conditional formatting from a GS range to another range and nothing is copied (no error). This is the snippet:
spreadsheet.getSheetByName('sheet_source').getRange(14,7,200,19).copyTo(spreadsheet.getSheetByName('sheet_target').getRange(14,7,200,19), SpreadsheetApp.CopyPasteType.PASTE_CONDITIONAL_FORMATTING, false);
If I use the same code but change the CopyPasteType to a different option, it works (see example below). The problem is that I only want conditional formatting copied so I need the PASTE_CONDITIONAL_FORMATTING to work. Please let me know if you have any suggestions.
spreadsheet.getSheetByName('sheet_source').getRange(14,7,200,19).copyTo(spreadsheet.getSheetByName('sheet_target').getRange(14,7,200,19), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
Per doubleunary's suggestion, I reformatted the script as follows, and it works:
function CndFmtFromTmplt_PasteCndFmt() {
//get spreadsheet
const spreadsheet = SpreadsheetApp.getActive();
//get sheets
const sheetSource = spreadsheet.getSheetByName("Template");
const sheetTarget = spreadsheet.getSheetByName("Test Sheet");
//clear rules
sheetTarget.clearConditionalFormatRules();
//get copy ranges
//const rangeSource = sheetSource.getRange(1, 1, sheetSource.getMaxRows(), sheetSource.getMaxColumns());
const rangeSource = sheetSource.getRange('A1:AF200');
const rangeTarget = sheetTarget.getRange('A1:AF200');
// copy values to destination range
rangeSource.copyTo(rangeTarget, SpreadsheetApp.CopyPasteType.PASTE_CONDITIONAL_FORMATTING,false);
};
The code you show looks fine, so it is unclear where the problem is. To make debugging easier, try structuring your code a bit, like this:
function test() {
const ss = SpreadsheetApp.getActive();
const sourceRange = ss.getRange('sheet_source!N7:S200');
const targetRange = ss.getRange('sheet_target!N7');
sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_CONDITIONAL_FORMATTING, false);
}
Check My Executions for failed executions, and view those logs to learn more about why the function fails. You can run the test() function in the script editor when testing.

Reorder multiple ranges in Google Sheets with apps script?

Recently I got automatic reorder code working for range DY29:EA43 (thanks to you), but I want also automatically reorder additional multiple ranges but I can't figure it out how I can run multiple functions in Apps Script?
Ranges I want to automatic reorder in addition:
Range DY47:EA60 by percentage in column EA (EA47:EA60).
Range DY65:EA77 by value in column EA (EA65:EA77).
Range DY82:EA95 by percentage in column EA (EA82:EA95).
Range DY99:EA113 by percentage in column EA (EA99:EA113).
Code I have now:
function myFunction(){
sample();
}
function myFunction() {
const sheet = SpreadsheetApp.getActiveSpreadsheet();
const a1Notations = ["B3:J7", "B11:J15", "B19:J23", "B27:J31", "B35:J39", "B43:J47", "B51:J55", "B59:J63"];
const ranges = sheet.getRangeList(a1Notations).getRanges();
const formatRanges = a1Notations.map(r => r.replace(/^./, "J"));
sheet.getRangeList(formatRanges).setNumberFormat("0");
ranges.forEach(r => r.sort({ column: r.getLastColumn(), ascending: false }));
sheet.getRangeList(formatRanges).setNumberFormat("#");
}
function sample() {
const sheet = SpreadsheetApp.getActiveSpreadsheet();
const range = sheet.getRange("EA29:EA43");
const formulas = range.getFormulas();
const mFormulas = formulas.map(([ea]) => [ea.replace(/=SUM\(([A-Z]+)([0-9]+)\+([A-Z]+)([0-9]+)\)/i, "=SUM($$$1$$$2+$$$3$$$4)")]);
if (JSON.stringify(formulas) != JSON.stringify(mFormulas)) range.setFormulas(mFormulas);
SpreadsheetApp.flush();
sheet.getRange("DY29:EA43").sort({ column: 131, ascending: false });
}
Link to sheet: https://docs.google.com/spreadsheets/d/17ZyUuDAp85Vr76NMmqQXuLqTUMMuHP6sQu2gvQREhDU/edit#gid=446993580
#1
Try
function reOrder() {
const sheet = SpreadsheetApp.getActiveSpreadsheet();
["DY47:EA60", "DY65:EA77", "DY82:EA95", "DY99:EA113"].forEach(rng => {
let values = sheet.getRange(rng).getValues()
values = values.sort(function (a, b) {
return a[2] - b[2];
});
sheet.getRange(rng).setValues(values)
})
}
#2
or to keep formulas
function reOrder() {
const sheet = SpreadsheetApp.getActiveSpreadsheet();
["DY47:EA60", "DY65:EA77", "DY82:EA95", "DY99:EA113"].forEach(rng => {
sheet.getRange(rng).sort([{ column: 131, ascending: true }]);
})
}
#3
last solution, according to the complixity of your spreadsheet, in EC47
=sort(arrayformula({DY47:DZ60,(EA47:EA60)*1}),3,1)
same for other ranges
you will need to show all rows

Is it possible to use a script to enable edition in more than one sheet on Google Sheet?

I need to enable edition in more than one sheet to 60 users (using e-mail).
The user need to edit a few cells and all the other the edition need to be blocked.
Example: all the user should have the edition enable in sheets X, Y and Z, and the range of cells enabled to edition is B6:Q50. All the other cells need to be blocked and only the owned can edit.
Is it possible?
Solution:
On your main Google spreadsheet file, you can create a bound script and try this tweaked script below:
This script was based from Protect spreadsheet then unprotect specific cells and ranges with script & article of addEditors() method.
Script:
function main() { //Main function to run
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
addEditors();
for(var x=0; x<sheets.length; x++){
unlockCertainRanges(sheets[x]);
}
}
function addEditors(){ //Function to add editors
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var emails = [
'test1#example.com',
'test2#example.com',
'test3#example.com'
];
sheet.addEditors(emails);
}
function unlockCertainRanges(currentSheet){ //Function to unlock certain ranges on your sheets
var sheet = currentSheet;
// Remove all range protections in the spreadsheet
var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
protection.remove();
}
var protection = sheet.protect();
//restrict editors to owner
protection.getRange().getA1Notation();
var eds = protection.getEditors();
protection.removeEditors(eds);
//set unprotected ranges
var ranges = protection.getUnprotectedRanges();
var data = ["B6:Q50"]; // ADD YOUR RANGES HERE TO BE EDITABLE
data.forEach(res => { //LOOPS INTO EVERY ARRAY CONTAINING SPECIFIC RANGES
ranges.push(sheet.getRange(res));
protection.setUnprotectedRanges(ranges); //REMOVES THE PROTECTION ON THE RANGE
});
}
Sample Result:
After running the main function, the emails added on addEditors function are automatically added as editors of the file & they'll be abe to edit range B6:Q50 and the rest of the cells will be protected (only the owner of the spreadsheet file will be able to edit):
Sample Images:
Image 1: A user is not allowed to edit cell A1 (outside of B6:Q50 range on all sheets)
Image 2: User is allowed to edit cell B6 (within B6:Q50 range on all sheets)

Defining a cell inside Google Sheets using a Script

I am writing a Google Sheets Script to save as Sheet file to a PDF. I want the File Name to be Cell A11 (which is a combination of texts from other cells). So I wrote this:
file.setName(Cell + '.pdf');
My question is: how can I define "Cell" to pull data from A11 from inside the spreadsheet.
Here. Add this function to your script.
function getFilename() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName('Sheet1');
// Edit the sheet name as necessary
var cell = sheet.getRange('A11');
var filename = cell.getValue();
return filename;
}
Then change
file.setName(Cell + '.pdf');
to
file.setName(getFilename() + '.pdf');

Resources