Nie każdy programista VBA wie, że w całkiem prosty sposób można wykorzystać język SQL do pobrania danych z określonego arkusza aktywnego skoroszytu. Bardziej zaawansowani programiści znają ryzyka związane z tą techniką- tzw. memory leaks, problem związany brakiem pamięci, ale także z brakiem dostępu do części danych w sytuacji gdy są one aktualizowane równocześnie z procesem pobierania. Pomimo wspomnianych zagrożeń uważam, że wspomniana technika jest na tyle interesująca, iż postanowiłem poświęcić jej co najmniej dwa wpisy. Zaprezentuję więc prostą technikę pobierającą SQL z wykorzystaniem ADODB (Microsoft ActiveX Data Objects).
1. Chyba najprostszy sposób pracy z ADODB oparty jest o technikę wczesnego wiązania dzięki czemu uzyskujemy dostęp do podpowiedzi IntelliSense dla obiektów, właściwości i metod związanych z ADODB. W tym celu w naszym projekcie, w edytorze VBA przechodzimy do Menu >> Tools >> References... i na liście odnajdujemy bibliotekę ADODB 2.8 (idealna dla Office od 2007 do 2013).
2. Bez wątpienia potrzebujemy zestawu danych testowych, które powinny znajdować się w określonym arkuszu. Najczęściej dane te znajdują się począwszy od komórki A1. Co jednak ważne- nie jest to wymagane. Silnik pobierania będzie wyszukiwał pierwszej zajętej komórki i tę właśnie uzna za początek naszej tabeli danych.
3. A teraz sam kod... wszelkie dodatkowe informacje umieszczone zostały poniżej w postaci komentarzy. A co się stanie w wyniku wywołania poniższej przykładowej procedury? Zależnie od wybranego zapytania SQL albo uzyskamy wybrany wycinek danych albo tabelę z podsumowaniem sprzedaży.
01 | Sub SQL_ADODB_AktywnySkoroszyt() |
03 | Dim strConnString As String |
04 | strConnString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ |
05 | "Data Source=" & ActiveWorkbook.FullName & ";" & _ |
06 | "Extended Properties=Excel 12.0 Xml;" |
10 | SQL = "SELECT * FROM [Arkusz Dane$] WHERE Data <#2015-11-01#" |
13 | SQL = "SELECT Produkt, SUM(Ilość), Sum(Ilość * Cena) " & _ |
14 | "FROM [Arkusz Dane$]" & _ |
19 | Dim RS As ADODB.Recordset |
20 | Set RS = New ADODB.Recordset |
22 | RS.Open SQL, strConnString |
24 | Sheets(3).Range( "A2" ).CopyFromRecordset RS |