Google Spreadsheet setBackgroundColors() "Deprecated" - google-apps-script

A gs I have been using in the past to check for duplicates, is no longer working. The script would check all cells in the spread sheet if any were identical it would highlight all their occurrences green. I also had another function that would revert all the cells back to white.
setBackgroundColors() has been deprecated; people have been recommended to now use setBackground(). The script still doesn't work...
Here is my gs, make a copy and fiddle with it. Many Thanks...
https://docs.google.com/spreadsheets/d/1UELTxZRZPKQKU9NsQwNefvdxJDM0xDt8904sZy3etoY/edit#gid=0
Here is the script.
/**
* Retrieves all the rows in the active spreadsheet that contain data and logs the
* values for each row.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
Logger.log(row);
}
};
/**
* Adds a custom menu to the active spreadsheet, containing a single menu item
* for invoking the readRows() function specified above.
* The onOpen() function, when defined, is automatically invoked whenever the
* spreadsheet is opened.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Check Directory",
functionName : "CheckDirectory"
}];
spreadsheet.addMenu("Script Center Menu", entries);
};
function CheckDirectory() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var numRows = data.length;
var numColumns = data[0].length;
var formats = [];
var values = [];
for (var i = 0; i < numRows; i++) {
formats[i] = [];
for (var j = 0; j < numColumns; j++) {
formats[i][j] = 'white';
if (data[i][j] != '') {
values.push([data[i][j], i, j]);
}
}
}
var numValues = values.length;
for (var k = 0 ; k < numValues - 1; k++) {
if (formats[values[k][1]][values[k][2]] == 'white') {
for (var l = k + 1; l < numValues; l++) {
if (values[k][0] == values[l][0]) {
formats[values[k][1]][values[k][2]] = 'green';
formats[values[l][1]][values[l][2]] = 'green';
}
}
}
}
dataRange.setBackground(formats);
};
function resetCheckDirectory() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var numRows = data.length;
var numColumns = data[0].length;
var formats = [];
var values = [];
for (var i = 0; i < numRows; i++) {
formats[i] = [];
for (var j = 0; j < numColumns; j++) {
formats[i][j] = 'white';
if (data[i][j] != '') {
values.push([data[i][j], i, j]);
}
}
}
var numValues = values.length;
for (var k = 0 ; k < numValues - 1; k++) {
if (formats[values[k][1]][values[k][2]] == 'white') {
for (var l = k + 1; l < numValues; l++) {
if (values[k][0] == values[l][0]) {
formats[values[k][1]][values[k][2]] = 'white';
formats[values[l][1]][values[l][2]] = 'white';
}
}
}
}
dataRange.setBackground(formats);
};

Use setBackgrounds(). With an s since it's a method that applies multiple background colors to multiple cells

Related

Google Sheet : The result could not be auto-expanded. Please insert new columns (1)

This script import opportunities that we get. It populates rows which then calculates some numbers such as interest and stuff. However, I now have errors when populating my cells (#REF error, see pictures below). Nothing has changed so my first guess is it has do with the processing of the sheet which has become too heavy.
`
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
var menu = SpreadsheetApp.getUi().createAddonMenu();
menu.addItem('Créer étude', 'init');
menu.addToUi();
}
function init() {
ss = SpreadsheetApp.getActiveSpreadsheet();
identifyJe();
sheetMaker = ss.getActiveSheet();
currentRow = ss.getActiveCell().getRowIndex();
ssEtudes = SpreadsheetApp.openById(getSheetEtudesId());
var ui = SpreadsheetApp.getUi();
var respon se = ui.alert(
'Ligne sélectionnée : ' + currentRow + '. Exécuter ?',
ui.ButtonSet.OK_CANCEL
);
if (response !== ui.Button.OK) return;
doEtude();
doContrat();
doPhases();
}
function doEtude(nomEtude) {
var etudeData = [];
for (var i = 0; i < etudeNamedRanges.length; i++) {
var column = ss.getRangeByName(etudeNamedRanges[i]).getColumn();
etudeData.push(sheetMaker.getRange(currentRow, column).getValue());
}
var destSheet = ssEtudes.getSheetByName('etudes');
var rowToAppend = getFirstEmptyRow(destSheet, 0);
for (var i = 0; i < etudeData.length; i++) {
var column = ssEtudes.getRangeByName(etudeNamedRanges[i]).getColumn();
destSheet.getRange(rowToAppend, column).setValue(etudeData[i]);
}
}
function doContrat() {
var contratData = [];
for (var i = 0; i < contratNamedRanges.length; i++) {
var column = ss.getRangeByName(contratNamedRanges[i]).getColumn();
contratData.push(sheetMaker.getRange(currentRow, column).getValue());
}
var destSheet = ssEtudes.getSheetByName('contrats');
var rowToAppend = getFirstEmptyRow(destSheet, 11);
for (var i = 0; i < contratData.length; i++) {
destSheet.getRange(rowToAppend, i + 4).setValue(contratData[i]);
}
}
function doPhases() {
var phasesCoords = getPhasesCoords();
var phasesData = [];
for (var i = 0; i < phasesCoords.length; i++) {
var phaseData = getPhaseData(phasesCoords[i]);
phaseData.unshift(i + 1);
phasesData.push(phaseData);
}
var destSheet = ssEtudes.getSheetByName('phases');
var rowToAppend = getFirstEmptyRow(destSheet, 9);
var columns = [];
for (var nPhase = 0; nPhase < phasesData.length; nPhase++) {
var phaseData = phasesData[nPhase];
for (var i = 0; i < phaseData.length; i++) {
if (columns[i] === undefined)
columns[i] = ssEtudes.getRangeByName(phasesNamedRanges[i]).getColumn();
destSheet
.getRange(rowToAppend + nPhase, columns[i])
.setValue(phaseData[i]);
}
}
}
`
Type of formula
The results
The error, which translates into The result could not be auto-expanded. Please insert new columns (1).
The results actually appear for some time and disappear after a few seconds, constantly. Does it have something to do with the size of the spreadsheet ?

Is it possible to copy range with formating using apps scripts?

dears
I need your support to edit this function as I need to copy data with formatting
This is the equation I working on
function copyRows()
{
var copySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet1');
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet2');
var dataRange = dataSheet.getDataRange();
var dataValues = dataRange.getValues();
for(var i = 1; i < dataValues.length; i++)
{
if(dataValues[i][29] === 'done')
{
copySheet.appendRow([dataValues[i][0],
dataValues[i][1],
dataValues[i][2],
dataValues[i][3],
dataValues[i][4]]);
}
}
for(var i = 1; i < dataValues.length; i++)
{
if(dataValues[i][29] === 'done')
{
var clearRow = i+1;
dataSheet.getRange('A' + clearRow + ':AC' + clearRow).clear();
}

Sheets Scripts- Clear cells based on background color

I am trying to clear (reset) the cell values on a sheet based on background color. I have found and changed the following 3 existing scripts. They all execute correctly without any errors, but none of them clear the form.
Here is a link to a mirror copy of my spreadsheet.
//////////////////////////////////
//https://stackoverflow.com/questions/70788737/clear-cell-contents-based-on-color-in-google-sheets
function ClearYellow1() {
var colorToDelete = '#CDCDB4';
var gs = SpreadsheetApp.getActive();
var sn = gs.getSheetByName('Temp');
var data = sn.getDataRange().getValues();
for (var r = 0; r < data.length; r++) {
for (var c = 0; c < data[0].length; c++) {
var cellBgColor = sn.getRange(r + 1, c + 1).getBackground();
if (cellBgColor === colorToDelete) {
sn.getRange(r+1,c+1).clear(); //for clearing values only use
//sn.getRange(r + 1, c + 1).deleteCells(SpreadsheetApp.Dimension.ROWS); //for deleting cells
}
}
}
}
/////////////////////////////////////
//https://stackoverflow.com/questions/65266797/change-cell-value-based-on-the-cells-background-color-in-google-sheets
function ClearYellow2() {
const sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Temp");
const rng = sheet1.getDataRange();
const colors = rng.getBackgrounds();
const values = rng.getValues();
colors.map((r,i)=>r.map((c,j)=>{
if(c=='#CDCDB4'){
values[i][j]="g";
}}));
rng.clearContent();
rng.setValues(values);
}
///////////////////////////////////////////
//https://stackoverflow.com/questions/68521942/google-sheets-delete-cell-with-specific-background-color
function ClearYellow3() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//var sheet = ss.getSheets()[0];
var sheet = ss.getSheetByName("Temp");
var range = sheet.getDataRange();
var bgColors = range.getBackgrounds();
var data = range.getValues() // <--- get all the data as an array
for (var i=0; i<bgColors.length; i++) {
for (var j=0; j<bgColors[i].length; j++) {
if (bgColors[i][j].toUpperCase() === '#CDCDB4') {
data[i][j] = ''; // <--- change the array
}
}
}
range.setValues(data); // <--- put the array back on the sheet
}
///////////////////////////////////////////////////////////
Any suggestions?
You should pick up the color from one cell to fix the problem.
A slight modification of code
function ClearYellow3() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Temp");
var color = sheet.getRange('C2').getBackground()
var range = sheet.getDataRange();
var bgColors = range.getBackgrounds();
var data = range.getValues()
for (var i=0; i<bgColors.length; i++) {
for (var j=0; j<bgColors[i].length; j++) {
if (bgColors[i][j] == color) {
data[i][j] = '';
// bgColors[i][j] = "#ffffff";//set to white
}
}
}
range.setValues(data).setBackgrounds(bgColors);//reset values and backgrounds
}
Reset values based on background colors:
I set a few colors to light yellow 3 and used the debugger to see what the value was and used that value to do the comparison
function ClearYellow3() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Sheet0");
var range = sheet.getDataRange();
var bgColors = range.getBackgrounds();
var data = range.getValues()
for (var i=0; i<bgColors.length; i++) {
for (var j=0; j<bgColors[i].length; j++) {
if (bgColors[i][j] == "#fff2cc") {
data[i][j] = '';
bgColors[i][j] = "#ffffff";//set to white
}
}
}
range.setValues(data).setBackgrounds(bgColors);//reset values and backgrounds
}
This worked first time without any problems

Using onEdit to bind a specific cell change value

This is my script. I need to populate the values in I2:I range when the cell value of C2 changes. I have created an array_temp but these are not getting pasted in I2. Can anybody please help me throw some light on it?
function onEdit(e) {
var spreadsheet = SpreadsheetApp.getActive();
var ss = e.getSheetByName('UserInterface');
var count = ss.getRange("H2").setFormula('=countif(TalukaName!B:B,UserInterface!C2)').getValue();
var DistrictName = ss.getRange('C2').getValue();
var matchindex = ss.getRange('H3').setFormula('=match(C2,TalukaName!B:B,0)').getValue();
var indexvalue = ss.getRange('H4').setFormula('=index(TalukaName!B:B,H3)').getValue();
var array = [] ;
ss.getRange('F2').clearcontent;
var ssTaluka= e.getSheetByName('TalukaName');
var range = ssTaluka.getDataRange();
var data = range.getValues();
for (var i = 0; i < count; i++) {
array[i]= data[i + matchindex - 1][0];
}
var array_temp = [];
for (var j = 0; j < array.length; j++) {
array_temp.push([
array[j]
])
}
ss.getRange('I2:I').clearContent();
ss.getRange('I2:I'+ (count+1)).setValues(array_temp) ;
}

When I change a cell's background color, how can I get all cells containing the same text to change the same color in all sheets?

I'm working with a set-list for a cover band in which I have listed all of our songs by decade on separate sheets, including a full set list on its own sheet. When we work on new songs, I color those cells green. I would like to see those same songs highlighted green wherever they may appear on the other sheets whenever I change color (onEdit, that is).
Here's what I've got so far pieced together from other sources:
function replace() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activecell = ss.getActiveSheet().getActiveCell().getA1Notation();
var activecellvalue = ss.getActiveSheet().getActiveCell().getValue();
var activecellcolor = ss.getActiveSheet().getActiveCell().getBackground();
var allsheets = ss.getSheets();
var s = 0;
var cells = [];
if (activecellvalue != 'Yes'|'No' && activecellcolor == '#00ff00'){
for (var s=0; s < allsheets.length; s++) {
var allcells = allsheets[s].getDataRange().getValues();
for (var i=0; i < allcells.length; i++) {
for (var j=0; j < allcells[i].length; j++) {
if (allcells[i][j].toString().match(activecellvalue) == activecellvalue) {
var newcells = allsheets[s].getRange(i+1,j+1).getA1Notation();
cells.push(newcells);}
}
}
allsheets[s].getRange(newcells).setBackground('#00ff00');
// cells.push(newcells);
Logger.log(newcells);
Logger.log(allsheets);
Logger.log(cells)
}
}
}
The "Yes" and "No" refer to cells containing messages in the negative or affirmative as to whether or not we have finished a song.
I have been able to get the script to color the same text in different cells in different sheets, but something still needs to be fixed which is allowing the same cell values in EVERY sheet to be highlighted, as well.
Thank you in advance for your help!
EDIT:
I have a working (albeit, seemingly inefficient) code that will seek out the text of an active cell elsewhere and change its cell color:
function colorchange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activecell = ss.getActiveSheet().getActiveCell().getA1Notation();
var activecellvalue = ss.getActiveSheet().getActiveCell().getValue();
var activecellcolor = ss.getActiveSheet().getActiveCell().getBackground();
var allsheets = ss.getSheets();
var s = 0;
var name = allsheets[s].getName();
if (activecellvalue != 'Yes'|'No' && activecellcolor == '#00ff00'){
for (var s=0; s < allsheets.length; s++) {
var cells = allsheets[s].getDataRange().getValues();
for (var i=0; i < cells.length; i++) {
for (var j=0; j < cells[i].length; j++) {
if (cells[i][j].toString().match(activecellvalue) == activecellvalue) {
var check = cells[i][j]
var newcells = allsheets[s].getRange(i+1,j+1).getA1Notation();
allsheets[s].getRange(newcells).setBackground('#00ff00');
}
}
}
}
}
else if (activecellvalue != 'Yes'|'No' && activecellcolor == '#ffffff'){
for (var s=0; s < allsheets.length; s++) {
var cells = allsheets[s].getDataRange().getValues();
for (var i=0; i < cells.length; i++) {
for (var j=0; j < cells[i].length; j++) {
if (cells[i][j].toString().match(activecellvalue) == activecellvalue) {
var check = cells[i][j]
var newcells = allsheets[s].getRange(i+1,j+1).getA1Notation();
allsheets[s].getRange(newcells).setBackground('#ffffff');
}
}
}
}
}
}
The problem is getting this script to trigger on a change to background color. According to this, such a feature is not yet possible. Can anyone provide a potential solution?
UPDATE:
Working solution. Triggered by a drop-down menu selection.
function songStatus()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = ss.getDataRange();
var curCell = sheet.getActiveCell();
var curCol = curCell.getColumn();
var curRow = curCell.getRow();
var allSheets = ss.getSheets();
var songs = [];
var status = sheet.getRange(curRow, 3).getValue();
var genre = sheet.getRange(curRow, 11).getValue();
if (status == "Now") {
sheet.getRange(curRow, 1).setBackground('#f884ff');
sheet.getRange(curRow, 3).setBackground('#f884ff');
var song = sheet.getRange(curRow, 1).getValue().toString();
for (var s=7; s < allSheets.length; s++) {
var row = allSheets[s].getDataRange().getLastRow();
var col = allSheets[s].getDataRange().getLastColumn();
var cells = allSheets[s].getDataRange().getValues();
for (var i=0; i < row; i++) {
for (var j=0; j < col; j++) {
if (cells[i][j].toString().match(song) == song) {
allSheets[s].getRange(i+1,j+1).setBackground('#f884ff');
}
}
}
}
}
else if (status == "Next")
{
sheet.getRange(curRow, 1).setBackground('#f2a2a2');
sheet.getRange(curRow, 3).setBackground('#f2a2a2');
var song = sheet.getRange(curRow, 1).getValue().toString();
for (var s=7; s < allSheets.length; s++) {
var row = allSheets[s].getDataRange().getLastRow();
var col = allSheets[s].getDataRange().getLastColumn();
var cells = allSheets[s].getDataRange().getValues();
for (var i=0; i < row; i++) {
for (var j=0; j < col; j++) {
if (cells[i][j].toString().match(song) == song) {
allSheets[s].getRange(i+1,j+1).setBackground('#f2a2a2');
}
}
}
}
}
}
Unfortunately, onEdit trigger only fires when an "Edit" is made by the user. However, you are right, changing the color is not considered as an edit. I would suggest a slightly different approach that would work in such a scenario. Instead of tracking your new songs by highlighting them with green and having the sheet run a script to detect if the color has been changed for that cell and then running a script to find that same song in other sheets, I'd suggest either tying your Yes/No drop-down to the onEdit function to fire the color change and the other scirpt to search for that song in other sheets, or making a new New/Old drop-down list to do that for you. Here's a small pseudo-code to do that:
function onEdit()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var range = ss.getDataRange();
var curCell = sheet.getActiveCell();
var curCol = curCell.getColumn();
var curRow = curCell.getRow();
var allSheets = ss.getSheets();
//Assuming your New/Old column in E
var status = sheet.getRange(curRow, 6).getValue();
if (status == "New")
{
sheet.getRange(curRow, 1, 1, range.getLastColumn()).setBackgroundRGB(230,240,220);
//Assuming your song name is in Column B
var song = sheet.getRange(curRow, 3).getValue();
for (var i=0; i<allSheets.length; i++)
{
var sRange = allSheets[i].getDataRange();
var sData = sRange.getValues();
var sRows = sRange.getLastRow();
for (var j=0; j<sRows; j++)
{
if (sData[j][1] == song)
{
allSheets[i].getRange(j+1, 1, 1, sRange.getLastColumn()).setBackgroundRGB(230,240,220);
}
}
}
}
}
Another advantage of having a code like this is that if your sheet evolves to say, track all the songs that were Old, New, In-progress, On hold or any different statuses that you could think of, and each of these had to be tracked by a color code at a glance, it's much easier to add else-if statements to do that for you.
Hope this helps!