Kolorieren Sie eine Zelle in Google Sheets basierend auf Zellendaten

7

Ich möchte eine Zelle anhand ihres Inhalts einfärben. 0= rot, 100= grün und linear zwischen interpoliert.

function LinInt(x){    
  var ss = SpreadsheetApp.getActiveSheet();
  var cell = ss.getActiveRange();
  var hue;
  hue = (x/100)*120;

  var color = HSVtoRGB(hue, 40, 100);
  cell.setBackground(color);

  return x;    
}   

function HSVtoRGB(h, s, v) {
    var r, g, b, i, f, p, q, t;
    if (h && s === undefined && v === undefined) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }
  return '#'+((b | g << 8 | r << 16) / 0x1000000).toString(16).substring(2);
}

Wenn ich das mache, bekomme ich eine Fehlermeldung, dass ich nicht anrufen darf setBackground. Ich gehe davon aus, dass ich die Farbe einer Zelle nicht von einer anderen ändern darf, weil ich es vermassle, die aktuelle Zelle zu erhalten, in der die Funktion ausgeführt wird.

Wie erhalte ich die Zelle, in der die Funktion ausgeführt wird, damit ich sie aufrufen setBackground()kann?

Zum Beispiel möchte ich =LinInt(50)in die Zelle tippen A1und A1gelb sein und die Nummer 50 darin haben. Wenn ich dann =LinInt(100)in die Zelle A2tippe, ist sie grün und hat die Nummer 100.

John Moffitt
quelle

Antworten:

3

Ich habe es gerade versucht, und hier ist eine flexiblere Funktion. Das vorherige Beispiel konnte die Bereiche ausgewählter Zellen nicht richtig verarbeiten. Dies kann (aber Sie können auch eine bessere Fehlerprüfung für leere Bereiche hinzufügen!). Es kann leicht angepasst werden, um andere Helligkeitsbereiche, Farbtöne und die automatische Berechnung des Maximalwerts zu erhalten , usw.:

/**
 * 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 menu = [({name: "colorize", functionName: "colorize"})];
  spreadsheet.addMenu("HSV Colors", menu);
}

/*
 * Change saturation of cell background colors based on their values
 */

function colorize() {

  // Prompt the user for a max value number.
  var numberRange = Browser.inputBox('Colorize Range',
      'Please enter the maximum number of your range' +
      ' (for example, "2"):',
      Browser.Buttons.OK_CANCEL);
  if (numberRange == 'cancel') {
    return;
  }

  // Prompt the user for a hue number.
  var hue = Browser.inputBox('Colorize Range',
      'Please enter the hue (0-359)' +
      ' (for example, "128"):',
      Browser.Buttons.OK_CANCEL);
  if (hue == 'cancel') {
    return;
  }


  var range = SpreadsheetApp.getActiveRange();
  Logger.log('range:' + range);

  var values = range.getValues(); // [][]

  Logger.log('values:' + values);

  var backgrounds = [];

  for (var row = 0; row < range.getNumRows(); row++) 
  {
    var rowBackgrounds = [];
    for (var column = 0; column < range.getNumColumns(); column++) 
    {
      var val = Number(values[row][column]);
      if (isNaN(val)) 
      {
        val = 0;
      }
      var newColor = HSVtoHEX(hue,255*val/numberRange,200);
      rowBackgrounds.push(newColor);
    }
    backgrounds.push(rowBackgrounds);
  }
  range.setBackgrounds(backgrounds);
}


// http://stackoverflow.com/a/17243070/1536038
function HSVtoHEX(h, s, v) {

  Logger.log('h:'+h+' s:'+s + ' v:' + v);

    var r, g, b, i, f, p, q, t;

    // turn variables into degrees and percentages
    h=h/360, s=s/255, v=v/255;

    if (h && s === undefined && v === undefined) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }

    //http://stackoverflow.com/a/5624139/1536038
  var result = "#" + ((1 << 24) + (Math.floor(r * 255) << 16) + 
      (Math.floor(g * 255) << 8) + Math.floor(b * 255))
      .toString(16).slice(1);
  Logger.log(result);
    return result;
}
Pixelpusher
quelle
3

Die Art und Weise, wie es funktionieren soll, ist nicht möglich. Das Ändern einer Hintergrundfarbe erfordert einen API-Aufruf und diese sind in benutzerdefinierten Formeln nicht zulässig . Deshalb habe ich folgenden Code kompiliert / erstellt:

Code

