Pokazywanie postów oznaczonych etykietą wydajność. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą wydajność. Pokaż wszystkie posty

piątek, 29 stycznia 2016

Konwersja typu Integer na Long


Ze względu na ograniczoną ilość czasu jaką obecnie dysponuję i jaką chciałbym poświęcać na publikację opisów zagadnień i problemów z zakresu VBA od czasu do czasu będę dodawał linki do ciekawych zagadnień z poświęconych programowaniu w VBA. Jako aktywny programista i trener bardzo często spotykam się z problemami, ciekawymi pomysłami oraz informacjami, które nie zawsze są powszechnie znane i wykorzystywane.

Zaczynam od informacji związanej z automatyczną konwersją zmiennych typu Integer (uważanych za przestarzały typ zmiennych) na zmienną typu Long. Co ważne, automatyczna konwersja działa tylko w systemach 32bit'owych. Dodatkowe informację znaleźć można pod tymi linkami:

MSDN: The Integer Data Types
StackOverflow: Why Use Integere Instead Of Long?

piątek, 23 października 2015

Właściwości .Value, .Value2 i .Text a szybkość działania

W niniejszym poście nie będę tłumaczył różnic pomiędzy wskazanymi właściwościami obiektu Range, a więc .Value, .Value2 czy .Text. Na dobrą sprawę nie będę nic tłumaczył tylko odeślę czytelników do bardzo ciekawego wpisu, w którym autor pokusił się o wykonanie testów dot. szybkości działania wskazanych właściwości. I co ciekawe, różnice w działaniu są bardzo znaczące więc tym bardziej każdy z programistów VBA, któremu zależny na efektywnym programowaniu powinien sięgać po właściwą technikę.
Co też ważne, artykuł przypomina o istotnych różnicach w działaniu wspomnianych właściwości.

Link do artykułu:
TEXT vs. VALUE vs. VALUE2 – Slow TEXT and how to avoid it...

piątek, 12 czerwca 2015

Wykorzystanie referencji R1C1 w praktyce (1/2)

Jednym z ważnych tematów omawianych w czasie prowadzonych kursów jest zagadnienie związane z wykorzystaniem referencji do zakresów określanych jako R1C1. Doświadczenie trenerskie pokazuje również, że zagadnienie to niekoniecznie wydaje się być proste do przyswojenia choć jednocześnie, po chwili zastanowienia i wykonaniu kilku ćwiczeń adresowanie komórek w stylu R1C1 staje się łatwiejsze. Spróbuję w tym wpisie krótko podsumować zasady dot. wykorzystania tej formy referencji.

Na początku chciałbym jednak przypomnieć- referencja R1C1 nie oznacza wyłącznie względnego stylu referencji. Z wykorzystaniem tego typu adresowania możemy także utworzyć referencję bezwzględną. I tak:


1. Jeżeli nasz adres R1C1 zawiera nawiasy kwadratowe to z pewnością będzie to adresowane względne. W tym wariancie dopuszczalne jest także wykorzystanie wartości ujemnych oraz pominięcie wartości liczbowych po literach R lub C.
2. Jeżeli w adresie R1C1 nie ma nawiasów kwadratowych oraz po literach R i C występują liczby to z pewnością mówimy o adresowaniu bezwzględnym.
3. I najważniejsze, warianty względnego i bezwzględnego adresowania mogą być ze sobą łączone w ramach jednego adresu.

Poniższe prosty przykłady pozwolą zobrazować szereg dostępnych wariantów adresowania R1C1. Załóżmy, że komórka Excela o adresie E5 zawierać będzie prostą formułę w stylu =A1, sprawdzimy następnie jaką postać ma adres R1C1 dla danej formuły:


Przykład 1: adres względny Wyjaśnienie: komórka A1 jest o 4 kolumny i wiersze odpowiednio w lewo i do góry względem komórki E5

Przykład 2: adres bezwzględny Wyjaśnienie: komórka B10 traktowana bezwzględnie, R10 to 10 wiersz (R = Row), a C2 to druga kolumna arkusza (C = Column)

