11 grudnia 2009
Wyświetlanie formuł w komentarzach -- dodatek xla
Dzisiaj uczestniczyłem w szkoleniu noszącym tytuł Techniki numeryczne w wycenie opcji finansowych organizowanym przez CEETA. W trakcie szkolenia zauważyłem, że prowadzący posługuje się makrem przypisanym do skrótu klawiszowego, które wyświetla w komentarzach tekst formuł wpisanych w komórkach. Dzięki temu rozwiązaniu można w łatwy sposób przedstawiać, wyróżniać formuły stosowane w arkuszu.
Pomysł ten spodobał mi się na tyle, że postanowiłem zaimplementować go w postaci dodatku xla.
- xlFormulaToComment.xla — dodatek xla
- xlFormulaToComment.bas — moduł z kodem dodatku
Słowa kluczowe: excel, makra, vba, addin
21 października 2009
DevCpp i instalacja biblioteki boost
Do instalacji biblioteki boost w środowisku DevCpp należy:
- Zainstalować środowisko programistyczne Bloodshed Dev-C++. Program można pobrać ze strony The Dev-C++ Resource Site.
- Pobrać kod źródłowy biblioteki boost ze strony Boost Downloads i rozpakować go do wybranego katalogu.
- Pobrać lub skompilować program bjam. Plik wykonywalny należy umieścić w katalogu, do którego rozpakowano źródła bibiloteki.
Przed przystąpieniem do kompilacji biblioteki należy upewnić się, że plik wykonywalny kompilatora g++.exe znajduje się na ścieżce wyszukiwania. Aby uzyskać odpowiedź na to pytanie można wprowadzić w oknie Command Prompt następujące polecenie.
g++ --version
Jeśli w wyniku tego polecenia zostanie wypisany komunikat poniższej treści lub podobny, to wszystko jest na dobrej drodze.
g++ (GCC) 3.4.2 (mingw-special) Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Jeżeli jednak otrzymamy komunikat:
Nazwa 'g++' nie jest rozpoznawana jako polecenie wewnętrzne lub zewnętrzne, program wykonywalny lub plik wsadowy.
a instalacja Dev-Cpp przebiegła bezbłędnie, to należy dodać do ścieżki wyszykiwania katalog, w którym został zainstalowany kompilator. Można zrobić to na dwa sposoby.
Pierwszy sposób polega na trwałej modyfikacji zmiennej środowiskowej PATH. Zmiany można dokonać wybierając po kolei: My Computer -> Properties -> Advanced -> Environment Variables -> System Variables -> Edit, a następnie dodać po średniku katalogu, w którym znajdują się pliki wykonywalne Dev-Cpp. Kolejne kroki przedstawione są na obrazkach.
Drugi sposób to rozszerzenie zmiennej środowiskowej PATH na czas trwania okna poleceń (Command Prompt).
set PATH=%PATH%;C:\Dev-Cpp\bin
W powyższych przykładach przyjęte zostało założenie, że Dev-Cpp został zainstalowany w domyślnym katalogu.
Zawartość zmiennej środowiskowej PATH można sprawdzić wykonując polecenie:
path
lub:
echo %PATH%
Minimalna instalacja z domyślnymi parametrami wykonywana jest po wydanym poleceniu:
bjam --toolset=gcc install
Jeśli nie chcemy budować biblioteki w domyślnym katalogu i jednocześnie chcemy skompilować bibliotekę na wszystkie możliwe sposoby, to uzyskamy ten efekt wydając polecenie:
bjam --build-dir=C:\Boost-build ^
--toolset=gcc ^
--build-type=complete install
Więcej opcji kompilacji można uzyskać wydając polecenie:
bjam --helpSłowa kluczowe: cplusplus, boost
19 października 2009
Kopiowanie zakresu -- Excel VBA
Poniżej krótka procedura rozwiązująca odwieczny problem kopiowania zakresów w arkuszach Excela. Pierwszy argument procedury (CopiedRange) to, zgodnie z nazwą, kopiowany zakres, a drugi (RangeTo) to zakres docelowy. Zakres docelowy powinien być pojedyńczą komórką wskazującą lewy górny róg miejsca, w którym ma się znaleźć kopiowany zakres.
Sub CopyRange(CopiedRange As Range, RangeTo As Range)
Dim nColumns As Long
Dim nRows As Long
With CopiedRange
nColumns = .Columns.Count
nRows = .Rows.Count
End With
With RangeTo
Debug.Assert .Columns.Count * .Rows.Count = 1
Set RangeTo = Range(.Offset(0, 0), _
.Offset(nRows - 1, nColumns - 1))
End With
RangeTo = CopiedRange.Value
End SubSłowa kluczowe: excel, vba, makra
11 sierpnia 2009
Rekurencyjne wypisywanie zawartości katalogu -- SAS 4GL
Na tej stronie znalazłem kod makra w języku 4GL służącego do wypisywania rekurencyjnie zawartości katalogów. Zmodyfikowałem to makro tak, aby lepiej odpowiadało moim potrzebom. Dodałem możliwość ograniczania głębokości rekurencji
%macro DirWalk(DIRNAME, MAXDEPTH=-1);
%local I FILEREF RC DIRID FILESCNT LEVEL LEN;
%let DIRNAME = %sysfunc(translate(&DIRNAME, "/", "\"));
%let DIRNAME = %sysfunc(compress(&DIRNAME, '"'));
%let LEN = %sysfunc(length(&DIRNAME));
%let LAST = %sysfunc(substr(&DIRNAME, &LEN, 1));
%if "&LAST" = "/" %then
%let DIRNAME = %sysfunc(substr(&DIRNAME, 1, &LEN - 1));
%let LEVEL = %eval(&MAXDEPTH);
%if %sysfunc(symexist(DEPTH)) = 0 %then
%let DEPTH = 1;
%let RC = %sysfunc(filename(FILEREF, "&DIRNAME"));
%let DIRID = %sysfunc(dopen(&FILEREF));
%if &DIRID > 0 %then %do;
* seems to be a directory, so walk it;
%let FILESCNT = %sysfunc(dnum(&DIRID));
%if &FILESCNT > 0 %then %do;
%do I = 1 %to &FILESCNT;
%let NAME =
%sysfunc(trim(&DIRNAME/%sysfunc(dread(&DIRID, \
&I))));
%put &DEPTH &LEVEL &I &NAME;
%if &LEVEL ne 0 %then %do;
%let DEPTH = %eval(&DEPTH + 1);
%dirWalk("&NAME", \
MAXDEPTH=%sysfunc(max(&LEVEL - 1, -1)));
%let DEPTH = %eval(&DEPTH - 1);
%end;
%end;
%end;
%let RC = %sysfunc(dclose(&DIRID));
%end;
%mend DirWalk;
Makro o można wywoływać na kilka sposobów:
%DirWalk("C:/katalog/", MAXDEPTH=0);
%DirWalk("C:/katalog/", MAXDEPTH=1);
%DirWalk("C:/katalog/", MAXDEPTH=-1);
%DirWalk("C:/katalog/");
Pierwsze wywołanie spowoduje wypisanie jedynie zawartości katalogu "C:/katalog/". Po drugim wywołaniu zobaczymy zawartość podanego katalogu oraz katalogów bezpośrednio w nim się znajdujących. Ostatnie dwa wywołania są równoważne i powodują wypisania zawartości podanego katalogu oraz wszystkich podkatalogów w nim znajdujących niezależnie od głębokości na której są położone w drzewie katalogów.
Samo wypisywanie zawartości katalogu jest mało przydatne. O wiele większą korzyść można odnieść z listy plików i katalogów zapisanych w tablicy. Służy temu kolejne makro (na uwagę zasługuje makro w nim zagnieżdżone):
%macro ListRecursive(DATASET, DIRNAME, MAXDEPTH=-1);
%let DIRNAME = &DIRNAME;
%let DATASET = &DATASET;
%macro DataDirWalk(DIRNAME, MAXDEPTH=-1);
%local I FILEREF RC DIRID FILESCNT LEVEL LEN;
%let DIRNAME = %sysfunc(translate(&DIRNAME, "/", "\"));
%let DIRNAME = %sysfunc(compress(&DIRNAME, '"'));
%let LEN = %sysfunc(length(&DIRNAME));
%let LAST = %sysfunc(substr(&DIRNAME, &LEN, 1));
%if "&LAST" = "/" %then
%let DIRNAME = %sysfunc(substr(&DIRNAME, 1, &LEN - 1));
%let LEVEL = %eval(&MAXDEPTH);
%if %sysfunc(symexist(DEPTH)) = 0 %then
%let DEPTH = 1;
%let RC = %sysfunc(filename(FILEREF, "&DIRNAME"));
%let DIRID = %sysfunc(dopen(&FILEREF));
%if &DIRID > 0 %then %do;
%let FILESCNT = %sysfunc(dnum(&DIRID));
%if &FILESCNT > 0 %then %do;
%do I = 1 %to &FILESCNT;
%let NAME = %sysfunc(dread(&DIRID, &I));
%let PATH = %sysfunc(trim(&DIRNAME/&NAME));
fileNum = &I;
fileName = "&NAME";
filePath = "&PATH";
parentDir = "&DIRNAME";
depth = &DEPTH;
output;
%if &LEVEL ne 0 %then %do;
%let DEPTH = %eval(&DEPTH + 1);
%DataDirWalk("&PATH", \
MAXDEPTH=%sysfunc(max(&LEVEL-1, -1)));
%let DEPTH = %eval(&DEPTH - 1);
%end;
%end;
%end;
%let RC = %sysfunc(dclose(&DIRID));
%end;
%mend DataDirWalk;
data &DATASET;
format fileName $32.;
format filePath $128.;
format parentDir $96.;
format depth best4.;
format fileNum best8.;
%DataDirWalk(&DIRNAME, MAXDEPTH=&MAXDEPTH);
run;
%mend;
- DirWalk.sas --- kod makra %DirWalk
- ListRecursive.sas --- kod makra %ListRecursive
Słowa kluczowe: sas, 4GL, makra
24 lipca 2009
Bloomberg API i płaszczyzna zmienności FX (VBA)
Z Bloomberg API po raz pierwszy zetknąłem się latem 2006 lub 2007 roku. Wtedy jeszcze nie wiedziałem, jak i gdzie mógłbym je zastosować. Przełom nastąpił w zeszłym roku spędziłem ponad tydzień ucząc się tego narzędzia i sprawdzając jego możliwości.
Korzystając z Bloomberg API należy pamiętać o przynajmniej dwóch faktach:
- zapytania obsługiwane są w sposób synchroniczny
- dane pobierane za pomocą Bloomberg API nie mogą opuszczać licencjonowanego stanowiska
- w liście referencji należy dodać bibliotekę Bloomberg Data Type Library
Jako przykład zastosowania Bloomberg API stworzyłem klasę FxVolGetter, która ma służyć do pobierania kwotowań zmienności FX:
Option Explicit
Option Base 0
Const IMP_VOL_TYPE = "DFLT_VOL_SURF_MID"
Const QUOTE_FORMAT_FIELD = "IMP_VOL_QUOTE_FORMAT"
Enum QUOTE_FORMAT
QUOTE_B
QUOTE_C
QUOTE_P
QUOTE_R
End Enum
Private blbObj As BLP_DATA_CTRLLib.BlpData
Private blbCookies As Integer
Private blbFields As String
Private blbOverFields As String
Private blbOverValues As Variant
Private Sub Class_Initialize()
Set blbObj = New BlpData
blbCookies = 1
blbFields = IMP_VOL_TYPE
blbOverFields = QUOTE_FORMAT_FIELD
blbOverValues = Array("B", "C", "P", "R")
End Sub
Public Function sendRequest(blbCode As String, _
Optional quoteType As QUOTE_FORMAT = QUOTE_B) As Variant
Dim tmp As Variant
'' send request to Bloomberg
Call blbObj.Subscribe(blbCode, _
blbCookies, _
blbFields, _
blbOverFields, _
blbOverValues(quoteType), _
tmp)
'' assign the results
sendRequest = tmp(0, 0)
End Function
... oraz przykład jej zastosowania:
Option Explicit
Option Base 0
Sub Test()
Dim volGetter As FxVolGetter
Dim ticker(2) As String
Dim vSurf As Variant
Dim reset As Variant
Dim i As Integer
Set volGetter = New FxVolGetter
ticker(0) = "EURUSD BGN Curncy"
ticker(1) = "XAUUSD BGN Curncy"
ticker(2) = "EURCHF BGN Curncy"
For i = 0 To UBound(ticker)
'' I need to reset the result container
'' before I write to it
vSurf = reset
vSurf = volGetter.sendRequest(ticker(i))
'' here you can play further with the
'' contents of the "res" variable
'' ...
Next i
End Sub
- FxVolGetter.cls -- moduł klasy FxVolGetter [1 kB]
- FxVolGetterTest.bas -- moduł z kodem wykorzystującym przedstawione rozwiązanie [1 kB]
Słowa kluczowe: vba, bloomberg api, zmienność implikowana


![[vim created]](./grafika/vim_created.png)