function onOpen() {
  var menu = [({name: "Cell", functionName: "LinInt"}),
    ({name: "Range", functionName: "LinRange"}),
    ({name: "Clear Formatting", functionName: "clearFormat"})];
  ss.addMenu("HSV Colors", menu);
}

function LinInt() {
  var cell = SpreadsheetApp.getActiveSheet().getActiveCell();
  var value = cell.getValue(), color = HSVtoHEX(value,40,100);
  cell.setBackground(color);
}   

function LinRange() {    
  var ss = SpreadsheetApp.getActiveSheet();
  var range = ss.getActiveRange(), values = range.getValues();
  var colors = new Array();  
  for(i in values) {
    colors[i] = new Array();
    for(var j=0, jLen=values[0].length; j<jLen; j++) {
      colors[i][j] = HSVtoRGB_2(values[i][j],40,100);
    }       
  }
  range.setBackgrounds(colors);
}   

// https://stackoverflow.com/a/17243070/1536038
function HSVtoHEX(h, s, v) {
    var r, g, b, i, f, p, q, t;

    // turn variables into degrees and percentages
    h=h/360, s=s/100, v=v/100;

    if (h && s === undefined && v === undefined) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }

    //https://stackoverflow.com/a/5624139/1536038
    return "#" + ((1 << 24) + (Math.floor(r * 255) << 16) + 
      (Math.floor(g * 255) << 8) + Math.floor(b * 255))
      .toString(16).slice(1);
}

function clearFormat() {
  ss.getDataRange().clearFormat();
}

Erklärt

Die onOpenFunktion erstellt in der aktiven Tabelle einen zusätzlichen Menüpunkt namens HSV-Farben mit drei Einträgen:

  1. Zelle: Dies funktioniert nur für eine aktive Zelle (auch wenn Sie einen Bereich ausgewählt haben).
  2. Reichweite: Dies ist für die Übernahme von Entfernungen gedacht (wenn dies für einzelne Zellen funktioniert, aber weniger effizient ist)
  3. Formatierung löschen: Löscht alle Stile auf dem gesamten Blatt (um leichter mit den Farben zu spielen).

Die LinIntund die LinRangesprechen für sich. Der LinRangeverwendet eine Stapeloperation, um die Hintergrundfarben effizient einzustellen.

Die HSVtoHEXFunktion konvertiert die HSV-Werte in ein RGB-Schema, das in einen Hexadezimalwert konvertiert wird.

Bemerkungen

Ursprünglich haben Sie mich durch Ihren Code täuschen lassen. Es hieß: HSVtoRGBAber tatsächlich haben Sie versucht, es in einen hexadezimalen Farbcode umzuwandeln. Das ist gut so, denn der setBackgroundRGB erlaubt keine Batch-Operationen wie der setBackgrounds .

Ihr Code gibt jedoch keinen korrekten Hexadezimalcode zurück:
Geben Sie hier die Bildbeschreibung ein

Geben Sie das Hex ein. Wert in colorizer.org und Sie erhalten den HSV-Code.

Fügen Sie onEditder LinInt()Funktion einen Trigger hinzu, und jeder Eintrag (Ganzzahl) ändert die Hintergrundfarbe.

Beispiel

Ich habe eine Beispieldatei für Sie erstellt: HSV to HEX

Verweise

  1. HSV & HSL , Wiki-Seite
  2. colorizer.org bietet einen Echtzeitüberblick über die verschiedenen Farbcode-Schemata wie RGB, HEX, HSL, HSV / HSB und CMYK.
  3. HSVtoRGB , Code zum Konvertieren von HSV in RGB
  4. RGBtoHEX , Codezeile zum Konvertieren von RGB in HEX
Jacob Jan Tuinstra
quelle
Hallo Jan, es ist auch Jan hier. :) Das ist ein wirklich hilfreiches Skript, das Sie zusammengestellt haben. Ich weiß, dass es wahrscheinlich eine kleine Änderung ist, aber ich kann nicht herausfinden, wie der Max- und Min-Wert automatisch aus dem ausgewählten Bereich anstelle der festen Werte von 0 bis 100 ermittelt wird.
Unterstreicht
0

Ich möchte eine Zelle anhand ihres Inhalts einfärben. 0 = rot, 100 = grün und linear interpoliert zwischen.

Wählen Sie den Bereich Format> Bedingte Formatierung> Farbskala, setzen Sie den Mittelpunkt auf Zahl und 50und Done:

Beispiel WA48783

pnuts
quelle