Dr Janusz Górczyński Materiały pomocnicze do zajęć z przedmiotu Projekt ADP Czym jest projekt ADP? Projekt Microsoft Access (.adp) jest typem pliku programu Access, który zapewnia skuteczny dostęp w trybie macierzystym do bazy danych Microsoft SQL Server za pomocą architektury składnika OLE DB. Używając projektu Access, można utworzyć aplikację klient/serwer, w której projekt ADP może być połączony ze zdalną bazą danych SQL Server lub lokalną bazą danych SQL Server Charakterystyczną cechą projektu ADP jest: 1. Połączenie projekt programu Access z bazą danych SQL Server. 2. Przechowywanie w bazie danych SQL Server takich obiektów jak: Tabele, Widoki, Diagramy. 3. Przechowywanie w projekcie Access formularzy, raportów i modułów. W jaki sposób tworzymy nowy projekt ADP? Wystarczy po prostu utworzyć nowy plik bazy danych, przy czym jako typ pliku wybieramy opcję *.adp, po jego utworzeniu Access wyświetla okna dialogowe, w którym wskazujemy serwer SQL i bazę danych, z którą zwiążemy utworzony projekt. Poniżej okno dialogowe w którym wskazujemy serwer SQL, sposób identyfikacji użytkownika oraz bazę danych.
Czy można zmienić bazę danych i serwer SQL? Oczywiście tak, w przycisku głównym Accessa znajdziemy polecenie Serwer, a dalej Połączenie. Jego klik otworzy pokazane wcześniej okno Właściwości łącza danych. Przykładowy Projekt Na dysku wspolny\podyplomowe jest plik o nazwie AnkietaSQL.adp, możemy go wykorzystać jako przykładowy projekt ADP. Po jego uruchomieniu trzeba wywołać okno właściwości łącza danych i zmienić serwer oraz bazę danych na własną. Jak wywołać procedurę przechowywaną? W bazie SQL utworzono procedurę przechowywaną zwracającą liczbę rekordów w tabeli PrzedmiotProwadzacy dla określonej wartości pola id_w i określonej wartości pola id_p. Definicja tej procedury pokazana jest niżej. Jak widzimy w procedurze zdefiniowano dwa parametry typu input o nazwach odpowiednio @idw oraz @idp, oba typu integer, oraz parametr typu output o nazwie @TakNie, także typu integer. create procedure [dbo].[pczymoznadodacprzedmiotwykladowca] @idw int, @idp int, @TakNie int out as select @TakNie = COUNT(*) from PrzedmiotProwadzacy where id_w=@idw and id_p=@idp Klasyczny sposób wywołania tej procedury przechowywanej przedstawiony jest w procedurze o nazwie TestProcedury utworzonej w module o nazwie Testowy w projekcie ADP. Komentarze powinny wyjaśnić sens i znaczenie poszczególnych instrukcji. Public Sub TestProcedury() ' deklaracja potrzebnych zmiennych i obiektów Dim cmd As ADODB.Command, prm As ADODB.Parameter ' tworzymy obiekt command Set cmd = New ADODB.Command ' podajemy nazwę procedury do wykonania cmd.commandtext = "dbo.pczymoznadodacprzedmiotwykladowca" ' określamy typ polecenia (jako procedurę przechowywaną) cmd.commandtype = adcmdstoredproc ' tworzymy kolejne parametry tej procedury i dodajemy je do kolekcji parametrów Set prm = cmd.createparameter("idw", adinteger, adparaminput) prm.value = 1 'przykładowa wartosc 'dodanie parametru do kolekcji parametrów obiektu command ' drugi parametr typu input Set prm = cmd.createparameter("idp", adinteger, adparaminput) prm.value = 2 'przykładowa wartosc 'dodanie parametru do kolekcji paramaetrów obieku command
' parametr wychodzący output Set prm = cmd.createparameter("taknie", adinteger, adparamoutput) 'dodanie parametru do kolekcji paramaetrów obieku command ' zdefinuiwanie aktywnego połączenia dla obiektu command Set cmd.activeconnection = CurrentProject.Connection ' wykonanie polecenia cmd.execute ' odebranie I wyświetlenie zwróconego parametru MsgBox cmd.parameters("taknie") ' zwalniamy pamięć RAM Set cmd = Nothing Set prm = Nothing Jak widać musimy zrealizować kilka kroków: 1. Utworzyć obiekt Command modelu ADO i określić jego właściwości CommandText i CommandType; 2. Zbudować kolekcję parametrów obiektu Command, czyli dla każdego parametru wykonujemy: a) Tworzymy obiekt Parameter podając jego nazwę, typ danych, kierunek i opcjonalnie rozmiar; b) Dla parametrów wchodzących przypisujemy jego wartość; c) Dodajemy utworzony parametr do kolekcji parametrów obiektu Command; 3. Przypisujemy aktywne połączenie do właściwości ActiveConnection obiektu Command; 4. Wykonujemy polecenie poprzez wywołanie metody Execute obiektu Command; 5. Jeżeli przewiduje to procedura przechowywana, to odbieramy parametr zwracany (typu output). W przykładowej bazie danych utworzyłem dedykowany moduł o nazwie ForStorageSub, moduł ten zawiera procedury i funkcje znakomicie ułatwiające wywoływanie procedur przechowywanych. Pokazana niżej procedura realizuje dokładnie to samo, co pokazana wyżej procedura TestProcedury. Public Sub TestForStorageSub() ' dokładnie to samo, ale z wykorzystaniem funkcji fdajwartosc MsgBox fdajwartosc("dbo.pczymoznadodacprzedmiotwykladowca", _ "idw", 1, p_integer, 0, _ "idp", 1, p_integer, 0, _ "TakNie", p_integer, 0) Jak utworzyć rekord set? W bazie mamy procedurę przechowywaną o nazwie dbo.pdajkierunki, jej zadaniem jest zwrócenie posortowanych informacji z tabeli Kierunki. ALTER procedure [dbo].[pdajkierunki] @idp int as select id_k, Kierunek from Kierunki order by kierunek W procedurze zdefiniowano, z uwagi na moduł ForStorageSub jeden pusty parametr o nazwie @idp typu integer. Pusty w tym sensie, że jest potrzebny z uwagi na procedury wspomnianego modułu, bowiem w samej procedurze przechowywanej nie jest wykorzystywany w żadnym warunku Where. Zestaw rekordów zwracany przez tę procedurę pokazany jest niżej.
Napiszemy teraz procedurę VBA, której zadaniem będzie wykonanie procedury przechowywanej pkierunki, a następnie z wykorzystaniem funkcji MsgBox wyświetlimy zwrócone informacje na ekranie. Public Sub KlasycznyTestRekordsetu() ' deklaracja potrzebnych zmiennych i obiektów Dim cmd As ADODB.Command, prm As ADODB.Parameter, rst As ADODB.Recordset, _ t As String, i As Integer ' tworzymy obiekt command Set cmd = New ADODB.Command ' podajemy nazwę procedury do wykonania cmd.commandtext = "dbo.pdajkierunki" ' określamy typ polecenia (jako procedurę przechowywaną) cmd.commandtype = adcmdstoredproc ' tworzymy kolejne parametry tej procedury i dodajemy je do kolekcji parametrów Set prm = cmd.createparameter("idp", adinteger, adparaminput) prm.value = 1 'przykładowa wartosc ' dodanie parametru do kolekcji parametrów obiektu command Set cmd.activeconnection = CurrentProject.Connection ' wykonanie polecenia Set rst = cmd.execute ' jeżeli są rekordy, to budujemy zmienną t If rst.recordcount > 0 Then t = "" For i = 1 To rst.recordcount t = t & Str(rst(0)) & " " & rst(1) & vbcrlf rst.movenext Next i t = Left(t, Len(t) - 1) MsgBox t, vbinformation, "Test rekordsetu" Else MsgBox "Brak rekordów", vbcritical, "Test rekordsetu" End If ' zamykamy obiekt recordset rst.close ' usuwamy wszytskie obiekty Set rst = Nothing Set cmd = Nothing Set conn = Nothing Z wykorzystaniem funkcji fdajrekordset z modułu ForStorageSub można to zrealizować znacznie prościej (w części dotyczącej uzyskania rekordsetu). Public Sub TestRekordsetuWgJG() Dim rst As ADODB.Recordset, t As String, i As Integer ' przypisanie do obiektu rst rekordsetu zwróconego przez fdajrekordset Set rst = fdajrekordset("dbo.pdajkierunki", _ "idp", 1, p_integer, 0) If rst.recordcount > 0 Then t = "" For i = 1 To rst.recordcount t = t & Str(rst(0)) & " " & rst(1) & vbcrlf rst.movenext Next i t = Left(t, Len(t) - 1) MsgBox t, vbinformation, "Test rekordsetu wg JG" Else MsgBox "Brak rekordów", vbcritical, "Test rekordsetu wg JG" End If rst.close Set rst = Nothing Myślę, że porównanie kodów obu procedur pozwala na sformułowanie wniosku, że warto było poświęcić trochę czasu na wymyślenie modułu ForStorageSub. Autor tego tekstu wykorzystuje ten moduł w aplikacjach zarówno VBA (Word, Excel, Access) jak i VB.NET do komunikacji z bazą danych MS SQL.