Hello there,
this article is about how to get Material Color Palette [https://material.io/guidelines/style/color.html#] into VBA code and how to deal with it. Plus, one little specialty – color interpolation to get full gradient of material colors.
You can find full code & example on my repo https://github.com/inDeev/Material-Colors-in-Excel-VBA
We need to prepare Excel file with macro support, so open new Excel sheet and save it as MaterialColorPalette.xlsm. While sheet is opened, run VBA window by [Alt+F11].
Insert new module into Project [Menu->Insert->Module] and rename it to materialColors in Properties window
Now open materialColor module by double click on it and insert code pasted below
Option Explicit
Public Function matColor(Name As String, Optional intensity As Integer = 500) As Long
Dim colorValue As Long
matColor = colorValue
End Function
When you look at material color website, you may notice, that each color in palette is defined by color name and number (50, 100, 200, …, 900) which defines color intensity. Because of that we use arguments Name (String) and intensity(integer), which is optional with default value of 500 (“Google suggests using the 500 colors as the primary colors”). Return type of our function is Long, because this is type which color in Excel VBA is presented by. colorValue is temporary variable which allows us to assign RGB values before they are returned by function.
If Name = "White" Then matColor = RGB(255, 255, 255): Exit Function
If Name = "Black" Then matColor = RGB(0, 0, 0): Exit Function
Material palette comes with 19 color shades. For so many values we rather use Select Case-Case-End Select conditions instead of If-ElseIf-Else-End If.
If Name = "White" Then matColor = RGB(255, 255, 255): Exit Function
If Name = "Black" Then matColor = RGB(0, 0, 0): Exit Function
Select Case Name ‘Requires exact color name e.g. “Light Blue”
Case "Red"
Case "Pink"
Case "Purple"
Case "Deep Purple"
Case "Indigo"
Case "Blue"
Case "Light Blue"
Case "Cyan"
Case "Teal"
Case "Green"
Case "Light Green"
Case "Lime"
Case "Yellow"
Case "Amber"
Case "Orange"
Case "Deep Orange"
Case "Brown"
Case "Grey"
Case "Blue Grey"
End Select
Now by little modification we allow to call color name by case insensitive values by modification of Name argument value and color name cases turned to lowercase:
Name = LCase(Name)
If Name = "white" Then matColor = RGB(255, 255, 255): Exit Function
If Name = "black" Then matColor = RGB(0, 0, 0): Exit Function
Select Case Name ‘Allows case insensitive names e.g. “Light blue”, “liGHt Blue”
Case "red"
Case "pink"
Case "purple"
Case "deep purple"
...
End Select
By next modification of Name argument value and color name cases (remove spaces) we allow to enter two-word names with or without spaces:
Name = LCase(Replace(Name, " ", ""))
If Name = "white" Then matColor = RGB(255, 255, 255): Exit Function
If Name = "black" Then matColor = RGB(0, 0, 0): Exit Function
Select Case Name ‘Allows case insensitive names w/ or w/o spaces e.g. “lIghtBlUe”
Case "red"
Case "pink"
Case "purple"
Case "deeppurple"
...
End Select
And finally, we allow to use grey/gray values for last two colors:
Case "gray", "grey"
Case "bluegray", "bluegrey"
Here comes the most boring part of whole function – manual copy & paste of color values. But with a little problem – colors are described by hexadecimal codes, VBA needs RGB defined by decimal values. In code below are that values converted and assigned to colorValue variable by RGB command.
Name = LCase(Replace(Name, " ", ""))
If Name = "white" Then matColor = RGB(255, 255, 255): Exit Function
If Name = "black" Then matColor = RGB(0, 0, 0): Exit Function
Select Case Name ‘Allows case insensitive names w/ or w/o spaces e.g. “lIghtBlUe”
Case "red"
Select Case intensity
Case 50: colorValue = RGB(255, 235, 238)
Case 100: colorValue = RGB(255, 205, 210)
Case 200: colorValue = RGB(239, 154, 154)
Case 300: colorValue = RGB(229, 115, 115)
Case 400: colorValue = RGB(239, 83, 80)
Case 500: colorValue = RGB(244, 67, 54)
Case 600: colorValue = RGB(229, 57, 53)
Case 700: colorValue = RGB(211, 47, 47)
Case 800: colorValue = RGB(198, 40, 40)
Case 900: colorValue = RGB(183, 28, 28)
End Select
Case "pink"
Select Case intensity
Case 50: colorValue = RGB(252, 228, 236)
Case 100: colorValue = RGB(248, 187, 208)
Case 200: colorValue = RGB(244, 143, 177)
Case 300: colorValue = RGB(240, 98, 146)
Case 400: colorValue = RGB(236, 64, 122)
Case 500: colorValue = RGB(233, 30, 99)
Case 600: colorValue = RGB(216, 27, 96)
Case 700: colorValue = RGB(194, 24, 91)
Case 800: colorValue = RGB(173, 20, 87)
Case 900: colorValue = RGB(136, 14, 79)
End Select
Case "purple"
Select Case intensity
Case 50: colorValue = RGB(243, 229, 245)
Case 100: colorValue = RGB(225, 190, 231)
Case 200: colorValue = RGB(206, 147, 216)
Case 300: colorValue = RGB(186, 104, 200)
Case 400: colorValue = RGB(171, 71, 188)
Case 500: colorValue = RGB(156, 39, 176)
Case 600: colorValue = RGB(142, 36, 170)
Case 700: colorValue = RGB(123, 31, 162)
Case 800: colorValue = RGB(106, 27, 154)
Case 900: colorValue = RGB(74, 20, 140)
End Select
Case "deeppurple"
Select Case intensity
Case 50: colorValue = RGB(237, 231, 246)
Case 100: colorValue = RGB(209, 196, 233)
Case 200: colorValue = RGB(179, 157, 219)
Case 300: colorValue = RGB(149, 117, 205)
Case 400: colorValue = RGB(126, 87, 194)
Case 500: colorValue = RGB(103, 58, 183)
Case 600: colorValue = RGB(94, 53, 177)
Case 700: colorValue = RGB(81, 45, 168)
Case 800: colorValue = RGB(69, 39, 160)
Case 900: colorValue = RGB(49, 27, 146)
End Select
Case "indigo"
Select Case intensity
Case 50: colorValue = RGB(232, 234, 246)
Case 100: colorValue = RGB(197, 202, 233)
Case 200: colorValue = RGB(159, 168, 218)
Case 300: colorValue = RGB(121, 134, 203)
Case 400: colorValue = RGB(92, 107, 192)
Case 500: colorValue = RGB(63, 81, 181)
Case 600: colorValue = RGB(57, 73, 171)
Case 700: colorValue = RGB(48, 63, 159)
Case 800: colorValue = RGB(40, 53, 147)
Case 900: colorValue = RGB(26, 35, 126)
End Select
Case "blue"
Select Case intensity
Case 50: colorValue = RGB(227, 242, 253)
Case 100: colorValue = RGB(187, 222, 251)
Case 200: colorValue = RGB(144, 202, 249)
Case 300: colorValue = RGB(100, 181, 246)
Case 400: colorValue = RGB(66, 165, 245)
Case 500: colorValue = RGB(33, 150, 243)
Case 600: colorValue = RGB(30, 136, 229)
Case 700: colorValue = RGB(25, 118, 210)
Case 800: colorValue = RGB(21, 101, 192)
Case 900: colorValue = RGB(13, 71, 161)
End Select
Case "lightblue"
Select Case intensity
Case 50: colorValue = RGB(225, 245, 254)
Case 100: colorValue = RGB(179, 229, 252)
Case 200: colorValue = RGB(129, 212, 250)
Case 300: colorValue = RGB(79, 195, 247)
Case 400: colorValue = RGB(41, 182, 246)
Case 500: colorValue = RGB(3, 169, 244)
Case 600: colorValue = RGB(3, 155, 229)
Case 700: colorValue = RGB(2, 136, 209)
Case 800: colorValue = RGB(2, 119, 189)
Case 900: colorValue = RGB(1, 87, 155)
End Select
Case "cyan"
Select Case intensity
Case 50: colorValue = RGB(224, 247, 250)
Case 100: colorValue = RGB(178, 235, 242)
Case 200: colorValue = RGB(128, 222, 234)
Case 300: colorValue = RGB(77, 208, 225)
Case 400: colorValue = RGB(38, 198, 218)
Case 500: colorValue = RGB(0, 188, 212)
Case 600: colorValue = RGB(0, 172, 193)
Case 700: colorValue = RGB(0, 151, 167)
Case 800: colorValue = RGB(0, 131, 143)
Case 900: colorValue = RGB(0, 96, 100)
End Select
Case "teal"
Select Case intensity
Case 50: colorValue = RGB(224, 242, 241)
Case 100: colorValue = RGB(178, 223, 219)
Case 200: colorValue = RGB(128, 203, 196)
Case 300: colorValue = RGB(77, 182, 172)
Case 400: colorValue = RGB(38, 166, 154)
Case 500: colorValue = RGB(0, 150, 136)
Case 600: colorValue = RGB(0, 137, 123)
Case 700: colorValue = RGB(0, 121, 107)
Case 800: colorValue = RGB(0, 105, 92)
Case 900: colorValue = RGB(0, 77, 64)
End Select
Case "green"
Select Case intensity
Case 50: colorValue = RGB(232, 245, 233)
Case 100: colorValue = RGB(200, 230, 201)
Case 200: colorValue = RGB(165, 214, 167)
Case 300: colorValue = RGB(129, 199, 132)
Case 400: colorValue = RGB(102, 187, 106)
Case 500: colorValue = RGB(76, 175, 80)
Case 600: colorValue = RGB(67, 160, 71)
Case 700: colorValue = RGB(56, 142, 60)
Case 800: colorValue = RGB(46, 125, 50)
Case 900: colorValue = RGB(27, 94, 32)
End Select
Case "lightgreen"
Select Case intensity
Case 50: colorValue = RGB(241, 248, 233)
Case 100: colorValue = RGB(220, 237, 200)
Case 200: colorValue = RGB(197, 225, 165)
Case 300: colorValue = RGB(174, 213, 129)
Case 400: colorValue = RGB(156, 204, 101)
Case 500: colorValue = RGB(139, 195, 74)
Case 600: colorValue = RGB(124, 179, 66)
Case 700: colorValue = RGB(104, 159, 56)
Case 800: colorValue = RGB(85, 139, 47)
Case 900: colorValue = RGB(51, 105, 30)
End Select
Case "lime"
Select Case intensity
Case 50: colorValue = RGB(249, 251, 231)
Case 100: colorValue = RGB(240, 244, 195)
Case 200: colorValue = RGB(230, 238, 156)
Case 300: colorValue = RGB(220, 231, 117)
Case 400: colorValue = RGB(212, 225, 87)
Case 500: colorValue = RGB(205, 220, 57)
Case 600: colorValue = RGB(192, 202, 51)
Case 700: colorValue = RGB(175, 180, 43)
Case 800: colorValue = RGB(158, 157, 36)
Case 900: colorValue = RGB(130, 119, 23)
End Select
Case "yellow"
Select Case intensity
Case 50: colorValue = RGB(255, 253, 231)
Case 100: colorValue = RGB(255, 249, 196)
Case 200: colorValue = RGB(255, 245, 157)
Case 300: colorValue = RGB(255, 241, 118)
Case 400: colorValue = RGB(255, 238, 88)
Case 500: colorValue = RGB(255, 235, 59)
Case 600: colorValue = RGB(253, 216, 53)
Case 700: colorValue = RGB(251, 192, 45)
Case 800: colorValue = RGB(249, 168, 37)
Case 900: colorValue = RGB(245, 127, 23)
End Select
Case "amber"
Select Case intensity
Case 50: colorValue = RGB(255, 248, 225)
Case 100: colorValue = RGB(255, 236, 179)
Case 200: colorValue = RGB(255, 224, 130)
Case 300: colorValue = RGB(255, 213, 79)
Case 400: colorValue = RGB(255, 202, 40)
Case 500: colorValue = RGB(255, 193, 7)
Case 600: colorValue = RGB(255, 179, 0)
Case 700: colorValue = RGB(255, 160, 0)
Case 800: colorValue = RGB(255, 143, 0)
Case 900: colorValue = RGB(255, 111, 0)
End Select
Case "orange"
Select Case intensity
Case 50: colorValue = RGB(255, 243, 224)
Case 100: colorValue = RGB(255, 224, 178)
Case 200: colorValue = RGB(255, 204, 128)
Case 300: colorValue = RGB(255, 183, 77)
Case 400: colorValue = RGB(255, 167, 38)
Case 500: colorValue = RGB(255, 152, 0)
Case 600: colorValue = RGB(251, 140, 0)
Case 700: colorValue = RGB(245, 124, 0)
Case 800: colorValue = RGB(239, 108, 0)
Case 900: colorValue = RGB(230, 81, 0)
End Select
Case "deeporange"
Select Case intensity
Case 50: colorValue = RGB(251, 233, 231)
Case 100: colorValue = RGB(255, 204, 188)
Case 200: colorValue = RGB(255, 171, 145)
Case 300: colorValue = RGB(255, 138, 101)
Case 400: colorValue = RGB(255, 112, 67)
Case 500: colorValue = RGB(255, 87, 34)
Case 600: colorValue = RGB(244, 81, 30)
Case 700: colorValue = RGB(230, 74, 25)
Case 800: colorValue = RGB(216, 67, 21)
Case 900: colorValue = RGB(191, 54, 12)
End Select
Case "brown"
Select Case intensity
Case 50: colorValue = RGB(239, 235, 233)
Case 100: colorValue = RGB(215, 204, 200)
Case 200: colorValue = RGB(188, 170, 164)
Case 300: colorValue = RGB(161, 136, 127)
Case 400: colorValue = RGB(141, 110, 99)
Case 500: colorValue = RGB(121, 85, 72)
Case 600: colorValue = RGB(109, 76, 65)
Case 700: colorValue = RGB(93, 64, 55)
Case 800: colorValue = RGB(78, 52, 46)
Case 900: colorValue = RGB(62, 39, 35)
End Select
Case "gray", "grey"
Select Case intensity
Case 50: colorValue = RGB(250, 250, 250)
Case 100: colorValue = RGB(245, 245, 245)
Case 200: colorValue = RGB(238, 238, 238)
Case 300: colorValue = RGB(224, 224, 224)
Case 400: colorValue = RGB(189, 189, 189)
Case 500: colorValue = RGB(158, 158, 158)
Case 600: colorValue = RGB(117, 117, 117)
Case 700: colorValue = RGB(97, 97, 97)
Case 800: colorValue = RGB(66, 66, 66)
Case 900: colorValue = RGB(33, 33, 33)
End Select
Case "bluegray", "bluegrey"
Select Case intensity
Case 50: colorValue = RGB(236, 239, 241)
Case 100: colorValue = RGB(207, 216, 220)
Case 200: colorValue = RGB(176, 190, 197)
Case 300: colorValue = RGB(144, 164, 174)
Case 400: colorValue = RGB(120, 144, 156)
Case 500: colorValue = RGB(96, 125, 139)
Case 600: colorValue = RGB(84, 110, 122)
Case 700: colorValue = RGB(69, 90, 100)
Case 800: colorValue = RGB(55, 71, 79)
Case 900: colorValue = RGB(38, 50, 56)
End Select
End Select
Now, if you call it from your application e.g.
Range(“A1”).Interior.Color = matColor(“Light blue”, 700)
Range(“A1”).Font.Color = matColor(“white”)
Range(“A1”).Value = “White on blue”
First cell of your sheet gets right colors defined by Material Color Palette:
Now we have exactly 10 shades of each of 19 colors. But what if we need to create smooth gradients or use other shade of given colors than predefined ones? In this case, we need to create linear interpolation between given color values.
In next step, we will create scale of Intensity from 0 to 1000, where 0 is white, 50 is first lighter color given by Material Palette, 900 is darker color of Material Palette and 1000 is black.
Firstly, we do a modification of white and black condition lines to correspond to 0 and 1000 intensity value of any color.
If Name = "white" Or intensity <= 0 Then matColor = RGB(255, 255, 255): Exit Function
If Name = "black" Or intensity >= 1000 Then matColor = RGB(0, 0, 0): Exit Function
Then we divide color assignment into two parts – colors with intensity assigned by Material Design Palette and colors with intensity not equal to values 0, 50, 100, 200, 300, …, 1000
If intensity Mod 100 = 0 Or intensity = 50 Then 'intensity equals to 50, 100, 200, ...
Select Case Name
Case “red”
Select Case intensity
Case 50
...
End Select
...
...
End Select
Else
End If
Now we need to create function which interpolates color values between values given by Material Design Palette. There is no possibility to interpolate directly between Long type color values. That values needs to be disassembled into red, green and blue components, then interpolated by factor (1-99) and combined back into Long type by RGB function. In function arguments bellow is lighter color inputs defined by Variant type, not Long. It is because of some VBA issue which causes error, when I try to give Long type number to Long type argument. This problem doesn’t occur on darker color argument.
Public Function interpolateColor(lighter As Variant, darker As Long, factor As Integer) As Long
Dim r1, g1, b1 As Integer
r1 = lighter Mod 256
g1 = (lighter \ 256) Mod 256
b1 = (lighter \ 256 \ 256) Mod 256
Dim r2, g2, b2 As Integer
r2 = darker Mod 256
g2 = (darker \ 256) Mod 256
b2 = (darker \ 256 \ 256) Mod 256
interpolateColor = RGB(Int(r1 - ((r1 - r2) * factor / 100)), _
Int(g1 - ((g1 - g2) * factor / 100)), _
Int(b1 - ((b1 - b2) * factor / 100)))
End Function
Now we need to find nearest greater and nearest lower value of intensity given by Material Color Palette. E.g. we need to get red color with intensity 234: greater intensity value is 300 and lower 200. Material Color Palette contains intensity with value 50, so we need to break first hundred into two parts of condition and then one part for values from 100 to 1000. Code below is part Else section of condition above.
Else
Dim lighter, darker As Long
Dim factor As Integer
If intensity < 50 Then ' 0-50
lighter = matColor(Name, 0)
darker = matColor(Name, 50)
factor = intensity * 2
ElseIf intensity < 100 Then ' 50-100
lighter = matColor(Name, 50)
darker = matColor(Name, 100)
factor = (intensity - 50) * 2
Else ' 100-1000
lighter = matColor(Name, Floor(intensity, 100)) ‘find closest lower intensity in Material Color Palette
darker = matColor(Name, Ceiling(intensity, 100)) ‘find closest greater intensity in Material Color Palette
factor = intensity - Floor(intensity, 100)
End If
End If
Because of VBA doesn’t know math functions Floor and Ceiling, we need to create them.
Public Function Ceiling(ByVal X As Double, Optional ByVal factor As Double = 1) As Double
Ceiling = (Int(X / factor) - (X / factor - Int(X / factor) > 0)) * factor
End Function
Public Function Floor(ByVal X As Double, Optional ByVal factor As Double = 1) As Double
Floor = Int(X / factor) * factor
End Function
Now we interpolate two colors which are present in Material Color Palette (lighter, darker) by factor and we get final interpolated color.
Else
Dim lighter, darker As Long
Dim factor As Integer
If intensity < 50 Then ' 0-50
...
ElseIf intensity < 100 Then ' 50-100
...
Else ' 100-1000
...
End If
colorValue = interpolateColor(lighter, darker, factor)
End If
That’s all, now we can call any shade of Material Color Palette e.g.
something = matColor(“lime”, 842)
and we get darker color than “Lime 800” but lighter than “Lime 900”.
For easy check that anything is OK, let’s create Function, which fill up Excel sheet with all Material Palette Colors gradients – intensity step by 20 because it is easier to see 50 rows of values on screen at once than 1000 rows. Step 1 is visible on this article heading. For that test case I use SelectionChange event of Worksheet.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Range("A:S").Interior.color = RGB(255, 255, 255)
Dim i As Integer
Dim j As Integer: j = 1
Dim cVal As Long
For i = 0 To 1000 Step 20
cVal = matColor("red", i)
Range("A" & j).Interior.color = cVal
cVal = matColor("Pink", i)
Range("B" & j).Interior.color = cVal
cVal = matColor("Purple", i)
Range("C" & j).Interior.color = cVal
cVal = matColor("DeepPurple", i)
Range("D" & j).Interior.color = cVal
cVal = matColor("Indigo", i)
Range("E" & j).Interior.color = cVal
cVal = matColor("blue", i)
Range("F" & j).Interior.color = cVal
cVal = matColor("Lightblue", i)
Range("G" & j).Interior.color = cVal
cVal = matColor("Cyan", i)
Range("H" & j).Interior.color = cVal
cVal = matColor("Teal", i)
Range("I" & j).Interior.color = cVal
cVal = matColor("Green", i)
Range("J" & j).Interior.color = cVal
cVal = matColor("LightGreen", i)
Range("K" & j).Interior.color = cVal
cVal = matColor("Lime", i)
Range("L" & j).Interior.color = cVal
cVal = matColor("Yellow", i)
Range("M" & j).Interior.color = cVal
cVal = matColor("Amber", i)
Range("N" & j).Interior.color = cVal
cVal = matColor("Orange", i)
Range("O" & j).Interior.color = cVal
cVal = matColor("deepOrange", i)
Range("P" & j).Interior.color = cVal
cVal = matColor("Brown", i)
Range("Q" & j).Interior.color = cVal
cVal = matColor("Grey", i)
Range("R" & j).Interior.color = cVal
cVal = matColor("blueGrey", i)
Range("S" & j).Interior.color = cVal
j = j + 1
Next i
End Sub
And voilà
#VBA #Excel #Material #Design #Color