środa, 29 maja 2013

Wybierz swoje ulubione forum

Przed kolejnym dłuższym weekendem bardzo luźny temat dot. samo-edukacji w zakresie VBA.

Od czasu do czasu uczestnicy szkoleń pytają o najlepszą stronę www dot. vba, o miejsce w sieci gdzie znajdą szereg ciekawych rozwiązań, przykłady, itp. No cóż, oczywiście najlepszą odpowiedzią zazwyczaj bywa Google.Com, inną odpowiedzią bywa strona MSDN Microsoftu, ale w praktyce, gdy rzeczywiście na praktyce chcemy oprzeć swoją edukację to na myśl przychodzi mi tylko jedna strona- StackOverflow.Com

Kilka więc słów o StackOverflow. Otóż jest to strona z serii Question+Answer gdzie można zadawać pytania dot. tematów związanych z programowaniem. VBA nie zajmuje tam najwyższej pozycji lecz jednocześnie jest obszarem z mocnym wsparciem. Mogę zapewnić, że poziom odpowiedzi jest na prawdę wysoki. A całość działa bardzo prosto:

-każdy może zadać pytanie i każdy może odpowiedzieć na pytanie, niekoniecznie więc od razu musimy uczyć się przez pytania, możemy przez udział w odpowiedziach i pomaganiu innym,

-jeżeli się pomylimy, zostaniemy upomnienie, komentarz może nas skarcić, możemy otrzymać punkty ujemne, ale jednocześnie mamy możliwość skorygowania swojego błędu przez reedycję odpowiedzi,

-pozytywne odpowiedzi i ciekawe pytania są nagradzane.

Jeżeli szukamy rzeczywistej pomocy z pewnością ją tam znajdziemy o ile spełnimy proste założenia zadając pytanie:

-musimy wykazać, że próbowaliśmy rozwiązać problem- pytania w stylu 'jak coś zrobić?' nie są mile widziane i wręcz odrzucane. Ale jeżeli zapytamy 'gdzie jest błąd w moim kodzie?' prezentując ten kod wraz z prostym opisem to na 99% uzyskamy pomoc.

Na zapleczu StackOverflow siedzi rzesza pasjonatów porozrzucanych po całym świecie. W obszarze VBA grapa ta to ludzie z Indii, Australii, Stanów Zjednoczonych, Wielkiej Brytanii, a także z Polski. To zaś gwarantuje, że niezależnie od pory dnia znajdzie się ktoś chętny do udzielenia pomocy.

Nawiązując do tematu niniejszego postu- wybierz swoje ulubione forum, śledź pytania i odpowiedzi dot. tematów, które Cię interesują, próbuj rozwiązywać problemy innych, sprawdzaj rozwiązania prezentowane, a gdy poczujesz się dostatecznie dobrym programistą zacznij udzielać rad tym, którzy pytają. To po prostu pomaga w rozwijaniu umiejętności. Bo praktyka czyni mistrza... 

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, 24 maja 2013

Ukryte elementy systemu IntelliSense

W czasie szkoleń staram się podkreślać znaczenie i uczyć korzystania  w pełni z systemu IntelliSense. Ta prosta funkcjonalność edytora IDE bardzo wyraźnie potrafi przyspieszyć edycję kodu VBA, wspomóc proces debugowania, itp.

Zasadniczo jednak IntelliSense jest pierwszym etapem w szukaniu pomocy i rozwiązań na etapie wykonywania danej operacji. Ot np. nie zawsze pamiętam jaka jest pełna składnia danej funkcji, czy dana metoda czy właściwość jest dostępna w danym kontekście czy może w sposób okrężny z wykorzystaniem pośredniej referencji do innego obiektu.

Okazuje się jednak, że szereg metod i właściwości (a czasem obiektów) pozostaje ukrytych z poziomu systemu IntelliSense, a przez to kodowanie staje się lekko utrudnione. Zanim ujawnię jak pominąć tą niedogodność jedno warto ustalić- to, że coś jest ukryte zapewne nie jest przypadkiem. Nie chcę teraz rozstrzygać przyczyn schowania wybranych opcji VBA przed programistą. Warto jednak przyjąć dwa proste założenia:
a) zanim sięgnę po to narzędzie sprawdzę poprawność jego działania (na liście ukrytych właściwości znajdziemy np. obiekt FileSearch, który przez błąd twórców Office przestał być dostępny od wersji 2007)
b) nawet jeżeli funkcjonalność działa teraz niekoniecznie będzie działać w nowszej wersji pakietu Office.

Pomimo powyższych obaw uważam, że warto przeczytać pozostałą część niniejszego posta. Podejdźmy do sprawy przez pryzmat 2 problemów:

Problem A- jak wyeksportować i zapisać kształt lub inny obiekt (np. tabelę) z prezentacji PowerPoint jako plik typu JPG.
Problem B- jak sprawnie przeprowadzić edycję kodu w pracy z obiektami formularza ActiveX znajdującymi się w arkuszu.

Zanim zaczniemy szukać rozwiązań w sieci skorzystajmy z systemu IntelliSense. Wpisujemy kolejno dla naszych problemów przykładowy kod:
Problem A:
ActivePresentation.Slides(1).Shapes(3).   i tu pomoc systemu IS kończy się, trudno odnaleźć właściwą metodę
Problem B- w celu weryfikacji ilości formantów danego typu:
Arkusz1.  i tu pomoc IS kończy się, jedyny kierunek to wykorzystać kolekcję OLEObjects, ale co dalej...

