【问题标题】:Return RGB values from Range.Interior.Color (or any other Color Property)从 Range.Interior.Color(或任何其他颜色属性)返回 RGB 值
【发布时间】:2014-07-30 17:23:19
【问题描述】:

我试图逐步将单元格的背景颜色更改为黑色,但我发现 Range.Interior.Color 方法返回了一个看似任意的 Long。查看 MSDN 上的文档,几乎没有关于这个数字代表什么。有没有办法从这个 long 中返回 RGB 值。我实际上需要 RGB(red,green,blue) 函数的反面。

【问题讨论】:

    标签: excel vba colors rgb


    【解决方案1】:

    这个“任意”数字是 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
    

    【讨论】:

    • 如果 RGB() 数字被编码为 R*256^2 + G*256 + B 这将不是 VBA,其中最简单的东西必须是古怪的。事实上恰恰相反:B*256^2 + G*256 + R
    • @Nickolay 当然是的,这是无穷无尽的 VBA 怪癖的一部分。为了我自己的利益,我一定是打得太快了。谢谢你的收获!!固定的。有人花了这么长时间才指出这一点,有点惊讶。我很惊讶我把它搞砸了,因为我在写这个方法时就知道这个怪癖,它显示了我是如何写出 R、G、B 的。
    • 是的。我只是注意到,因为我认为手工计算会更快,而不是复制粘贴(正确)代码并运行它:)
    • @Nickolay FWIW 怪癖在于 Excel 对象模型(类型库),而不是 VBA(语言)。 Excel v1.0 已经需要与 1985 年的工作表进行反向兼容,我认为 Excel 工作表单元格内部在 CSS 成为梦想之前几年就已经存在。说到怪癖……
    • @Mathieu:嘿,顺便说一句,感谢您在橡皮鸭上所做的努力!
    【解决方案2】:

    很高兴看到怀亚特先生使用了颜色到 RGB 的快速方法

    R = C Mod 256
    G = C \ 256 Mod 256
    B = C \ 65536 Mod 256
    

    这比使用左中右的十六进制 str 快很多倍 有些人推荐

    【讨论】:

      【解决方案3】:

      简答:

      没有内置功能。您必须编写自己的函数。

      长答案:

      从 Interior.Color 属性返回的 long 是我们习惯于在 html 中看到颜色的典型十六进制数字的十进制转换,例如“66FF66”。此外,可以传递常量 xlNone (-4142) 以将单元格设置为在背景中没有颜色,但是这些单元格在Get 属性中标记为白色RGB(255, 255, 255)。知道了这一点,我们就可以编写一个函数来返回一个或所有适当的 RGB 值。

      幸运的是,一位善良的艾伦·怀亚特先生在这里做到了!

      Determining the RGB Value of a Color

      【讨论】:

        【解决方案4】:

        另一个答案对我不起作用。我发现:

        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 256X And 255 相同。通过执行And 255,您实际上过滤了从 256 开始的所有位,并且只保留前 8 位,这正是 256 的大小。同样适用于 128、64 等。
        【解决方案5】:

        这是给猫剥皮的另一种方法

        '
        ' 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 
        

        【讨论】:

          【解决方案6】:

          应该注意,对于十六进制值,如果您要导出为 HTML,您也会遇到怪癖。

          理想情况下,您应该从单个颜色创建十六进制字符串,而不是从 ColorVal 数字返回一个十六进制。

          如果单元格是像绿色/蓝色这样的“纯”颜色,您可能会得到一些无效的十六进制数字

          RED - RGB(255,0,0) 返回 'FF' - 它应该返回 'FF0000'

          BLUE - RGB(0,0,255) 返回 'FF00000' - 它应该返回 '0000FF'

          enter image description here

          如果你使用这些来创建 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) & "&"
          

          【讨论】:

          • +1 我认为您正在充实我的回答下的 cmets 中指出的内容(Excel 的十六进制部分与 HTML 实现的顺序相反)。然后还添加前导零。后者可以在没有新功能的情况下完成。转换为十六进制的工作表函数有第二个长度参数。所以:WorksheetFunction.Dec2Hex(colorVal Mod 256, 2) &amp; WorksheetFunction.Dec2Hex((colorVal \ 256) Mod 256, 2) &amp; WorksheetFunction.Dec2Hex(colorVal \ 65536, 2) 用于您的第一个,WorksheetFunction.Dec2Hex(colorVal, 6) 用于您的第二个。
          【解决方案7】:

          Mark Ba​​lhoff 的 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
          

          【讨论】:

          • 肯定是一个有价值的补充,我很欣赏引用,但有几个简短的说明:1) 如果将其用作工作表函数和 2),DisplayFormat 调用将出错 将第二个Select Case formatType 更改为Select Case formatType Mod 4 允许删除案例4 到7(不必要的代码重复)。我也可能会选择将大开关块中的最后一个Case 转换为Case Else,以默认用户输入错误,并将较小的开关块转换为If formatType &lt; 4 Then ... Else ... End If,但最后两个是更多个人选择。跨度>
          【解决方案8】:

          简答

          将这 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 对话框。)

          【讨论】:

            猜你喜欢
            • 2011-03-04
            • 1970-01-01
            • 2013-12-02
            • 1970-01-01
            • 1970-01-01
            • 2013-06-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多