Przykład 3: adres względny dla komórki będącej w tej samej kolumnie Wyjaśnienie: komórka E1 jest w tej samej kolumnie co E5, zwracany adres R1C1 wskazuje ten fakt przez brak wartości po C

Przykład 4: adres częściowo względny i bezwzględny Wyjaśnienie: kwadratowe nawiasy sugerują względność, kolumna jest więc o 3 w prawo od kolumny E i będzie to kolumna H. Brak nawiasów po R sugeruje adres bezwzględny dla wierszy i wskazuje na wiersz 10

W kolejnym wpisie przedstawię kilka praktycznych przykładów zastosowania formuły R1C1.

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).


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


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.


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.

poniedziałek, 5 maja 2014

Wydajność i efektywność 2/2- Mikrooptymalizacja

Wracam do tematów związanych z optymalizacją i tym razem skupię się na drobiazgach, a więc mikroelementach, które potrafią mieć znaczący wpływ na szybkość wykonywanego kodu.

1. Instrukcje warunkowe:
  • należy stosować wielostopniową instrukcję If...ElseIf...Else...End If w miejsce instrukcji Select Case
  • nie należy stosować instrukcji IIf() gdyż każdorazowo sprawdza warunki dla prawy i fałszu
  • używać krótką formę porównawczą If CzyPrawda Then... w miejsce If CzyPrawda=True Then...
  • w pracy z tekstem nie używać modułowej deklaracji Option Compare Text. Gdy porównujemy teksty używać instrukcji UCase(), LCase() lub parametrów vbCompareText gdzie dostępne
  • sprawdzając, czy zmienna przechowuje tekst używać konstrukcji If Len(tekst) =0 Then... zamiast If tekst ="" Then...
  • przed ustawieniem właściwości, gdy nie mamy pewności jej bieżącego stanu, warto sprawdzić jej bieżącą wartość. Odczyt wartości właściwości wykonywany jest szybciej niż zmiana właściwości.
2. Obiekty i zewnętrzne biblioteki:
  • nie używać ogólnej deklaracji As Object
  • używać techniki wczesnego wiązania
  • używać dłuższej techniki wczesnego wiązania, zamiast:
     Dim myObject As New ObjectType
        stosować:
  Dim myObject As ObjectType
  Set myObject = New ObjectType
  • wykorzystywać instrukcję With...End With
3. Inne zagadnienia:
  • co oczywiste lecz warte przypomnienia- zawsze stosujemy właściwy typ zmiennych, typ Variant nie powinien być wykorzystywany
  • używać funkcji konwersji typów (CInt, CDbl, CSng, itp) przy przekazywaniu wartości różnych typów pomiędzy zmiennymi
  • operacje dzielenia dla licz całkowitych wykonywać z odwrotnym operatorem dzielenia A\B zamiast A/B
  • w pracy ze zmiennymi tekstowymi używać funkcji tekstowych: Mid$, Left$, Right$
  • wykonując szereg operacji na zakresie warto przenieść zakres do tablicy i dalsze analizy wykonywać na tablicy
  • w procesie pobierania i zwracania wartości pomiędzy komórkami arkusza i zmiennymi stosować zmienne typu Double dzięki czemu unikniemy procesu konwersji, formatowania, zaokrąglania, itp.
Na koniec przypomnę najważniejszą z technik, o której wspomniałem w poprzednim poście poświęconym zagadnieniom optymalizacji- nie zapominajmy o A w VBA...

Przy okazji zapraszam na prowadzone przez nas szkolenia z zakresu programowania w VBA, które organizujemy w Warszawie, Krakowie i Wrocławiu. W czasie naszych kursów VBA prezentujemy szereg technik związanych z efektywnym programowaniem.

poniedziałek, 28 kwietnia 2014

Wydajność i efektywność 1/2- Makrooptymalizacja

