How to store RGB colour in variable? - excel

I'm looking to store an RGB colour in a variable in an Excel VBA project, to set the background color of various cell/ranges throughout a sub.
I want to set the colour once in a variable, so if I decide to change it throughout I only need to do it in one place.
Dim clrBlue As ColorFormat
clrBlue = RGB(0, 0, 256)
Range("a2").Interior.Color = clrBlue
Range("b3").Interior.Color = clrBlue
With the above code, I'm getting runtime error:
Object variable or With block variable not set
I could write separate functions (SetBlue, SetRed, SetGreen) to apply each colour, but that feels messy.
Can anyone suggest what I'm doing wrong?

RGB returns a Long, so you need to declare clrBlue as Long instead of as ColorFormat.
Dim clrBlue As Long
clrBlue = RGB(0, 0, 255)
Application.union(Range("A2"), Range("B3")).Interior.Color = clrBlue

As others have said, RGB() returns a Long, so you'll need to use that instead of ColorFormat. On a somewhat related note, I really like the Color enum in C#, and I started mimicking that in my VBA modules. You can create your own enum to store the values of colors in your project, then reference the color with Color.Blue.
This also makes it really easy to modify a color, if you decide to go with a different shade of blue. Update the enum, and all of the places you've used Color.Blue will update.
Example:
Public Enum Color
Black = 0 'RGB(0, 0, 0)
Blue = 14390640 'RGB(112, 149, 219)
Gray = 11842740 'RGB(180, 180, 180)
Red = 6118894 'RGB(238, 93, 93)
White = 16777215 'RGB(255, 255, 255)
End Enum
To get the long value of the RGB value to store, I just threw the value into the Immediate window and copied the output.
In Immediate Window, type:
? RGB(112, 149, 219)
The output will be 14390640. There might be an easier way to get the value.

I haven't tried this and I'm not disputing any of the previous commenters.
I do notice that the original code sample has: clrBlue = RGB(0, 0, 256)
The highest number allowed in RGB is 255. That might be the problem.

Related

Fill the whole container of grouped shapes - Excel

I have create some shapes in Excel, group them together and i can not find how to apply fill color on the whole group. Not on the shapes but on the background.
Any help?
In short, this isn't possible on a shape group.
Detailed explanation:
From https://learn.microsoft.com/en-us/office/vba/api/excel.groupshapes
The GroupedShapes object "Represents the individual shapes within a
grouped shape."
Because the group itself only represents the shapes within it, it doesn't have its own fill colour as such, only the fill colours of the shapes within it.
So, as I guess you've discovered, if you do something like this:
With Sheet1.Shapes(1).GroupItems.Parent
.Fill.ForeColor.RGB = RGB(255, 0, 0)
End With
Then you are telling the group to apply the Forecolor to every shape within the group, and not the group object itself.
If you wish to have a background colour to the group, then a workaround would be to create a rectangle at the back, and set the colour of that instead.
Update: Workaround Example
If you wish to implement my suggested workaround, then the following will get you there. You will need to adjust for colours / workbook / worksheet / shape group name etc. There might be a prettier way, but I have this working...
Const shapeGroupName As String = "ShapeGroup"
Const shapeGroupBGName As String = "ShapeGroupBG"
Const shapeGroupMargin As Single = 5
Dim x As Integer
Dim y As Integer
Dim h As Integer
Dim w As Integer
Dim shapeCount As Integer
Dim shapeCol() As String
With Sheet1.shapes.Range(Array(shapeGroupName))
ReDim Preserve shapeCol(.GroupItems.Count)
For shapeCount = 1 To .GroupItems.Count
shapeCol(shapeCount) = .GroupItems.Item(shapeCount).Name
Next
y = .Top - shapeGroupMargin
x = .Left - shapeGroupMargin
h = .Height + shapeGroupMargin * 2
w = .Width + shapeGroupMargin * 2
.Ungroup
End With
shapeCol(0) = shapeGroupBGName
With Sheet1.shapes.AddShape(msoShapeRectangle, x, y, w, h)
.Name = shapeGroupBGName
.Fill.ForeColor.RGB = RGB(255, 0, 0)
.Line.DashStyle = msoLineDashDot
.ZOrder msoSendToBack
End With
With Sheet1.shapes.Range(shapeCol).Group
.Name = shapeGroupName
End With
This works by getting the dimensions of the group, and the names of the shapes within it. Next it ungroups the shapes, adds a rectangle behind the existing shapes, and then regroups accordingly.
A couple of notes:
I have created an arbitrary margin size, as the dimensions of the group are actually the top left and bottom right of the objects within it. In excel, the GUI adds a nice bit extra on to this, so its up to you to set this to what you want.
You can also implement a different shape (i.e. a rounded rectangle instead if desired etc.).
If you have multiple shape groups, then the above could be modified easily to accommodate this.

