piątek, 8 maja 2015

Konwersja tablicy Array na Recordset

Tablice Array są istotnym elementem wielu rozwiązań tworzonych w VBA. Co zrobić jednak w sytuacji gdy określoną tablicę (jedno- lub wielowymiarową) chcemy przefiltrować ze względu na określone zmienne kryteria? W Excelu rozwiązanie to wydaje się być proste - przenieść tablicę do komórek Excela i zastosować filtrowanie. Co jednak zrobić w kodzie VBA stworzonym w innych aplikacjach z pakietu Office? Odpowiedź jest relatywnie prosta- należy przekonwertować tablicę Array na obiekt ADODB.Recordset aby następnie zyskać możliwość filtrowania danych zgodnie z zasadami języka SQL. Myślę więc, że każdy kto spotkał się z podobnym problemem może uznać niniejsze zagadnienie za interesujące.

Krok 1- tworzymy referencję do biblioteki ADODB z poziomu edytora VBA (Menu >> Tools >> References... >> zaznaczamy Microsoft ActiveX Data Objects 2.8 Library)

Krok 2- tworzymy tablicę array przenosząc komórki Excela do tablicy lub tworząc ją na poziomie kodu.
01Dim i As Integer
02Dim arrTemp(100, 1) As Variant
03'inicjujemy losowanie w celu utworzenia losowych nazw produktu
04Randomize  
05For i = 0 To 100
06    'kolumna z ID
07    arrTemp(i, 0) = i
08    'kolumna z nazwą produktu, nazwa częściwo losowa
09    arrTemp(i, 1) = "Produkt " & _
10                    Chr(65 + Int(Rnd() * 26)) & _
11                    Format(i, "000")
12Next i
Krok 3- tworzymy obiek ADODB.Recordset i konfigurujemy pola tego obiektu
1Dim RS As ADODB.Recordset
2Set RS = New ADODB.Recordset
3 
4'tworzymy wirtualny recordset
5RS.Fields.Append "ID", adBigInt, , adFldKeyColumn
6RS.Fields.Append "ProductName", adVarChar, 50
7RS.Open
Krok 4- przenosimy dane z tablicy do obiektu Recordset
1For i = 0 To 100
2    RS.AddNew
3    RS("ID").Value = arrTemp(i, 0)
4    RS("ProductName").Value = arrTemp(i, 1)
5 
6Next i
Krok 5- tak utworzony obiekt możemy swobodnie filtrować korzystając z właściwości .Filter obiektu Recordset. W poniższym kodzie efekt filtrowania testujemy przenosząc wybrane wartości obiektu Recordset do komórek arkusza Excel.
01With RS
02        'przykład 1: filtrowanie ze względu na ID
03        .Filter = "ID >5 and ID <20"
04        ActiveCell.CurrentRegion.Clear
05        ActiveCell.CopyFromRecordset RS
06         
07        Stop
08         
09        'przykład 2: filtrowanie ze względu na ID
10        .Filter = "ID > 90"
11        ActiveCell.CurrentRegion.Clear
12        ActiveCell.CopyFromRecordset RS
13         
14        Stop
15        'przykład 3: filtrowanie ze względu na nazwę produktu
16        .Filter = "ProductName LIKE '%Z%'"
17        ActiveCell.CurrentRegion.Clear
18        ActiveCell.CopyFromRecordset RS
19End With