如何在Excel/VBA中获取RGB颜色对应的十六进制值?

10

我正在尝试在我的VBA代码中设置一个公共颜色常量。通常,我可以使用以下代码:

Dim BLUE As Long
BLUE = RGB(183, 222, 232)

然而,由于RGB函数的存在,无法将其设为公共常量。我使用在线转换器将此RGB值转换为十六进制,并得到了B7DEE8。

使用:

BLUE = &HB7DEE8

结果显示完全不同的颜色。我认为这可能是RGBA颜色,已经尝试使用B7DEE8__,并且最后一个数字为B8时其颜色非常接近,但是我想知道如何找到正确的值。
注意:我实际上不需要将其转换为十六进制代码,我只需要知道如何找到它,因为我在Excel表格中使用了五个固定颜色,并希望设置它们。
7个回答

13

表面上看似乎出现了颜色反转的原因是RGB()函数实际上创建了一个BGR值。

更具体地说,红色字节是低位字节,蓝色字节是高位字节(或至少是四个中的第三个)。

在立即窗口中尝试此示例:

x = RGB(255, 0, 128) ' full red, half blue
? hex(x)
8000FF

x = RGB(128, 0, 255) ' half red, full blue
? hex(x)
FF0080
请注意,"满"字节(255或FF)和"半满"字节(128或80)在每个结果中都位于相反的侧面。这就是为什么您需要按与预期相反的顺序指定十六进制常数以获得相同值的原因。
此外,无需使用在线转换器。Hex()函数提供所给数字的十六进制值,Int将接受十六进制格式的字符串并返回十进制值:
? Int("&hff0000") 
 16711680

更新:

要使用这些信息创建你的十六进制常量,你只需在即时窗口中运行你的RGB()和Hex()语句(输入Ctrl+G打开和关闭它),然后将生成的Hex值用作常量。如果该值少于6位数字,则可以在左侧用零进行填充,但从技术上讲这并不是必须的:

x = RGB(183, 222, 232)
? "Public Const MyBlue = &h" & hex(x)
Public Const MyBlue = &hE8DEB7

然后将那行代码复制到您的代码中。


很不幸,由于我正在尝试将颜色设置为公共常量,所以我无法使用Hex()或RGB()来定义它们,因为它们不是常量。但这是非常有用的信息,谢谢! - Brandon

12

你需要将字节顺序反转

BLUE = &HE8DEB7

获取正确的颜色值。


1
@Brandon 我不知道这个问题是否有任何答案。但至少已经有文档记录,例如这里 - Howard

5

好的,接下来将介绍如何在Excel 2010中获取单元格颜色并提供有效的十六进制代码:

Public Function getHexCol(a As Range)

' In excel type in for example getHexCol(A1) to get the hexcode of the color on     A1.
Dim strColour As String
Dim hexColour As String
Dim nColour As Long
Dim nR As Long, nB As Long, nG As Long

strColour = a.Interior.Color
If Len(strColour) = 0 Then Exit Function

nColour = Val(strColour) ' convert string to decimal number
hexColour = Hex(nColour) ' convert decimal number to hex string
While Len(hexColour) < 6 ' pad on left to 6 hex digits
hexColour = "0" & hexColour
Wend

nB = CLng("&H" & Mid(hexColour, 1, 2))
nG = CLng("&H" & Mid(hexColour, 3, 2))
nR = CLng("&H" & Mid(hexColour, 5, 2))

getHexCol = Hex(RGB(nB, nG, nR))
End Function

2
Function GetRGB(ByVal cell As Range) As String

Dim R As String, G As String
Dim b As String, hexColor As String
hexCode = Hex(cell.Interior.Color)

'Note the order excel uses for hex is BGR.
b = Val("&H" & Mid(hexCode, 1, 2))
G = Val("&H" & Mid(hexCode, 3, 2))
R = Val("&H" & Mid(hexCode, 5, 2))

GetRGB = R & ":" & G & ":" & b
End Function

请注意,Excel中的RGB值是反过来的(BGR)。