Zagadnienia dot. optymalizacji i efektywności programów w VBA podzielone zostaną na dwie części zgodnie z przyjętą gdzieniegdzie systematyką:
  1. makrooptymalizacja dot. zagadnień szerszych, dużych, właściwego doboru narzędzi, techniki, rozwiązania czy algorytmu,
  2. mikrooptymalizacja dot. szeregu drobnych detali w kodzie, które w całościowym ujęciu mają istotny wpływ na szybkość wykonywania procedury.
Muszę jednak od razu poczynić zastrzeżenia zanim przejdę do prezentacji krótkich opisów w/w technik. Optymalizacja jest tematem 'żywym', co jakiś czas zdarza się, że pojawiają się nowe sugestie, tak więc nie należy traktować niniejszych postów jako zamkniętą listę działań optymalizacyjnych. I drugie zastrzeżenie- niektóre z technik można uznać za sporne, a więc takie, które nie w każdym przypadku przekładają się na widoczną poprawę efektywności.

Na początek kilka zagadnień dot. makrooptymalizacji:

1. W aspekcie pracy z pętlami, tablicami i kolekcjami:
  • unikać zagnieżdżonych pętli, stosować techniki wyjścia z pętli (Exit For, Exit Do)
  • w procesach porównywania posortować porównywane kolekcje/tablice
  • w pracy z kolekcjami stosować pętle For Each...Next
  • w pracy z tablicami stosować pętle For i...Next
  • w pracy z tablicami dynamicznymi stosować płynną redefinicję wymiaru
2. W pracy z obiektami:
  • unikać aktywowania (.Activate) i zaznaczanie (.Select)
  • wyłączać odświeżanie ekranu (Application.ScreenUpdating = False)
  • wyłączać (gdy tylko jest to bezpieczne) standardowe okna potwierdzeń (Application.DisplayAllerts = False)
  • wyłączać przeliczanie formuł, szczególnie gdy kod VBA ingeruje w strukturę wartości i formuł w skoroszycie (Application.Calculation = xlManual)
3. Inne aspekty:
  • unikać przesadnego stosowania zmiennych publicznych
  • gdy możliwe i dopuszczalne zerować wartości zmiennych publicznych instrukcją End
  • nie tworzyć własnych funkcji jeżeli podobna funkcja istniej w zbiorze funkcji VBA lub WorksheetFunction
A na koniec chyba najważniejsza z technik optymalizacji- nie zapominać o A w VBA... innymi słowy, jeżeli można coś wykonać z wykorzystaniem dostępnych, gotowych narzędzi w aplikacji to zróbmy to w miejsce tworzenia nowego kodu VBA.

środa, 18 grudnia 2013

Narzędzia programisty VBA

Oczywiście, że podstawowym środowiskiem pracy programisty VBA pozostaje Integrated Developer Editor (IDE) dostarczany w pakiecie Office. Nie mniej istnieje kilka narzędzi pomocniczych, które można zintegrować ze środowiskiem lub jako osobne aplikacje mogą stać się niezastąpioną pomocą w codziennej pracy z VBA. Oto kilka przykładowych programów wartych polecenia i uwagi.

1. EZ-Tool 
 Link do strony dostawcy: www

Narzędzie instalowane jako dodatek środowiska IDE. Wspiera programistę w szeregu czynności: tworzenie procedur, zarządzanie komentarzami, obsługą błędów. Dostarcza schematy dla ADO. W moim odczuciu narzędzie w stylu 'must have'.

2. RibbonX Visual Designer 2010
Link do strony dostawcy: www

Narzędzie wspomagające tworzenie elementów wstążki- zakładek, przycisków i innych kontrolek.

3. Excel VBA Code Cleaner
Link do strony dostawcy: www

Jak sama nazwa wskazuje narzędzie oczyszczające kod ze zbędnych elementów. Narzędzie polecane w przypadku dużych projektów, projektów tworzonych w dłuższych okresach czasu, itp.



piątek, 27 września 2013

Sprawdzanie właściwości przed jej ustawieniem

