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

czwartek, 8 października 2015

Wstrzymanie wykonania kodu na dokładnie jedną sekundę

Niniejszy post jak wiele innych został zainspirowany zapytaniem na jednym z międzynarodowych forów. W dużym skrócie pytanie brzmiało- 'jak wstrzymać dalsze wykonywanie kodu na dokładnie jedną sekundę?' Pierwsza odpowiedź jaka została podana wyglądała następująco:
01Dim StartTime As Date
02Dim EndTime As Date
03 
04StartTime = Now
05'... jakiś kod
06 
07Debug.Print "S:" & Timer,   'dodane w celu przetestowania czasu
08     
09    EndTime = StartTime + TimeValue("00:00:01")
10    Application.Wait EndTime
11     
12Debug.Print "E:" & Timer    'dodane w celu przetestowania czasu
13 
14'... jakiś kod
Wadą powyższego rozwiązania jest wykorzystanie instrukcji TimeValue i Application.Wait. Precyzja obu z nich to ledwie sekunda. Jeżeli więc uruchomimy powyższe rozwiązanie np. o godzinie 12:35:45,65 (65 setnych sekundy) to kod będzie oczekiwał niecałą sekundę i dalsza akcja zostanie uruchomiona o 12:35:46,00, lub kilka setnych sekundy później. (Zarówno w powyższym jak i poniższym przykładzie dodane zostały instrukcje Debug.Print, których celem jest prześledzenie rzeczywistego czasu oczekiwania). Jeżeli więc zależy nam na dokładnie, lub prawie dokładnie jednej sekundzie oczekiwania musimy sięgnąć po rozwiązanie wykorzystujące instrukcję Timer:
01Dim Start As Single
02    Start = Timer
03 
04'... jakiś kod
05Debug.Print "S:" & Timer,   'dodane w celu przetestowania czasu
06    Do While Start + 1 > Timer
07       DoEvents
08    Loop
09Debug.Print "E:" & Timer    'dodane w celu przetestowania czasu
10'... jakiś kod
Chciałbym dodać jednak pewne istotne ostrzeżenie- powyższe rozwiązanie nie zadziała w momencie gdy nastąpi przekroczenie północy. Jeżeli istnieje możliwość należy dodać dodatkowe warunki do proponowanego rozwiązania.