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);
});
}
Related
The job process is like below:
Use column A as a condition to query the spreadsheet DATA, and return the column * of the spreadsheet DATA.
But now my spreadsheet is facing the delay issue and lag problem ,
i have confuse how to settle it.
if is any wrong please forgive me
please check out the example sheets any suggestion is welcome,
and thanks at all
I believe your goal is as follows.
You want to reduce the process cost for retrieving your goal.
In your situation, how about using Google Apps Script as a direction? I thought that when Google Apps Script is used, the process cost might be able to be reduced. When Google Apps Script is used for your situation, it becomes as follows.
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet and save the script. And, when you use this script using your provided Spreadsheet, please put a custom function of =SAMPLE('INPUT COL B'!B2:B,'DATA'!W2:AF) to a cell. By this, the result is returned.
function SAMPLE(srcValues, dataValues) {
const obj = dataValues.reduce((o, [w, ...v]) => {
const last = v.pop();
if (v.join("") != "") {
v.forEach(c => {
if (!o[c]) o[c] = [w, last];
});
}
return o;
}, {});
return srcValues.map(([b]) => obj[b] || [null, null]);
}
Testing:
When this script is for your provided Spreadsheet, the following result is obtained.
Note:
When the data becomes larger, the custom function might not be able to be used. At that time, please run the script by the script editor, custom menu, a button on Spreadsheet, and so on. The script is as follows. In this case, please copy and paste the following script to the script editor of Spreadsheet and save the script. And please run the function with the script editor. By this, in this script, the result value is put to the column "E" of "INPUT COL B" sheet.
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const [srcSheet, dataSheet] = ["INPUT COL B", "DATA"].map(s => ss.getSheetByName(s));
const srcValues = srcSheet.getRange("B2:B" + srcSheet.getLastRow()).getValues();
const dataValues = dataSheet.getRange("W2:AF" + dataSheet.getLastRow()).getValues();
const obj = dataValues.reduce((o, [w, ...v]) => {
const last = v.pop();
if (v.join("") != "") {
v.forEach(c => {
if (!o[c]) o[c] = [w, last];
});
}
return o;
}, {});
const res = srcValues.map(([b]) => obj[b] || [null, null]);
srcSheet.getRange(2, 5, res.length, res[0].length).setValues(res);
}
Reference:
Custom Functions in Google Sheets
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.
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?
I am trying to create a script in Google Sheets that select a range and print it. I am trying to print some information based on some parameters. I have the following script that sets the desired range, but I do not see a way to print it using script.
function printInvoice() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("A1:H46");
range.activate();
}
Any suggestions? Thanks!
You can use the following script:
var PRINT_OPTIONS = {
'size': 7, // paper size. 0=letter, 1=tabloid, 2=Legal, 3=statement, 4=executive, 5=folio, 6=A3, 7=A4, 8=A5, 9=B4, 10=B
'fzr': false, // repeat row headers
'portrait': true, // false=landscape
'fitw': true, // fit window or actual size
'gridlines': false, // show gridlines
'printtitle': false,
'sheetnames': false,
'pagenum': 'UNDEFINED', // CENTER = show page numbers / UNDEFINED = do not show
'attachment': false
}
var PDF_OPTS = objectToQueryString(PRINT_OPTIONS);
function onOpen(e) {
SpreadsheetApp.getUi().createMenu('Print...').addItem('Print selected range', 'printSelectedRange').addToUi();
}
function printSelectedRange() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getActiveRange();
var gid = sheet.getSheetId();
var printRange = objectToQueryString({
'c1': range.getColumn() - 1,
'r1': range.getRow() - 1,
'c2': range.getColumn() + range.getWidth() - 1,
'r2': range.getRow() + range.getHeight() - 1
});
var url = ss.getUrl().replace(/edit$/, '') + 'export?format=pdf' + PDF_OPTS + printRange + "&gid=" + gid;
var htmlTemplate = HtmlService.createTemplateFromFile('js');
htmlTemplate.url = url;
SpreadsheetApp.getUi().showModalDialog(htmlTemplate.evaluate().setHeight(10).setWidth(100), 'Print range');
}
function objectToQueryString(obj) {
return Object.keys(obj).map(function(key) {
return Utilities.formatString('&%s=%s', key, obj[key]);
}).join('');
}
You will also need to create an html file in your project (File>New>HTML File) with the name js, and paste in the following code:
<script>
window.open('<?=url?>', '_blank', 'width=800, height=600');
google.script.host.close();
</script>
This will create a button in your Sheets menu that will open a PDF with the selected range. You can modify some settings such as the print orientation, its size, or whether to show the gridlines or not on top of the script. If you still want to automatically print the ranges without having to manually go through the print dialog, you can either:
Send the document to your printer using GmailApp API class, if your printer supports such functionality.
Use Google Cloud Print. The following blog post may help you with that: https://ctrlq.org/code/20061-google-cloud-print-with-apps-script
I stumbled on your code quite by chance from an "unallowed question to stack overflow which actually seems to be exactly what I want - could not get any detail on how to print from App Script for sheets.
I have been trying it out but it falls over at the line in your sample
"var htmlTemplate = HtmlService.createTemplateFromFile('js');"
where the service cannot find 'js'. Afraid I do not understand what an html template is anyway - are you able to explain?
I know there are a lot of questions out there related to Google Scripts and some of them touch on my issue but I can't seem to figure out the full answer.
I only want to be able to run 1 or 2 scripts in the same project file for 1 spreadsheet. How do I allow permission for everyone with whom the sheet is shared WITHOUT forcing each user to go through the process of allowing Authorization? Is this possible?
Maybe there is an alternative script? Here is my script (in case this helps):
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{name:"Go to active row", functionName:"Go to active
row"}];
sheet.addMenu("Scripts", entries);
myFunction();
};
function gotoend() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getDataRange().getValues();
lastRow.forEach(function (row,index) {
if (row[3] == "") { // row[0] is the same as Column A. row[1] = B
lastRow.length = index;
}
});
var newRange = sheet.getRange(lastRow.length,1);
sheet.setActiveRange(newRange);
}
/**
* #OnlyCurrentDoc
*/