czwartek, 10 lipca 2014

Pasek postępu w komórce Excela

Całkiem dużym zainteresowaniem cieszy się mój zeszłoroczny wpis dot. paska postępu wyświetlanego w pasku stanu (StatusBar) aplikacji Excel, którego treść można znaleźć pod tym linkiem. Pomyślałem więc, że dodam jeszcze jeden wpis prezentujący inny wariant paska postępu. Nadal będę trzymał się koncepcji aby pasek był rozwiązaniem minimalistycznym. Tym razem więc informacje o postępie umieścimy w...dowolnej komórce Excel. Oczekiwany efekt prezentuje poniższa grafika:



I tu należy uczynić ważne zastrzeżenie- rozwiązanie to nie będzie dostępne dla wszystkich wersji MS Excel gdyż oparte jest o zaawansowane techniki formatowania warunkowego, które rozbudowane zostało począwszy od wersji 2007.

Krok 1 (wariant ręczny).
Tworzymy komórkę z formatowaniem warunkowym, która będzie zawierać nasz pasek postępu. Proponowany wariant to: Menu >> Formatowanie warunkowe >> Pasek danych gdzie następnie wartości ustawiamy jako liczby i określamy ich minimalną i maksymalną wartość jako odpowiednio 0 i 1. Wskazane będzie również dodanie do naszej komórki obramowania.

Krok 1 (kod VBA)
Proponuję wariant dynamicznego tworzenia paska, a więc taki, gdzie nie definiujemy stałego miejsca jego lokalizacji, a zależnie od okoliczności wyświetlić go możemy w dowolnej komórce Excela (cały przykład obrazuje działanie dla aktywnej komórki). W tym celu będziemy potrzebowali kod VBA, który utworzy w komórce formatowanie warunkowe. Poniższy kod dostarcza niezbędny minimalny zestaw instrukcji VBA (komentarze wewnątrz kodu dodatkowo wyjaśniają poszczególne sekcje).

01Sub PasekPostępuFormatowanie(rngCell As Range)
02 
03    'tworzymy formatownie warunkowe
04    With rngCell
05        .FormatConditions.AddDatabar
06        With .FormatConditions(1)
07            'opcjonalnie false jeżeli nie chcemy
08            'wyświetlać liczb wewnątrz paska
09            .ShowValue = True
10            .SetFirstPriority
11            .MinPoint.Modify _
12                    newtype:=xlConditionValueNumber, _
13                    newvalue:=0
14            .MaxPoint.Modify _
15                    newtype:=xlConditionValueNumber, _
16                    newvalue:=1
17            .BarColor.Color = 13012579
18            .BarFillType = xlDataBarFillSolid
19        End With
20    
21        'tworzymy obramowanie- sekcja opcjonalna
22        With .Borders()
23            .LineStyle = xlContinuous
24            .ColorIndex = 0
25            .TintAndShade = 0
26            .Weight = xlThin
27        End With
28 
29        'tworzymy styl tekstu- o ile .ShowValue
30        'powyżej ustawiono na True
31        .Style = "Percent"
32        .HorizontalAlignment = xlCenter
33        .VerticalAlignment = xlCenter
34    End With
35End Sub

Krok 2
Nie pozostało nam nic innego jak wypróbować nasz kod w oparciu o testową procedurę.

01Sub Pasek_Postępu_Komórka_Excel()
02 
03    Dim iTest As Double, jTest As Long
04    
05    'tworzymy formatowanie warunkowe we wskazanej komórce
06    Dim rngProgress As Range
07    Set rngProgress = ActiveCell'lub obszar typu Range("A5")
08    PasekPostępuFormatowanie rngProgress
09    
10    'pętla testowa- prezentacyjna
11    For iTest = 0 To 1 Step 0.01
12        
13        'poniższa pojedyncza linia powinna być
14        'umieszczona wewnątrz Twojego kodu
15        'a zmienna iTest przekazywać % wykonania
16         rngProgress.Value = iTest
17        
18        'pętla spowalniająca do celów prezentacji
19        For jTest = 1 To 20000000
20        Next jTest
21        
22    Next iTest
23    
24End Sub

Krok 3. 
Myślę, że po wykonaniu zadania nasz pasek powinien zniknąć. Chyba najproście można to zrobić kopiując pustą komórkę (np. ostatnią komórkę w arkuszu) w miejsce naszego paska postępu. Poniższy kod można dodać po zakończeniu pętli, przed zakończeniem procedury.

1Cells(Rows.Count, Columns.Count).Copy rngProgress

Jeżeli ktoś miałby wątpliwość jak cała koncepcja działa proponuję skopiować do nowego modułu obie powyższe procedury. Następnie proszę uruchomić procedurę z kroku 2 i obserwować zachowania aktywnej komórki.