Czas więc na rozwiązanie...W środowisku edytora VBA musimy

1. wywołać przeglądarkę obiektów Object Browser, w tym celu wybieramy F2 na klawiaturze
2. klikamy prawym klawiszem myszy w obszarze Object Browser
3. zaznaczamy pozycję Show Hidden Members

a teraz cieszymy się z dodatkowych funkcjonalności, metod i właściwości, które odkrywa przed nami IntelliSense. Wracamy szybko do naszych problemów i...

Problem A, okazuje się, że istnieje metoda .Export dla kształtów, która w łatwy sposób umożliwia nam utworzenie następującego kodu:

ActivePresentation.Slides(1).Shapes(3).Export "alfa.jpg",ppShapeFormatJPG

Problem B, okazuje się, że istnieją ukryte kolekcje poszczególnych typów obiektów ActiveX formularza, co pozwala nam na łatwą edycję przykładowego kodu:

Debug.Print Arkusz1.CheckBoxes.Count
Debug.Print Arkusz1.Buttons.Count

Na koniec dwa oczywiste spostrzeżenia:

1. wszystkie ukryte metody, właściwości i obiekty są lekko wyszarzone,  łatwo więc odnaleźć te z nich, które standardowo są niedostępne i na które należy uważać,
2. łatwo dostrzec jak wiele potencjalnych możliwości zostało ukryte przed programistami. Warto więc eksperymentować, testować i korzystać z tych opcji.

piątek, 17 maja 2013

Blokada własnej funkcji po stronie Excela

Pytanie z jednego z forum wydało mi się na tyle ciekawe, że postanowiłem przedstawić swoją odpowiedź także i w tym miejscu.

Pytanie owo brzmiało: czy da się stworzyć funkcję własną użytkownika tak, aby była dostępna po stronie środowiska VBA/IDE (możliwość wywoływania z okna Immediate lub innych procedur i funkcji) i aby nie była dostępna po stronie komórek w arkuszu. Ponieważ nie da się wykluczyć dostępności funkcji po stronie Excela możemy jedynie zwrócić inny jej wynik jeżeli wywołana zostanie właśnie w dowolnej komórce arkusza. Do tego zmierzać będzie więc rozwiązanie.

Pierwsza myśl to zastosowanie słowa kluczowego Private przed deklaracją funkcji. Otóż słowo to sprawia, że funkcja nie jest wyświetlana w podpowiedzi natomiast nie sprawia, że funkcja nie jest dostępna. Innymi słowy- jeżeli ktoś zna nazwę naszej funkcji może z niej skorzystać w dowolnej komórce Excela.

Rozwiązanie, które zaproponuję opiera się o sprawdzenie skąd pochodzi wywołanie funkcji (Application.Caller). Jeżeli wynik zwraca wartość Range to znaczy to, że funkcja wywołana jest z aplikacji Excel. Rozwiązanie to nie jest jednak wystarczające. Okazuje się, że jeżeli nasza funkcja jest wykorzystywana w obliczeniach pośrednich innej funkcji wywołanej z Excela to również otrzymamy informację jakoby wywołanie pochodziło z komórkek Excela. Dlatego też niezbędna jest dodatkowa weryfikacja, czy w wywołaniu użyto nazwy naszej funkcji.

Aby nie przedłużać teorii przedstawię kod, który powinien wyjaśnić wszystkie wątpliwości:

piątek, 10 maja 2013

Zapomniany parametr właściwości Address

Nawiązując do ostatnio opublikowanego tematu dot. zapomnianego parametru metody Select tym razem krótko o zapomnianych parametrach właściwości Address obiektu Range (zakresu komórek).
Myślę, że każdy z programistów używa właściwości Range.Address w celu kontroli czy też porównania określonych zakresów. Nie każdy jednak wykorzystuje dodatkowe parametry jakie ta właściwość posiada.

Korzystając z pomocy VBA przytoczę ogólną składnię tej właściwości:

A wynik działania poszczególnych parametrów- w postaci komentarzy wewnątrz kodu- prezentuje poniższe przykładowe makro. I myślę, że poniższy kod będzie wystarczającym wyjaśnieniem dot. wykorzystania pełnych możliwości właściwości Range.Address.

poniedziałek, 6 maja 2013

Ścieżka do grafiki osadzonej w MS Word

Poniższy kod ma swoje źródło w pytaniu na jednym z globalnych forów. Chodziło w nim mniej więcej o uzyskanie ścieżki do pliku źródłowego dla zaznaczonego obrazu umieszczonego w dokumencie aplikacji MS Word.

W sumie rozwiązanie jest proste nie mniej w MS Word mamy do czynienia z dwoma typami obiektów rysunkowych należącymi albo do kolekcji Shapes albo do kolekcji InlineShapes.Poniższy kod dzięki prostej technice obsługi błędów sprawdza oba warianty. Jeżeli obiekt nie należy do pierwszej z kolekcji to sprawdzona zostaje druga. Ostatecznie uzyskamy oczekiwany wynik, a w sytuacji gdy nie został zaznaczony obiekt typu rysunkowego zwrócone zostanie puste okno MsgBox.