12

I am trying to set an orangish color in the following manner:

WorkSheet.Range("A1:A5").Interior.color = 49407

and

WorkSheet.Range("A1:A5").Interior.color = &HC0FF 'Hex value of 49407

Aren't these two supposed to be exactly equivalent? The colors being set are different.

Community
  • 1
  • 1
Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191

4 Answers4

38

No, those values are not equivalent: &HC0FF is -16129, whereas &HC0FF& is 49407.

VBA, being a rather old language uses 16 bit integers by default. In this day and age, you pretty much want longs always instead of ints, but you have to ask VBA for them.

&HC0FF is a construct that defines a 16-bit constant from hex. Because the sign bit in this value is set (on, negative) when interpreted as a 16-bit value, hence the conversion to -16129. We may consider that this sucks, but it is not a bug! When you use -16129 (as a signed integer), in 32 bit form, 1's are propagated thru the whole top 16 bits and that results in the blue value of 255.

What you really wanted here is a a 32-bit hex constant: &HC0FF&. The extra & on the end tells VBA that this is a long constant instead of an int. Interpreted in 32-bits, this is a positive value, so gives the decimal equivalent you're looking for.

In short, ask for long hex constants with the trailing &.

As an aside, this propensity of VBA toward 16 bit can also bite us when using decimal constants, such as in an expression 16000 * 16000, which will overflow 16 bit arithmetic. So, sometimes one needs to use the trailing & on decimal constants too (or assign one to a long first).

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
11

This will convert the hex-format colors you have to the RGB Long that Office uses for RGB colors:

Function HexToLongRGB(sHexVal As String) As Long
    Dim lRed As Long
    Dim lGreen As Long
    Dim lBlue As Long

    lRed = CLng("&H" & Left$(sHexVal, 2))
    lGreen = CLng("&H" & Mid$(sHexVal, 3, 2))
    lBlue = CLng("&H" & Right$(sHexVal, 2))

    HexToLongRGB = RGB(lRed, lGreen, lBlue)

End Function
Steve Rindsberg
  • 14,442
  • 1
  • 29
  • 34
8

I believe the answers from Gimp and Johannes both miss the key issue.

A colour on a computer screen is defined by specifying how much red, blue and green you require. For each of the three colours you specify a number between 0 and 255. These three numbers are normally specified as a single number by concatenating the three separate numbers. With Html you specify a colour as #RRGGBB where RR, GG and BB are hexadecimal numbers or you can replace RRBBGG by the decimal equivalent. With Excel the sequence is reversed so &HBBGGRR or the decimal equivalent.

49407 is the decimal equivalent of 00C0FF which for Excel means Blue = 0, Green = 192 and Red = 255.

But &HC0FF or &H00C0FF is -16129 or Blue = 255, Green = 192 and Red = 255. This seems to be a flaw in the &H conversion. I cannot find anyway of getting C0FF converted to 49407.

If you insist on using the &H conversion, the best I can offer is:

 Range("A1:A5").Interior.color = &H01C0FF

This is Blue = 1, Green = 192 and Red = 255 and I cannot tell the difference from Blue = 0, Green = 192 and Red = 255.

But I would recommend:

Range("A1:A5").Interior.color = RGB(255,192,0)

because the RGB function always returns a positive number and you do not have to worry about Excel's reverse sequence.

Tony Dallimore
  • 12,335
  • 7
  • 32
  • 61
  • yeah, you can't skip the leading 0's...... the answer about the int size is very cool, but this is very much the practical answer – Mike M Oct 23 '17 at 00:46
  • 1
    This is the REAL answer. Way to use your own "Standard" Microsoft. – BenPen Nov 25 '19 at 20:07
4

A Colorcode is usually composed of three values, RED, GREEN, BLUE. Your Hexcode is missing one of the three and excel is autofilling it with FF. So your color C0FF is transformed to be FFC0FF.

Here is an Exampleprogram so you can see it in action, make a new sheet and execute it.

' C0FF will be changed to be FFC0FF
Range("A1").Interior.Color = &HC0FF
Range("A1").Select
ActiveCell.FormulaR1C1 = Range("A1").Interior.Color
Range("A2").Select
ActiveCell.FormulaR1C1 = "=DEC2HEX(R[-1]C,6)"

' 49407 is actually 00C0FF
Range("B1").Interior.Color = 49407
Range("B1").Select
ActiveCell.FormulaR1C1 = Range("B1").Interior.Color
Range("B2").Select
ActiveCell.FormulaR1C1 = "=DEC2HEX(R[-1]C,6)"

' Use RGB to have better control over your results
' Switch the order when doing so: 00C0FF => 00 Blue C0 Green FF Red
Range("C1").Interior.Color = RGB(&HFF, &HC0, &H0)
Range("C1").Select
ActiveCell.FormulaR1C1 = Range("C1").Interior.Color
Range("C2").Select
ActiveCell.FormulaR1C1 = "=DEC2HEX(R[-1]C,6)"

EDIT: Added a third example to illustrate switching the colors as suggested in a different answer.

Johannes
  • 6,490
  • 10
  • 59
  • 108
  • That clears a lot of it up. Thanks! I have switched to specifying RGB values separately but I am wondering if it is possible to make excel read it as `00C0FF` directly? – Anirudh Ramanathan Sep 28 '12 at 18:23