I was hoping the following code would take all the text values in column B and places them as a note in the corresponding row in column A.
But it doesn't.
It takes the first text value in cell B2 and inserts the same note in all the rows in column A.
How do I amend the code so that B2 text becomes a note for A2, B3 text becomes a note for A3, B4 becomes a note for A4 etc, etc.
function addNote() {
var ss = SpreadsheetApp.getActive();
var srcSheet = ss.getSheetByName("SKU_INFO_ASC");
var targetCell = srcSheet.getRange("A2:A100");
var sourceCell = srcSheet.getRange("B2:B100");
var noteText = sourceCell.getValue();
targetCell.setNote(noteText);
}
Solution
The main problem in your code is that you are using the methods to read and write in single cells (getValue instead of getValues and setNote instead of setNotes.
Try the following approach:
Code
function addNote() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SKU_INFO_ASC");
var values = sheet.getRange("A2:A100").getValues()
sheet.getRange("B2:B100").setNotes(values)
}
References
Range: setValues
Range: setNotes
Related
Trying to move data from one sheet to another if two sets of data in each sheet corresponds (the date in this case). I keep getting the following error:
Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveRange
I've seen some things to suggest I might not be pulling through from the sheet I've named, or that it's pulling through the value wrong? Not sure, any advice would be great.
Code:
function pullData(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var inputSheet = ss.getSheetByName("Input");
var currentSheet = ss.getActiveSheet();
var dateCell = inputSheet.getActiveCell("C2").getValue();
var inputRange = inputSheet.getActiveRange("C6:Z999");
var currentRange = currentSheet.getActiveRange("C6:Z999");
if (dateCell == currentSheet.getActiveCell("B2").getValue()){
var inputRows = inputRange.getNumRows();
var inputCols = inputRange.getNumColumns();
for (var i = 1; i <= inputRows; i++) {
for (var j = 1; j <= inputCols; j++) {
var inputValue = inputRange.getCell(i,j).getValue();
var currentValue = currentRange.getCell(i,j).setValue(inputValue);
}
}
}
}
When the value of cell "C2" of the sheet Input is the same with the value of cell "B2 of the active sheet, you want to copy the values of cells "C6:Z999" of the sheet Input to the cells "C6:Z999" of the active sheet.
You want to know the reason of the following error message.
Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveRange
Modification points:
getActiveRange() has no arguments. But you use the arguments. I think that the reason of your error message is this.
Also, getActiveCell() has no arguments. So in your script, I think that an error occurs at var dateCell = inputSheet.getActiveCell("C2").getValue();. From this situation, I thought that your tested script might be different from the script in your question.
When I saw the flow of your script, I thought that your goal might be as follows.
When the value of cell "C2" of the sheet Input is the same with the value of cell "B2 of the active sheet, you want to copy the values of cells "C6:Z999" of the sheet Input to the cells "C6:Z999" of the active sheet.
If my understanding is correct, getActiveCell("C2"), getActiveRange("C6:Z999") and getActiveCell("B2") might be getRange("C2"), getRange("C6:Z999") and getRange("B2"), respectively.
Pattern 1:
In this pattern, your script is modified for removing the error message.
Modified script:
Please modify your script as follows.
From:
var dateCell = inputSheet.getActiveCell("C2").getValue();
var inputRange = inputSheet.getActiveRange("C6:Z999");
var currentRange = currentSheet.getActiveRange("C6:Z999");
if (dateCell == currentSheet.getActiveCell("B2").getValue()){
To:
var dateCell = inputSheet.getRange("C2").getValue();
var inputRange = inputSheet.getRange("C6:Z9");
var currentRange = currentSheet.getRange("C6:Z9");
if (dateCell == currentSheet.getRange("B2").getValue()){
Pattern 2:
In this pattern, your script is modified by reducing the process cost. In your current script, getValue() and setValue() are used in the for loop. In this case, when inputRows and inputCols are large, the process cost will be high. So in this pattern, I would like to propose to reduce the cost.
Modified script:
Please modify your script as follows. In this modification, the values of cells "C6:Z999" of the sheet Input are copied to the cells "C6:Z999" of the active sheet using copyTo. By this, your goal can be achieved without using the for loop.
function pullData(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var inputSheet = ss.getSheetByName("Input");
var currentSheet = ss.getActiveSheet();
var dateCell = inputSheet.getRange("C2").getValue();
var inputRange = inputSheet.getRange("C6:Z9");
var currentRange = currentSheet.getRange("C6:Z9");
if (dateCell == currentSheet.getRange("B2").getValue()){
inputRange.copyTo(currentRange, {contentsOnly:true}); // Modified
}
}
References:
getActiveRange()
getActiveCell()
copyTo(destination, options)
Basically, this is what I want to do as a custom formula for a conditional format in Google Sheets:
If any cell in range + any other cell in range = the value I specify;
Return those cells (i.e. format them as I say).
What I'm doing is, I have a column of about 80 numerical (currency) values and I'm trying to figure out if any two of them sum to a given value.
Here is a sheet where i've demonstrated the solution with this (somewhat) simple formula:
=ARRAYFORMULA(QUERY(SPLIT(TRANSPOSE(SPLIT(TEXTJOIN("#",TRUE,IF(ROW(B2:B100)<TRANSPOSE(ROW(B2:B100))*(B2:B100<>""),B2:B100&"|"&TRANSPOSE(B2:B100),)),"#")),"|"),"where Col1+Col2="&D2))
Rafa Guillermo is right. It would be much easier to do it with a script, you can try this one:
function sum() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1"); //Enter the name of your sheet.
var column = 1; //Choose the number of column you want
var startRow = 2; //Choose the number of the first row with values
var lastRow = sheet.getLastRow();
var wantedSum = 50; //Your desired value.
var values = sheet.getRange(startRow, column, lastRow-1).getValues();
for (var i = 0;i<lastRow-startRow+1;i++) {
var a = values[i][0];
for (var j = 0;j<lastRow-startRow+1;j++) {
var b = values[j][0];
if (a+b == wantedSum) {
sheet.getRange(startRow+i, column).setBackground("green"); //You can edit this to the color or format you want.
sheet.getRange(startRow+j, column).setBackground("green");
return; // This stops when it finds the first pair that sums what you want, but there may be other pairs.
}
}
}
}
Remember to edit the name of your sheet, the column, the first row with values of that column and the value you are looking for.
I have this script here, but I want it to only run on ONE specific sheet named "Nes Smart Data" (SheetNo5). Currently it runs on all sheets and puts the data on cells where I don't want them to be. Can you help me correct the code? Thanks a lot!
function onEdit(e){
var sheet = SpreadsheetApp.getActiveSheet();
var range = e.range;
var column = range.getColumn();
var row = range.getRow();
var text;
if (column==11) { //Replace 2 with the column number of your comments cell//
var newRange = sheet.getRange(row,column-5); //If the date is in the next column
var today = Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'dd.MM.yyyy');
newRange.setValue(today);
}
if (column == 11){
text = sheet.getRange(row, 23).getValue();
sheet.getRange(row, 23).setValue(text + e.value+".");
}
}
Replace the following variable and things should work as desired -
Current:
var sheet = SpreadsheetApp.getActiveSheet();
Modification proposed:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Nes Smart Data');
Let me know if it doesn't!
Ideally, I want to be able to search through an entire sheet (or range of cells) and remove any values that have been repeated in that sheet (for example, if "2" appears in A3, B8, and D4, then I want to keep it in A3 and delete it in B8 and D4).
I normally see this problem addressed by looking at one column or row for duplicates (using the UNIQUE function) but not for an entire sheet.
How can I do this?
Here's some code that will do that for an entire sheet.
Please note it will work on text and numbers and it will overwrite any formulas.
function removeDuplicates() {
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var range = sheet.getDataRange();
var values = range.getValues();
var traversedValues = [];
var rowCount = values.length;
var colCount = values[0].length;
for (var row = 0; row < rowCount; ++row) {
for (var col = 0; col < colCount; ++col) {
var value = values[row][col];
if (traversedValues.indexOf(value) > -1) {
values[row][col] = null;
} else {
traversedValues.push(value);
}
}
}
range.setValues(values);
}
References for you
Beginner's guide to coding with Google Apps Script
For loops
if...else statements
Arrays
I am new with Google Sheets scripts and I can't seem to figure why I am getting this error: Range not found (line 4, file "Code"). I have followed everything from https://developers.google.com/apps-script/guides/sheets/functions#creating_a_custom_function
Here is my code:
function getBgColor(input) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(input);
return range.getBackground();
}
I appreciate all the assistance.
Your code should be fine if your input range is only one cell, at least if you pass it in as a string. =getBgColor("D1").
However, if you want to pass in a range, I think you will have to loop to that range in order to get the colors of the whole range. So you'll need something like this (untested):
function getBgColor(input) {
var bgs = SpreadsheetApp.getActiveSheet().getRange(input).getBackgrounds(),
colors = [];
for(var i = 0; i < bgs.length; i++){
colors.push(bgs[i]);
}
return colors;
}
That should give you a range with all the backgroundcolors of the range that you passed it. If you would want those colors in one cell, use: return colors.join(", "). If you want to return only unique colors, there are also ways to do that..
See if this helps first ?