【发布时间】:2014-07-30 17:23:19
【问题描述】:
我试图逐步将单元格的背景颜色更改为黑色,但我发现 Range.Interior.Color 方法返回了一个看似任意的 Long。查看 MSDN 上的文档,几乎没有关于这个数字代表什么。有没有办法从这个 long 中返回 RGB 值。我实际上需要 RGB(red,green,blue) 函数的反面。
【问题讨论】:
我试图逐步将单元格的背景颜色更改为黑色,但我发现 Range.Interior.Color 方法返回了一个看似任意的 Long。查看 MSDN 上的文档,几乎没有关于这个数字代表什么。有没有办法从这个 long 中返回 RGB 值。我实际上需要 RGB(red,green,blue) 函数的反面。
【问题讨论】:
这个“任意”数字是 RGB 值 (B256^2 + G256 + R) 和十六进制颜色值转换为十进制数(基数为 16 到以 10 为底),具体取决于您要查看的方式。只是基数不同。下面是我在为 Excel 编写的 XLAM 插件文件中使用的方法。这种方法多次派上用场。我已将文档包含在我的插件文件中。
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Function Color
' Purpose Determine the Background Color Of a Cell
' @Param rng Range to Determine Background Color of
' @Param formatType Default Value = 0
' 0 Integer
' 1 Hex
' 2 RGB
' 3 Excel Color Index
' Usage Color(A1) --> 9507341
' Color(A1, 0) --> 9507341
' Color(A1, 1) --> 91120D
' Color(A1, 2) --> 13, 18, 145
' Color(A1, 3) --> 6
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function Color(rng As Range, Optional formatType As Integer = 0) As Variant
Dim colorVal As Variant
colorVal = rng.Cells(1, 1).Interior.Color
Select Case formatType
Case 1
Color = WorksheetFunction.Dec2Hex(colorVal, 6)
Case 2
Color = (colorVal Mod 256) & ", " & ((colorVal \ 256) Mod 256) & ", " & (colorVal \ 65536)
Case 3
Color = rng.Cells(1, 1).Interior.ColorIndex
Case Else
Color = colorVal
End Select
End Function
【讨论】:
R*256^2 + G*256 + B 这将不是 VBA,其中最简单的东西必须是古怪的。事实上恰恰相反:B*256^2 + G*256 + R
很高兴看到怀亚特先生使用了颜色到 RGB 的快速方法
R = C Mod 256
G = C \ 256 Mod 256
B = C \ 65536 Mod 256
这比使用左中右的十六进制 str 快很多倍 有些人推荐
【讨论】:
简答:
没有内置功能。您必须编写自己的函数。
长答案:
从 Interior.Color 属性返回的 long 是我们习惯于在 html 中看到颜色的典型十六进制数字的十进制转换,例如“66FF66”。此外,可以传递常量 xlNone (-4142) 以将单元格设置为在背景中没有颜色,但是这些单元格在Get 属性中标记为白色RGB(255, 255, 255)。知道了这一点,我们就可以编写一个函数来返回一个或所有适当的 RGB 值。
幸运的是,一位善良的艾伦·怀亚特先生在这里做到了!
【讨论】:
另一个答案对我不起作用。我发现:
R = C And 255
G = C \ 256 And 255
B = C \ 256 ^ 2 And 255
它工作正常。
【讨论】:
RGB(50,100,200) = RGB(50,100,200) Mod 256 的红色值和RGB(50,100,200) = RGB(50,100,200) And 255 的红色值
X Mod 256 与X And 255 相同。通过执行And 255,您实际上过滤了从 256 开始的所有位,并且只保留前 8 位,这正是 256 的大小。同样适用于 128、64 等。
这是给猫剥皮的另一种方法
'
' Type definition in declarations
'
Type RGBcolor
r As Long
g As Long
b As Long
End Type
'
' Inverse RGB function
'
Function GetRGB(ByVal x As Long) As RGBcolor
With GetRGB
.r = x Mod 256
x = x \ 256
.g = x Mod 256
x = x \ 256
.b = x Mod 256
End With
End Function
'
' Sub to test the GetRGB function
'
Sub test(x As Long)
Dim c As RGBcolor
c = GetRGB(x) ' returns RGB values: c.r, c.g, c.b
Debug.Print "Original", "Red", "Green", "Blue", "Recombined value"
Debug.Print x, c.r, c.g, c.b, RGB(c.r, c.g, c.b)
End Sub
'
'
***** IMMEDIATE WINDOW *****
test 1000
Original Red Green Blue Recombined value
1000 232 3 0 1000
【讨论】:
应该注意,对于十六进制值,如果您要导出为 HTML,您也会遇到怪癖。
理想情况下,您应该从单个颜色创建十六进制字符串,而不是从 ColorVal 数字返回一个十六进制。
如果单元格是像绿色/蓝色这样的“纯”颜色,您可能会得到一些无效的十六进制数字
RED - RGB(255,0,0) 返回 'FF' - 它应该返回 'FF0000'
BLUE - RGB(0,0,255) 返回 'FF00000' - 它应该返回 '0000FF'
如果你使用这些来创建 HTML/CSS 颜色输出,你会得到任何蓝色单元格的红色。
我修改了脚本以根据 RGB 值组装每两个字符的十六进制“块”,并使用一个 UDF 填充一个前导 0,返回一个字符的输出(希望如果您正在阅读本文,您可以做类似的东西)
Color = ZeroPad(Hex((colorVal Mod 256)), 2) & ZeroPad(Hex(((colorVal \ 256) Mod 256)), 2) & ZeroPad(Hex((colorVal \ 65536)), 2)
--编辑:忘记包含 UDF 的代码...
Function ZeroPad(text As String, Cnt As Integer) As String
'Text is the string to pad
'Cnt is the length to pad to, for example ZeroPad(12,3) would return a string '012' , Zeropad(12,8) would return '00000012' etc..
Dim StrLen As Integer, StrtString As String, Padded As String, LP As Integer
StrLen = Len(Trim(text))
If StrLen < Cnt Then
For LP = 1 To Cnt - StrLen
Padded = Padded & "0"
Next LP
End If
ZeroPad = Padded & Trim(text)
ENDOF:
End Function
顺便说一句 - 如果您希望在表单编辑器中显示十六进制代码(莫名其妙地有它自己的标准,除了普通的 HTML 十六进制颜色)
Case 4 ' ::: VBA FORM HEX :::
Color = "&H00" & ZeroPad(Hex((colorVal \ 65536)), 2) & ZeroPad(Hex(((colorVal \ 256) Mod 256)), 2) & ZeroPad(Hex((colorVal Mod 256)), 2) & "&"
【讨论】:
WorksheetFunction.Dec2Hex(colorVal Mod 256, 2) & WorksheetFunction.Dec2Hex((colorVal \ 256) Mod 256, 2) & WorksheetFunction.Dec2Hex(colorVal \ 65536, 2) 用于您的第一个,WorksheetFunction.Dec2Hex(colorVal, 6) 用于您的第二个。
Mark Balhoff 的 VBA 脚本运行良好。所有功劳归他所有。
如果您还想获得条件格式单元格的颜色代码/索引,可以像这样修改代码:
'----------------------------------------------------------------
' Function Color
' Purpose Determine the Background Color Of a Cell
' @Param rng Range to Determine Background Color of
' @Param formatType Default Value = 0
' 0 Integer color of cell, not considering conditional formatting color
' 1 Hex color of cell, not considering conditional formatting color
' 2 RGB color of cell, not considering conditional formatting color
' 3 Excel Color Index color of cell, not considering conditional formatting color
' 4 Integer "real" visible color of cell (as the case may be the conditional formatting color)
' 5 Hex "real" visible color of cell (as the case may be the conditional formatting color)
' 6 RGB "real" visible color of cell (as the case may be the conditional formatting color)
' 7 Excel Color Index "real" visible color of cell (as the case may be the conditional formatting color)
' Usage Color(A1) --> 9507341
' Color(A1, 0) --> 9507341
' Color(A1, 1) --> 91120D
' Color(A1, 2) --> 13, 18, 145
' Color(A1, 3) --> 6
'-----------------------------------------------------------------
Function Color(rng As Range, Optional formatType As Integer = 0) As Variant
Dim colorVal As Variant
Select Case formatType
Case 0 To 3
colorVal = Cells(rng.Row, rng.Column).Interior.Color
Case 4 To 7
colorVal = Cells(rng.Row, rng.Column).DisplayFormat.Interior.Color
End Select
Select Case formatType
Case 0
Color = colorVal
Case 1
Color = Hex(colorVal)
Case 2
Color = (colorVal Mod 256) & ", " & ((colorVal \ 256) Mod 256) & ", " & (colorVal \ 65536)
Case 3
Color = Cells(rng.Row, rng.Column).Interior.ColorIndex
Case 4
Color = colorVal
Case 5
Color = Hex(colorVal)
Case 6
Color = (colorVal Mod 256) & ", " & ((colorVal \ 256) Mod 256) & ", " & (colorVal \ 65536)
Case 7
Color = Cells(rng.Row, rng.Column).DisplayFormat.Interior.ColorIndex
End Select
End Function
【讨论】:
Select Case formatType 更改为Select Case formatType Mod 4 允许删除案例4 到7(不必要的代码重复)。我也可能会选择将大开关块中的最后一个Case 转换为Case Else,以默认用户输入错误,并将较小的开关块转换为If formatType < 4 Then ... Else ... End If,但最后两个是更多个人选择。跨度>
将这 3 个不言自明的单行字放到一个模块中,然后在 VBA 或工作表公式中使用它们:
Function rr(rgbCode): rr = rgbCode Mod 256: End Function
Function g(rgbCode): g = (rgbCode \ 256) Mod 256: End Function
Function b(rgbCode): b = rgbCode \ 65536: End Function
(我不能使用单个 R 作为 red 的函数名,因为在 Goto F5reserved /kbd> & 名称 CTRL+F3 对话框。)
【讨论】: