Strona 1 z 1

Wypełnienie komórki kolorem na podstawie parametrów RGB.

: czw lis 26, 2015 11:39 am
autor: Julius_PL
Witam,
potrzebuję wypełnić kolorem komórki np w kolumnie D na podstawie danych RGB z kolumn A, B, C.
Przeszukałem, googlowałem i nie znalazłem.
Jest kilka przykładów gdzie zwracana jest wartość rgb, albo kolorowanie przy użyciu stylów, ale mnie chodzi o konkretny kolor RGB, pewnie przy użyciu makra.

Będę wdzięczny za ew. pomoc czy wskazówki.

Re: Wypełnienie komórki kolorem na podstawie parametrów RGB.

: czw lis 26, 2015 7:42 pm
autor: Julius_PL
Witam ponownie.

Zamiast szukać na szybko napisałem jak poniżej.
Na razie zaspokaja to moje potrzeby.
Może komuś się przyda.

Kod: Zaznacz cały

Sub BackColorRGB

  oDocument=ThisComponent                                     'wyróżnienie aktywnego dok. (=>Selection)
  oSheet=oDocument.Sheets.getByName("Arkusz1")     'wyróżnienie arkusza nr1
  
  for i=1 to 100                                                          ' dla 100 wierszy
	oCell=oSheet.getCellByPosition(3,i)                         
	oCell.CellBackColor = RGB(oSheet.getCellByPosition(0,i).getValue(), oSheet.getCellByPosition(1,i).getValue(),oSheet.getCellByPosition(2,i).getValue())   
  next i
  
End Sub
Pozdrawiam.

Re: Wypełnienie komórki kolorem na podstawie parametrów RGB.

: czw sty 21, 2016 4:34 pm
autor: qdq
Dzięki. Przyda się.

Można użyć jako bogatszą alternatywę dla formatowania warunkowego.

Re: Wypełnienie komórki kolorem na podstawie parametrów RGB.

: czw mar 03, 2016 4:51 pm
autor: qdq
Rozbudowałem powyższe makro, tak, żeby kolorowało komórki zaznaczonego zakresu od czerwonego do zielonego w odniesieniu do średniej, minimum i maksimum z danej kolumny. Przydatne, żeby szybko ocenić trendy bez rysowania wykresów.

Niestety makro wykonuje się bardzo powoli. Czy ktoś z większym doświadczeniem miałby ochotę rzucić okiem i dać kilka wskazówek jak je zoptymalizować?

Kod: Zaznacz cały

Sub RGB_kolumny

  oRange=ThisComponent.getCurrentSelection()

for i = 0 to oRange.getColumns.getCount - 1

    ' zliczanie średniej, maxa i mina
    min=0
    max=0
    suma=0
    sred=0
    licz=0
    for j = 0 to oRange.getRows.getCount - 1
        oCell=oRange.getCellByPosition(i,j)
        suma = suma + oCell.value
        If max < oCell.value Then  max = oCell.value
        If min > oCell.value Then  min = oCell.value
        if oCell.string <> "" then licz = licz + 1
    next j
    sred = suma/licz 
    for j = 0 to oRange.getRows.getCount - 1

oCell=oRange.getCellByPosition(i,j)
        war = oCell.value
        r=255
        b=255
        g=255

        if sred = 0 then sred = 0.001
        if min = 0 then min = -0.001
        if max = 0 then max = 0.001

        if war <= sred then g = g - 200 * (war-sred)/(min-sred)
        if war <= sred then b = b - 255 * (war-sred)/(min-sred)
        if war > sred then r = r - 255 * (war-sred)/(max-sred)
        if war > sred then b = b - 200 * (war-sred)/(max-sred)

         if r > 255 then r = 255
         if r < 0 then r = 0
         if g > 255 then g = 255
         if g < 0 then g = 0
         if b > 255 then b = 255
         if b < 0 then b = 0

        oCell.CellBackColor = RGB(r,g,b)
        if oCell.value = 0 then oCell.CellBackColor = RGB(230,230,230)
        if oCell.string = "" then oCell.CellBackColor = RGB(230,230,230)
        if oCell.value = min then oCell.CellBackColor = RGB(250,0,0)
        if oCell.value = max then oCell.CellBackColor = RGB(0,250,250)
    next j
  next i
end sub 

Re: Wypełnienie komórki kolorem na podstawie parametrów RGB.

: czw mar 03, 2016 5:08 pm
autor: Jan_J
Wszystkie operacje powtarzasz wewnątrz podwójnej pętli. Na dodatek (chyba) źle, bo jeżeli pętla wylicza średnią, to zanim nie skończy, nie nie znasz ostatecznego wyniku. W takim razie nie powinno się go używać w tej samej pętli do obliczenia koloru. Chyba że chodzi właśnie o kolorowanie według naszej przyrastającej wiedzy o średniej; bywają takie zadania.

Optimum imho jest takie:

[*]pierwszy blok liczy statystyki z danych: min, max, średnią. Możesz to robić gotowymi funkcjami albo własną pętlą. Funkcjami będzie szybciej. W pseudokodzie
min = max = srednia = wartość pierwszej komórki
w pętli po komórkach
w = wartość bieżącej komórki # ważne żeby nie pobierać danej wiele razy; to trwa
if w < min: min = w else if w > max: max = w endif; srednia = srednia + w
koniec pętli (podwójnej)
srednia = srednia / liczba komórek w obszarze
modyfikacja min i maks, tak by nie dzielić przez 0 w przypadku, kiedy wszystkie wartości są jednakowe

[*]drugi blok przygotowuje tablicę kolorów o odpowiedniej długości
alokacja tablicy kolory o długości nk
dla każdego i od 0 do nk-1: kolory[nk] = rgb(coś tutaj, żeby umieć obliczyć wartość koloru na podstawie numeru)
w innych miejscach nie używamy funkcji rgb, tylko tablicy wynikowej

[*]w bloku trzecim przechodzisz jeszcze raz po obszarze i przypisujesz każdej komórce kolor
wynikający z jej wartości. W pseudokodzie:
w pętli po wszystkich komórkach (podwójnej)
w = wartość komórki
k = numer pozycyjny wartości koloru na podstawie nk i położenia w względem min, maks, średnia
(najlepiej prostą proporcją, można wyszukiwaniem binarnym, if-ami jest najwolniej)
pod kolor komórki podłóż kolory[k]
koniec pętli

OK, zdaje sę że chcesz to robić osobno w wierszach, więc część zastrzeżeń jest nieważna.
Ale unikaj i tak: wielokrotnego odwoływania się do właściwości komórki; obliczania wewnątrz pętli rzeczy, które za każdym razem wychodzą takie same.

Re: Wypełnienie komórki kolorem na podstawie parametrów RGB.

: czw mar 03, 2016 6:23 pm
autor: belstar
Możesz wyeliminować ciągłe powtarzanie pobierania danych, przez pobranie całego bloku za jednym zamachem (tablica - getDataArray()) i pętle wykonać na danych w pamięci, to samo dotyczy się kolorów, jakaś deklaracja tablicy.
I jeszcze by się zdało jakąś obsługę błędów zaimplementować, bo jak zaznaczę większy zakres jak potrzeba to występuje wyjątek.