czwartek, 29 maja 2014

Sprawdzenie warunku zapisanego w zmiennej tekstowej

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

ś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:

01Sub 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    
20End 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.

01Sub 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    
27End 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:

01Sub 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    
22End 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:
  • 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.
Użycie WMI w kodzie VBA wymagać będzie utworzenia referencji do obiektu:
1Dim objWMI As Object
2Set objWMI = GetObject( _
3"winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
lub
1Set 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\\'")
     
Dodatkowe przykłady zastosowań bez problemu można znaleźć w sieci choć w szczególności polecam ten link ze strony Microsoft MSDN.  Szerszy opis WMI znajduje się również na stronie Microsoft MSDN.

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:
  • 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.