Barvy ve VBA

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.

Práce s barvou - Záznamník maker

Práce s barvou – Záznamník maker

Upravenou proceduru ukazuje následující výpis.

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.

Color - standardní paleta barev (Excel 2010)

Color – standardní paleta barev (Excel 2010)

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…

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.

Sladění barev - buňka

Sladění barev – buňka

Sladění barev - tvar

Sladění barev – tvar

Sladění barev - datová řada v grafu

Sladění barev – datová řada v grafu

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.

Barvy na formuláři

Barvy na formuláři

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.

Kolorgenerator

Kolorgenerator

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.

Převod do odstínu šedé a kontrastní písmo

Převod do odstínu šedé a kontrastní písmo

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