Barvy ve VBA jsou tématem, které dokáže nadchnout, nudit i otrávit. Každopádně se mu vyhnout nemůžeme. Pojďme na to.
V úvodu vyzkoušíme, jak práci s barvami vidí Záznamník maker.
Upravenou proceduru ukazuje následující výpis.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Sub Makro1() 'Černá, Text1, velmi světlá 35 % 'barva pozadí With Selection.Interior .Pattern = xlSolid .PatternColorIndex = xlAutomatic .ThemeColor = xlThemeColorLight1 .TintAndShade = 0.349986266670736 .PatternTintAndShade = 0 End With 'barva písma With Selection.Font .ThemeColor = xlThemeColorLight1 .TintAndShade = 0.349986266670736 End With End Sub |
Už první pohled do kódu naznačuje, že práce s barvami může být pěkný opruz. Nejsem nejspíš tak dobrý angličtinář, abych rozlišil význam slov „tint“ a „shade“, navíc zkušenost říká, že s hodnotou této vlastnosti asi není něco v pořádku (už od oka by měla být 0,35 značící 35 %). A světe div se, zatímco po spuštění procedury se obarví pozadí, písmo ne. Zaokrouhlení hodnoty nepomůže. Chvíli jsem chybu studoval v diskusích na internetu a pak jsem daný způsob práce s barvami opustil.
Máme jinou možnost? Ano. V Excelu 2003 a starších existovala strohá paleta 256 barev a práce se odvíjela především od vlastnosti ColorIndex. Dnes se k ní vrátíme pouze na skok. Doba pokročila, paleta se rozrostla, a naším cílem bude vlastnost Color (datový typ Long). Obarvíme si tedy podle stávající palety (zde Excel 2007/2010) pár buněk a hodnotu Color pro ně zjistíme.
1 2 3 4 5 6 7 8 9 10 11 12 13 | Sub BarvyColor() Dim rngBunka As Range 'pro každou buňku ve výběru For Each rngBunka In Selection 'přiřazení hodnoty barvy do buňky rngBunka.Value = rngBunka.Interior.Color Next rngBunka End Sub |
A nyní se podívejte, jak zatočíme s kódem ze Záznamníku maker…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | Sub Makro1() 'Černá, Text1, velmi světlá 35 % 'Záznamník maker 'barva pozadí 'ok 'With Selection.Interior ' .Pattern = xlSolid ' .PatternColorIndex = xlAutomatic ' .ThemeColor = xlThemeColorLight1 ' .TintAndShade = 0.349986266670736 ' .PatternTintAndShade = 0 'End With 'Záznamník maker 'barva písma 'špatně 'With Selection.Font ' .ThemeColor = xlThemeColorLight1 ' .TintAndShade = 0.349986266670736 'End With 'nepomůže ani zaokrouhlení 'With Selection.Font ' .ThemeColor = xlThemeColorLight1 ' .TintAndShade = 0.35 'End With 'ok 'barva písma Selection.Interior.Color = 5855577 'barva pozadí Selection.Font.Color = 5855577 End Sub |
Sladění barev na listu
Ukážeme si, jak sjednotit barvu vyskytující se v buňce, tvaru a v datové řadě grafu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | Sub SladitBarvy() Dim intRed As Integer Dim intGreen As Integer Dim intBlue As Integer With ActiveSheet 'náhodné složky barvy RGB intRed = Int(256 * Rnd) intGreen = Int(256 * Rnd) intBlue = Int(256 * Rnd) 'obarvení tvaru .Shapes("Rectangle 1").Fill.ForeColor.RGB = RGB(intRed, intGreen, _ intBlue) 'obarvení řady grafu .ChartObjects("Graf 1").Chart.SeriesCollection(1).Format.Fill.ForeColor.RGB _ = RGB(intRed, intGreen, intBlue) 'převzetí barvy prvku buňkou '.Range("E2").Interior.Color = RGB(intRed, intGreen, intBlue) .Range("E2").Interior.Color = .Shapes("Rectangle 1").Fill.ForeColor.RGB End With End Sub |
V kódu se potkáváme kromě vlastnosti Color ještě s vlastností RGB a také s funkcí RGB. Obecně zkratka RGB představuje jeden z barevných modelů pro zobrazovací zařízení, v němž jsou barvy namíchány ze tří složek – R (Red, červená), G (Green, zelená) a B (Blue, modrá). Hodnoty každé z nich se pohybují mezi 0-255. Složky RGB pro pozadí buňky zjistíme po rozklepnutí tlačítka Barva výplně (ikonka plechovky s barvou) a vybráním položky Další barvy. Otevře se dialog Barvy a požadované informace se nachází pod záložkou Vlastní.
Sladění barev s formulářem a webem
Visual Basic používá své vlastní kódy s barvami.
a) &H0080C0FF&
rozdělení na části
&H00 80 C0 FF &
&H … hexadecimální číslo
&H00 … vlastní barva Visual Basicu
80 … B (blue, modrá složka barvy)
C0 … G (green, zelená složka barvy)
FF … R (red, červená složka barvy)
& … typový znak pro Long
b) &H80000012&
rozdělení na části
&H80 00 00 12 &
&H … hexadecimální číslo
&H80 … systémová barva
12 … pořadové číslo (odpovídá vbButtonText, tj. barva textu na tlačítku)
& … typový znak pro Long
Složky systémové barvy lze zjišťovat přes API funkci, nicméně jsem narazil na několik nesrovnalostí a tuto variantu vypustil z úvah.
Poznámka
Převod mezi číselnými soustavami zvládá na listu Excelu funkce HEX2DEC (DEC2HEX):
HEX2DEC(„FF“) = 255
HEX2DEC(„C0“) = 192
HEX2DEC(„80“) = 128
DEC2HEX(255) = FF
DEC2HEX(192) = C0
DEC2HEX(128) = 80
Na webu, v kódu HTML (CSS) se zpravidla setkáme s následující syntaxí:
#FFC080
rozdělení na části
# FF C0 80
# … (hexadecimální) číslo
FF … R (red, červená složka barvy)
C0 … G (green, zelená složka barvy)
80 … B (blue, modrá složka barvy)
I zde je možné ovšem vyjádřit barvu v systému RGB:
rgb(255,192,128)
Převod barev
V příloze jsou uvedeny funkce pro převod barev. Pokud je chcete používat na listu, přidejte do nich řádek Application.Volatile. I tak je nutné si uvědomit, že změna barvy buňky není pro Excel důvodem automaticky přepočítat list, tudíž si jej budete muset vynutit stiskem klávesy F9.
Sluší se uvést, že procedury až na výjimky nejsou mé vlastní, pouze jsem je částečně upravil k obrazu svému. Vesměs jsem vycházel ze stránek VB Helper.
Kromě zmíněného barevného modelu RGB existují další. Možná jste slyšeli o modelu HSL (Hue, Saturation, Luminance, tj. odstín , saturace a světlost). Dialog Barvy v Excelu jej sice zvládá, nicméně převod barev u něj je problematický a záleží na postupu. Za zmínku stojí ještě model CMYK (Cyan, Magenta, Yellow, blacK, tj. složky azurové, purpurové, žluté a černé barvy), uplatňující se při tisku. Převod opět není jednoduchý a pro tyto účely sahám vždy po tištěném vzorkovníku. V domácích podmínkách nečekejte, že barva bude stejná na monitoru i po tisku. Navíc hry vstupuje celá řada proměnných, které zde není možné rozebírat.
Pokud barvu vidíte a neznáte pouze její hodnotu, pak veškerou práci svěřte aplikaci. Mým vítězem je Kolorgenerator (freeware, přenositelný na flash fisku). Stačí barvu natáhnout kapátkem a hned víte RGB, HTML či VB kód.
Rozlišení barev
V plné rychlosti teď zařadíme zpátečku. Proč? Barevné hrátky v Excelu končí první černobílou tiskárnou (kopírkou). Řada barev tak splyne v jednolitou šedou. Proto je vhodné rozhodování se na základě barvy směřovat k jiným ukazatelům. Ostatně barvy nevnímáme všichni stejně, nemluvě o barvosleposti a dalších očních vadách. Vyhněte se pokud možno obarvování písma a dbejte, aby bylo vhodně kontrastní vůči pozadí. Osobně zpravidla volím pouze černou nebo bílou barvu textu, v případě detailnějšího stylování buněk odstín šedé. V grafech doporučuji vybírat i jiný typ čáry (čárkovaná, čerchovaná) a tvar značky datového bodu (trojúhelník, kolečko, čtverec).
Jak to dopadne s barvami po převodu do odstínů šedi, a jak na kontrastní písmo, si předvedeme na původní paletě Excelu 2003.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | Sub PrevestBarvyDoSede() Dim i As Integer Dim intRed As Integer Dim intGreen As Integer Dim intBlue As Integer Dim intY As Integer Dim intZ As Integer Dim y As Double Dim lngBarva As Long With ActiveSheet For i = 1 To 56 '************* 'první sloupec '************* 'barva pozadí, vlastnost ColorIndex (Excel 2003) .Cells(i, 1).Interior.ColorIndex = i 'hodnota .Cells(i, 1) = i 'převzetí barvy jako vlastnost Color lngBarva = .Cells(i, 1).Interior.Color 'rozklad barvy na složky červené, zelené a modré intRed = lngBarva And 255 intGreen = lngBarva \ 256 And 255 intBlue = lngBarva \ 65536 And 255 'jaká barva fontu na barevné pozadí intZ = (((0.3 * intRed) + (0.59 * intGreen) + (0.11 * intBlue)) < _ 150) * -255 'barva písma, vlastnost Color, funkce RGB .Cells(i, 1).Font.Color = RGB(intZ, intZ, intZ) '************* 'druhý sloupec '************* 'ekvivalentní odstín šedé 'intY = (intRed * 0.3 + intGreen * 0.59 + intBlue * 0.11) 'intY = (intRed * 0.2126 + intGreen * 0.7152 + intBlue * 0.0722) 'ITU-R Recommendation BT.601 intY = (intRed * 0.299 + intGreen * 0.587 + intBlue * 0.114) 'barva pozadí, vlastnost Color, funkce RGB .Cells(i, 2).Interior.Color = RGB(intY, intY, intY) 'hodnota .Cells(i, 2) = intY 'jaká barva fontu na barevné pozadí intZ = (((0.3 * intRed) + (0.59 * intGreen) + (0.11 * intBlue)) < _ 150) * -255 'barva písma, vlastnost Color, funkce RGB .Cells(i, 2).Font.Color = RGB(intZ, intZ, intZ) Next i End With End Sub |
Příloha
barvy_vba.zip