Calculate a colour in a linear gradient

I'd like to implement something like the powerpoint image below. A gradient that goes between three values.
It starts at A (-1), the mid point is B (0), and the end is C (1).
I have realised that I can save some effort by calculating the 'start' as a-to-b, and the 'end' as b-to-c. I can do as 2 sets of 2 gradients, instead of 1 gradient with three values.
But I'm stumped (despite googling) on how to get from one colour to another - ideally in the RGB colour space.
I'd like to be able to have something like this -
const colourSpace = (value, startColor, endColor) => {...}
colorSpace(-0.25, red, yellow) // some sort of orangey color
colorSpace(1, yellow, green) // fully green
colorSpace(0.8, yellow, green) // mostly green
This isn't a front-end application, so no CSS gradients - which is what google was mostly referencing.
Thanks all,
Ollie
If you aren't too worried about being perceptually consistent across the color space (you would need to work in something like LAB mode to do that), you can just take the linear interpolation in RGB space. Basically you take a distance (between 0 and 1), multiply it by the different in the coordinates, and add it to the first one. This will allow you to find arbitrary points (i.e colors) along the line between any two colors.
For example between red and yellow:
let canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d');
let rgb1 = [255, 0, 0] // red
let rgb2 = [255, 255, 0] // yellow
function getPoint(d, a1, a2) {
// find a color d% between a1 and a2
return a1.map((p, i) => Math.floor(a1[i] + d * (a2[i] - a1[i])))
}
// for demo purposes fill a canvas
for (let i = 0, j = 0; i < 1; i += .002, j++) {
let rgb = getPoint(i, rgb1, rgb2)
ctx.fillStyle = `rgba(${rgb.join(",")}, 1)`
ctx.fillRect(j, 0, 1, 200);
}
<canvas id="canvas" width="500"></canvas>
You can repeat this to get multiple 'stops' in the gradient.
I ended up using Chroma for converting between colour spaces.

How to use a color buffer in OpenGL ES 2

I am a bit confused on how to draw color using a color buffer. I found a similar question here and made my shader the same as shown in the post's accepted answer. I then used the code:
mColorHandle = GLES20.glGetAttribLocation(Shader, "vColor");
GLES20.glEnableVertexAttribArray(mColorHandle);
ByteBuffer cb = ByteBuffer.allocateDirect(color.length * BYTES_PER_FLOAT);
cb.order(ByteOrder.nativeOrder());
colorBuffer = cb.asFloatBuffer();
colorBuffer.put(color);
colorBuffer.position(0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, cbo);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, colorBuffer.capacity(), colorBuffer);
GLES20.glVertexAttribPointer(mColorHandle, 4,
GLES20.GL_FLOAT, false,
0, 0);
in attempt to draw the color.
The shape displayed the color I was trying to draw but it faded out the color across the shape like this:
If someone could tell me what's going wrong and how I could get the shape to be all the same color, I would appreciate it.
Thanks to Rabbid76 for helping me find the mistake.
Instead of 4 elements total in the color array, there needs to be 16, an RGBA value for each vertex. (4 elements of the array are used to make one RGBA value.)

How to get white color in PyQT

the following instructions gets me rgb value in pyqt
c = result.pixel(x,y)
r = str(QtGui.qRed(c))
g = str(QtGui.qGreen(c))
b = str(QtGui.qBlue(c))
is there any way to get white value ?
for example: QtGui.qWhite(c) something ??
QtGui.QColor.fromRgb(c).lightness()
should do.
If you need to extract from a QColor not just the light but also the hue and saturation you can use getHsl:
>>> QColor(0,128,80).getHsl()
(157, 255, 64, 255)

CCParticleExplosion color?

I realize that a ccColor3B takes RGB values between 0 and 255, but in a ccColor4F, the values are between 0 and 1.0? I have custom colors I would like to use something like ccColor3B blueColor = ccc3(61, 66, 255); as a ccColor4F. I've tried dividing by 255 but all of the colors show up as black for some reason. My code looks something like: ccColor4F startColor;
startColor.r = blueColor/255;
startColor.g = blueColor/255;
startColor.b = blueColor/255;
startColor.a = 1.0f;
I'm not sure what I'm doing wrong!
You need to deal with each RGB value individually. For example:
startColor.r = blueColor.r / 255.0f;
Or you could just use what's already in place to do that conversion.
From ccTypes.h:
static inline ccColor4F ccc4FFromccc3B(ccColor3B c)

Resources