The way that you want it to work, is not possible. Changing a background color, involves an API call and these are not allowed in custom formulas. Therefore I compiled/created the following code:
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();
}
Explained
The onOpen
function will create an extra menu item in the active spreadsheet, called HSV Colors having three entries:
- Cell: this will only work on one active cell (even if you selected a range).
- Range: this is meant for take on ranges (if will work on single cells, but less efficiently)
- Clear Formatting: clears all styling on the entire sheet (to play with the colors more easily)
The LinInt
and the LinRange
speak for themselves. The LinRange
uses a batch operation to efficiently set the background colors.
The HSVtoHEX
function will convert the HSV values into a RGB scheme, that is converted to a hexadecimal value.
Remarks
Originally you had me fooled, by your code. It said: HSVtoRGB
but in fact you were trying to convert it to a hexadecimal color code. That's a good thing, because the setBackgroundRGB doesn't allow for batch operations like the setBackgrounds does.
Your code however doesn't return a correct hexadecimal code:
Type in the hex. value in colorizer.org and you will get the HSV code.
Add an onEdit
trigger on the LinInt()
function and every entry (integer) will give a change in background color.
Example
I've created an example file for you: HSV to HEX
References
- HSV & HSL, wiki page
- colorizer.org, gives a real time overview of the diferent color code schemes, like RGB, HEX, HSL, HSV/HSB and CMYK.
- HSVtoRGB, code to convert HSV to RGB
- RGBtoHEX, line of code to convert RGB to HEX