刚试了一下... hex(interior.color) 不能得到正确结果... 例如,尝试这个。Excel 颜色 10192433 对应的 RGB 值为 '49,134,155',应该对应十六进制值 31869b.... 但是 hex(10192433) 的结果是 9BD7C4 - Amit Kohli
我没有遇到这个问题。我尝试重现你所说的,但即使使用 MsgBox (Hex(10192433)) 正确地向我显示 9B8631...(我在 Excel 2013 上) - SourceSeeker
@SourceSeeker 是的,这个颜色(10192433)在色彩图表上是 R-49 G-134 B-155,即十六进制的 R-31 G-86 B-9b(31 86 9b 组合成的一种蓝绿色)。因为 XL 显示的 RGB 值实际上是反转的 BGR(可能是由于字节序),所以需要注意。但是,10192433 的十六进制值实际上是 9b 86 31。请注意位被翻转了,它是 BGR 而不是 RGB。如果 XL 将其显示为 RGB,则十进制数实际上将是 3245723 而不是 10192433。 - John Smith
@iliketocode 我已经注意到Excel函数hex(...)返回的RGB值是相反的,但我仍然不明白Amit Kohli的十六进制值9BD7C4来自哪里:"但是hex(10192433) = 9BD7C4"。9BD7C4 = 9B D7 C4 = 155 215 196 = 12900251 (XL: RGB(155,215,196)的值) = 浅绿松石色 = C4D79B (XL: HEX(12900251)的值 = BGR) >LINE BREAK< C4D79B = C4 D7 9B = 196 215 155 = 10213316 (XL: RGB(196,215,155)的值) = 浅绿色 = 9BD7C4 (XL: HEX(10213316)的值 = BGR) - SourceSeeker

0

这里是另一个函数,它也适用于MS Access,并考虑了RGB顺序的反转:

Function VBA_RGB_To_HEX(iRed As Integer, iGreen As Integer, iBlue As Integer) As String
    Dim sHex As String
    sHex = "#" & VBA.Right$("00" & VBA.Hex(iBlue), 2) & VBA.Right$("00" & VBA.Hex(iGreen), 2) & VBA.Right$("00" & VBA.Hex(iRed), 2)
    VBA_RGB_To_HEX = sHex
End Function

0
抱歉我回复晚了。
像工作表上的按钮这样的ActiveX元素可以更改其背景和字体颜色。它们使用一种类似于&H00B5752F&的特定HEX格式。它是基于蓝色、绿色、红色的顺序,而不是RGB类型的红色、绿色、蓝色的顺序。
如果您知道RGB值并想转换为ActiveX颜色HEX格式,可以使用以下步骤。
Sub RGB_to_ActiveX_HEX_Color()
'       This macro allows the user to input numeric RGB values
'       to get the HEX format for Activex element Hex Colors
'
'       Result will be printed in the immediate window
'
'       Example: RGB(47,117,181)  =  &H00B5752F&


Dim mySplitArr
Dim myRGB_numbers As Variant
Dim newStr As String
Dim commaTally As Long
        
        myRGB_numbers = InputBox("Enter RGB values separated by commas ", "RGB to HEX")
        
        On Error GoTo error_Handler_main
        mySplitArr = Split(myRGB_numbers, Chr(44))
        
        For i = LBound(mySplitArr) To UBound(mySplitArr)
            If Not IsNumeric(mySplitArr(i)) Or mySplitArr(i) < 0 Or mySplitArr(i) > 255 Then GoTo error_Handler_main
        Next i
        
        If UBound(mySplitArr) < 2 Then GoTo error_Handler_main
        
        Debug.Print "RGB(" & mySplitArr(0) & ", " & mySplitArr(1) & ", " & mySplitArr(2) & ")  =  " & "&H00" & VBA.Right$("00" & VBA.Hex(mySplitArr(2)), 2) & VBA.Right$("00" & VBA.Hex(mySplitArr(1)), 2) & VBA.Right$("00" & VBA.Hex(mySplitArr(0)), 2) & "&"

Exit Sub
error_Handler_main:
    MsgBox "There was an error in your input" & vbNewLine & vbNewLine & _
            "Be sure to separate RGB values with commas." & vbNewLine & vbNewLine & _
            "example:   123,255,0" & vbNewLine & vbNewLine & _
            "Also values must be between 0 and 255 for each color"
    Exit Sub
    

End Sub

-1

我测试了这段代码,但无法真正理解Howard的答案

Dim rd, gr, bl As Integer
rd = 183
gr = 222
bl = 232
BLUE = RGB(rd, gr, bl)
hexclr = Format(CStr(Hex(rd)), "00") +
Format(CStr(Hex(gr)), "00") + 
Format(CStr(Hex(bl)), "00")
MsgBox hexclr 'B7DEE8

只需添加另一行:MsgBox Hex(BLUE) 'E8DEB7,您就会发现颜色字节被反转了。 - Howard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接