Wyobraźmy sobie sytuację, w której kryteria i warunki zostały określone w postaci zmiennych tekstowych co obrazuje poniższy przykład:
Dim Warunek As String
Warunek = "1=1"
lub też
Warunek = "1+5=6"
albo
Warunek = "A=A"
Czy istnieje możliwość aby sprawdzić prawdziwość powyższych warunków w kodzie VBA? Otóż i tak i nie. W zakresie warunków oparty o liczby możemy sięgnąć po funkcję Evaluate i zweryfikować prawdziwość powyższych przykładów:
Warunek = "1=1"
Debug.Print Evaluate(Warunek) >> True
Warunek = "1+5=6"
Debug.Print Evaluate(Warunek) >> True
Warunek = "1+5=7"
Debug.Print Evaluate(Warunek) >> False
Problemem jest jednak poniższy zapis dot. zmiennych tekstowych, który zwróci błąd:
Warunek = "A=A"
Debug.Print Evaluate(Warunek) >> Error 2029
Metoda Evaluate zadziała prawidłowo dla poniższego zapisu warunku opartego o parametry tekstowe, a więc wartości ujęte w dodatkowe wewnętrzne cudzysłowy:
Warunek = """A""=""A"""
Debug.Print Evaluate(Warunek) >>True
Warunek = """A""=""a"""
Debug.Print Evaluate(Warunek) >> True
Warunek = """A""=""Z"""
Debug.Print Evaluate(Warunek) >> False
czwartek, 29 maja 2014
środa, 21 maja 2014
Pobieranie informacji dot. systemu operacyjnego i parametrów komputera- 2/2
Zgodnie z obietnicą zaprezentuję dwa przykłady wykorzystania WMI z poziomu kodu VBA.
Przykład 1. Pobranie informacji dot. parametrów procesora:
Warto zwrócić uwagę, że w powyższym przykładzie wystarczy podmienić zapytanie SQL aby uzyskać informacje dot. innych parametrów naszego systemu lub komputera.
Przykład 2. Pobranie informacji o otwartych procesach i zamknięcie wszystkich dot. aplikacji MS Word.
Warto pamiętać, że metoda Terminate zamyka aplikację bez dodatkowych pytań o zapisanie dokumentów. Oczywiście powyższe zadanie można wykonać szybciej odpowiednio konstruując zapytanie SQL co prezentuje poniższy kod VBA:
Przykład 1. Pobranie informacji dot. parametrów procesora:
01 | Sub WMI_Processor_Info() |
02 | |
03 | Dim objWMI As Object |
04 | Set objWMI = GetObject( "winmgmts:\\.\root\cimv2" ) |
05 | |
06 | Dim objQuery As Object |
07 | Set objQuery = objWMI.ExecQuery( "Select * from Win32_Processor" ) |
08 | |
09 | Dim objParam As Object |
10 | For Each objParam In objQuery |
11 | Debug.Print 1, objParam.Name |
12 | Debug.Print 2, objParam.Caption |
13 | Debug.Print 3, objParam.Version |
14 | Next |
15 |
16 | Set objParam = Nothing |
17 | Set objQuery = Nothing |
18 | Set objWMI = Nothing |
19 | |
20 | End Sub |
Warto zwrócić uwagę, że w powyższym przykładzie wystarczy podmienić zapytanie SQL aby uzyskać informacje dot. innych parametrów naszego systemu lub komputera.
Przykład 2. Pobranie informacji o otwartych procesach i zamknięcie wszystkich dot. aplikacji MS Word.
01 | Sub WMI_Processes_Info_Close() |
02 | |
03 | Dim objWMI As Object |
04 | Set objWMI = GetObject( "winmgmts:\\.\root\cimv2" ) |
05 | |
06 | Dim objQuery As Object |
07 | Set objQuery = objWMI.ExecQuery( "Select * from Win32_Process" ) |
08 | |
09 | Dim objProces As Object |
10 | For Each objProces In objQuery |
11 | |
12 | 'pobieramy informacje dot. procesów |
13 | Debug.Print 1, objProces.Name |
14 | Debug.Print 2, objProces.Caption |
15 | Debug.Print 3, objProces.ProcessID |
16 | |
17 | 'zamykamy te, które dot. aplikacji MS Word |
18 | If objProces.Name = "WINWORD.EXE" Then |
19 | objProces.Terminate |
20 | End If |
21 | Next |
22 |
23 | Set objProces = Nothing |
24 | Set objQuery = Nothing |
25 | Set objWMI = Nothing |
26 | |
27 | End Sub |
Warto pamiętać, że metoda Terminate zamyka aplikację bez dodatkowych pytań o zapisanie dokumentów. Oczywiście powyższe zadanie można wykonać szybciej odpowiednio konstruując zapytanie SQL co prezentuje poniższy kod VBA:
01 | Sub WMI_Processes_Close_MSWord() |
02 | |
03 | Dim objWMI As Object |
04 | Set objWMI = GetObject( "winmgmts:\\.\root\cimv2" ) |
05 | |
06 | Dim objQuery As Object |
07 | Set objQuery = objWMI.ExecQuery( _ |
08 | "Select * from Win32_Process Where Name='WINWORD.EXE'" ) |
09 | |
10 | Dim objProces As Object |
11 | For Each objProces In objQuery |
12 | |
13 | 'zamykamy wszystkie aplikacje zwrócone przez zapytanie SQL |
14 | objProces.Terminate |
15 | |
16 | Next |
17 |
18 | Set objProces = Nothing |
19 | Set objQuery = Nothing |
20 | Set objWMI = Nothing |
21 | |
22 | End Sub |
piątek, 16 maja 2014
Pobieranie informacji dot. systemu operacyjnego i parametrów komputera- 1/2
WMI (Windows Management Instrumentation) to zagadnienie, na które trafiłem całkiem przypadkiem na stronie www.stackoverflow.com. Po głębszej analizie możliwości implementacji WMI w kodzie VBA uznałem, że warto podzielić się tą wiedzą z czytelnikami.
Czym jest WMI? Zacytuję za Wikipedią: "WMI (ang. Windows Management Instrumentation) – zestaw protokołów i rozszerzeń systemu Windows umożliwiających zarządzanie i dostęp do zasobów komputera, takich jak adaptery sieciowe, aktualnie otwarte programy, lista procesów, odczyty z wbudowanych czujników temperatury, odczytów woltomierzy itp."
Co w praktyce możemy zrobić dzięki WMI? Oto kilka przykładowych możliwości:
lub
Kolejnym krokiem będzie stworzenie właściwego zapytania SQL skierowanego do odpowiedniej tabeli systemowej. Oto przykłady:
W kolejnym poście zaprezentuję dwa gotowe przykłady wykorzystania WMI listujące informacje o parametrach procesora oraz zamykające procesy spełniające określone kryteria.
Czym jest WMI? Zacytuję za Wikipedią: "WMI (ang. Windows Management Instrumentation) – zestaw protokołów i rozszerzeń systemu Windows umożliwiających zarządzanie i dostęp do zasobów komputera, takich jak adaptery sieciowe, aktualnie otwarte programy, lista procesów, odczyty z wbudowanych czujników temperatury, odczytów woltomierzy itp."
Co w praktyce możemy zrobić dzięki WMI? Oto kilka przykładowych możliwości:
- uzyskać informacje o systemie operacyjnym
- uzyskać listę procesów uruchomionych w systemie, w tym zamykać procesy
- uzyskać parametry wykorzystania dysków
- uzyskać informacje dot. procesora komputera
- uzyskać parametry pamięci RAM
- a nawet zamknąć system operacyjny.
1 | Dim objWMI As Object |
2 | Set objWMI = GetObject( _ |
3 | "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" ) |
1 | Set objWMI = GetObject( "winmgmts:\\.\root\cimv2" ) |
Kolejnym krokiem będzie stworzenie właściwego zapytania SQL skierowanego do odpowiedniej tabeli systemowej. Oto przykłady:
- parametry systemu operacyjnego: "Select * from Win32_OperatingSystem"
- parametry procesora: "Select * from Win32_Processor"
- parametry uruchomionych procesów: "Select * from Win32_Process"
(powyższy mechanizm pozwala wylistować ID procesu, na bazie którego możemy np. zamknąć określony proces z poziomu kodu VBA) - Listę plików określonego folderu: "Select * From Cim_DataFile " & _
"Where Drive = 'C:' And Path = '\\Instalki\\'")
W kolejnym poście zaprezentuję dwa gotowe przykłady wykorzystania WMI listujące informacje o parametrach procesora oraz zamykające procesy spełniające określone kryteria.
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:
stosować:
Dim myObject As ObjectType
Set myObject = New ObjectType
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.
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.
- nie używać ogólnej deklaracji As Object
- używać techniki wczesnego wiązania
- używać dłuższej techniki wczesnego wiązania, zamiast:
stosować:
Dim myObject As ObjectType
Set myObject = New ObjectType
- wykorzystywać instrukcję With...End With
- 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.
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.
Subskrybuj:
Posty (Atom)