Niniejszy temat został wywołany na forum StackOverflow.Com gdzie padło pytanie o sens niniejszego kodu (który tutaj został lekko zmodyfikowany dla celów prezentacyjnych):


Na pierwszy rzut oka w istocie- jaki jest sens sprawdzać czy dany wiersz jest ukryty skoro chcemy i tak ostatecznie odkryć wszystkie dziesięć tysięcy wierszy. Wystarczy przecież wykonać poniższą pętlę:


Otóż pierwszy zapis jest bardzo uzasadniony i ma swoją wyraźną przewagę nad pętlą drugą (choć efekt ostatecznie będzie na 100% identyczny). Porównawczo wygląda to następująco (dla identycznych parametrów środowiska, w którym wykonany został test dla każdego wariantu):

1. pętla pierwsza, wszystkie wiersze były uprzednio odkryte- czas wykonania- 0.2 sek
2. pętla druga, wszystkie wiersze były uprzednio odkryte- czas wykonania- 13.1 sek

3. pętla pierwsza, wszystkie wiersze były uprzednio ukryte- czas wykonania- 15.6 sek


Z czego wynikają różnice. Zasadniczo z prostego założenia, zgodnie z którym odczyt właściwości odbywa się szybciej niż jej ustawienie. Jeżeli istnieje uzasadnienie, że większość elementów (tu: wierszy) może nie wymagać ustawiania właściwości (tu: odkrywania) to warto uprzednio sprawdzić bieżący stan danej właściwości (tu: czy wiersz jest ukryty czy odkryty). Zasadę tę warto stosować do wszystkich właściwości o ile pracujemy na relatywnie dużej kolekcji.

poniedziałek, 27 maja 2013

Najprostszy i najlepszy pasek postępu

Wydaje mi się, że każdy programista pisząc swoją pierwszą dłuższą procedurę (dłuższą w zakresie ilości kodu, ale też szczególnie długiego czasu jej wykonywania), która to procedura ma trafić do innego użytkownika myśli o tym, aby dodać do aplikacji informację o postępie wykonania operacji. Koncepcja ta jest ze wszech miar słuszna, ale nie każde rozwiązanie jakie zastosujemy pozostaje właściwym. Osobiście jestem zwolennikim minimalizmu w tym zakresie zgodnie z którym zamiast wyskakujących okien opartych o formularze wykorzystajmy po prostu pasek stanu (Status Bar) naszej aplikacji, szczególnie, że metoda ta również może być efektywna.

Rozwiązanie uwzględnia dwie koncepcje. Wystarczy w poniższej linii

wybrać jeden z wariantów:

pasekTXT_A -który postęp będzie wyświetlał jako tekst "Wykonano: xx.0%"
pasekTXT_B -który postęp wykonania wyświetli jako układ symboli >|||||     <

Poniższy kod to przykład stworzony wyłącznie w celach prezentacyjnych. Adaptacja do własnych potrzeb wydaje się być jednak bardzo łatwa.

piątek, 8 marca 2013

Nie zapomnieć o A w VBA...

Swego czasu trafiłem na obszerny artykuł napisany przez specjalistę od VBA poświęcony roli 'A' w 'VBA'... Niestety nie zapisałem linku do owego artykułu, być może można go odnaleźć w sieci. Niemniej treść owego można by skrócić do kilku prostych zdań, z którymi bardzo się zgadzam.

Nie twórzmy makr wszędzie tam, gdzie istnieją proste rozwiązania dostępne po stronie samej aplikacji Excel (czy innej aplikacji Office). A jeżeli już musimy tworzyć makro, to w pierwszej kolejności wykorzystajmy funkcjonalność gotowych rozwiązań, które znamy z aplikacji Excela.

Jednym z najprostszych i najważniejszych przypadków owego A w VBA jest kwestia wykorzystania funkcji arkuszowych, do których mamy dostęp z pomocą kolekcji WorksheetFunction... i temu tematowi, kwestii wykorzystania instrukcji WorksheetFunction poświęcę wkrótce kilka osobnych wpisów.