Centrum skryptów - Microsoft Office

Jak pobrać rozmiar pola i przykładowy rekord dla wszystkich tabel i pól w bazie danych programu Access?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak pobrać rozmiar pola i przykładowy rekord dla wszystkich tabel i pól w bazie danych programu Access?

Cześć Skrypciarze! Pytanie

Cześć Skrypciarze! Ostatnimi czasy natknąłem się na Wasz artykuł , w którym doradzacie, jak pobrać nazwy wszystkich tabel w bazie danych programu Access, razem z listą wszystkich pól w każdej tabeli oraz typem danych w każdym z tych pól. Bardzo mi się to przydało, ale pracowałoby mi się ze skryptem jeszcze lepiej, gdybym mógł dodać rozmiary każdego pola oraz wyświetlić przykładowy rekord z każdej tabeli. Czy jesteście w stanie mi pomóc?

-- SP

Cześć Skrypciarze! Odpowiedź

Cześć, SP! Ten dzień może być najlepszym dniem Twojego życia, pamiętaj o tym. No dobra, może być najlepszym dniem mojego życia, zaczął się bowiem od jakże przeze mnie lubianych rytuałów. Ostatnio ze Skrypciarzami zaczęliśmy nowy rytuał, mianowicie każdego ranka zasiadamy w skrypciarskiej kuchni i wcinamy skrypciarskie donaty.

Uwaga: Oczywiście robimy to poza godzinami pracy. Każde z nas przychodzi pół godziny wcześniej, żeby pałaszować wspólnie nasze ulubione ciastka, o ile można to tak nazwać. Pomaga nam to w utrzymywaniu więzi, tak ważnych dla pracy grupowej, jak i daje szansę przedyskutowania wielu istotnych kwestii związanych z naszym Centrum Skryptów.

To powyżej to oczywiście ściema, wiadomo przecież, że pracodawcy czytają tylko i wyłącznie rzeczy napisane kursywą, tudzież pogrubione, i to w tabeli. Wspólne jedzenie jest oczywiście wymówką, żeby jak najpóźniej siadać do pracy. Tylko czemu ciągle ja kupuję te donaty? (mam nadzieję, ze pytanie retoryczne zmusi moich skrypciarskich kolegów i koleżanki do refleksji nad moim portfelem…)

Teraz jestem już po dwóch, więc jestem zwarty i gotowy do napisania skryptu, który pobiera wszystkie tabele w bazie danych programu Access, raportuje ich nazwę, typ danych oraz rozmiar, a następnie pokazuje przykładowy rekord dla każdej z tych tabeli:

Const adSchemaTables = 20

Const adSchemaColumns = 4



Set objConnection = CreateObject("ADODB.Connection") 

Set objRecordSet2 = CreateObject("ADODB.Recordset")



objConnection.Open _

    "Provider = Microsoft.Jet.OLEDB.4.0; " & _

        "Data Source = 'C:\Scripts\Test.mdb'"



Set objRecordset = objConnection.OpenSchema(adSchemaTables)



Do Until objRecordset.EOF

    strSample = ""

    strTableName = objRecordset("Table_Name")



    If UCase(objRecordset("Table_Type")) = "TABLE" Then



    Set objFieldSchema = objConnection.OpenSchema(adSchemaColumns, _

        Array(Null, Null, strTableName))



        Wscript.Echo "============================================================"

        Wscript.Echo UCase(objRecordset("Table_Name"))

        Wscript.Echo "============================================================"

        Wscript.Echo

        objRecordset2.Open "SELECT * FROM " & strTableName, objConnection

        objRecordset2.MoveFirst



        Do While Not objFieldSchema.EOF

            strColumn = objFieldSchema("Column_Name")

            Wscript.Echo "Field Name: " & objFieldSchema("Column_Name") 

            Wscript.Echo "Data Type: " & objFieldSchema("Data_Type")

            Wscript.Echo "Field Size: " & objFieldSchema("Character_Maximum_Length")

            Wscript.Echo

            strSample = strSample & strColumn & " -- " & _

                objRecordset2.Fields.Item(strColumn) & vbCrLf

            objFieldSchema.MoveNext

        Loop



        Wscript.Echo

        Wscript.Echo "SAMPLE RECORD"

        Wscript.Echo strSample

        Wscript.Echo

        Wscript.Echo



        objRecordset2.Close

    End If



    objRecordset.MoveNext

Loop
Access 2007: Jeżeli uruchomicie skrypt w bazie danych programu Access 2007, Wasze twierdzenie Open będzie musiało być trochę inne niż to podane powyżej. Będzie się różnić nie tylko rozszerzeniem pliku (.accdb zamiast .mdb), zauważycie, że inny będzie także dostawca:
objConnection.Open _

    "Provider = Microsoft.ACE.OLEDB.12.0; " & _

        "Data Source = C:\Scripts\Test.accdb"

Nie będziemy się tu zajmować podstawowymi zasadami pobierania informacji na temat tabeli/pola. To wszystko omówiliśmy już w naszym poprzednim artykule na ten temat. Omówiliśmy tę kwestię bardzo szczegółowo, więc po co się powtarzać, nadwerężając cierpliwość osób, które czytały już rzeczony artykuł. Wolimy za to skoncentrować się na kodzie i tym, co różni skrypt z pierwszego artykułu od dzisiejszego.

Tak jak w pierwotnym skrypcie, zaczynamy od zdefiniowania pary stałych (adSchemaTables oraz adSchemaColumns), które dają nam dostęp do właściwości tabeli oraz pól bazy danych. Następnie tworzymy wystąpienie obiektu ADODB.Connection, który ma za zadanie połączyć się z bazą danych, oraz obiektu ADODB.Recordset (wystąpienie, które nazwaliśmy objRecordset2). Po co nam ten drugi obiekt? Za chwilę wytłumaczymy, trochę cierpliwości.

Należy teraz wywołać metodę Open obiektu Connection, otworzyć bazę danych C:\Scripts\Test.mdb i przy użyciu poniższego wiersza kodu otrzymać zwrócony zestaw rekordów (objRecordset), który zawiera wszystkie informacje o tabelach Test.mdb:

Set objRecordset = objConnection.OpenSchema(adSchemaTables)

Teraz będzie trochę trudniej. Ustawiamy pętlę OK Do Until, która przechodzi przez całość zestawu, aż do momentu, w którym właściwość EOF przyjmie wartość True (innymi słowy, pętla przechodzi przez wszystkie elementy do końca). Wewnątrz pętli ustawiamy pustą wartość właściwości, po czym przypisujemy właściwości Table_Name (która jest niczym innym jak nazwą tabeli) zmienną strTableName.

Następnie pojawia nam się następujący, jakże niepokojący wiersz kodu:

If UCase(objRecordset("Table_Type")) = "TABLE" Then

Szczerze mówiąc, dorzuciliśmy to tylko dla picu. Ograniczając raportowane dane do tabel mających właściwość Table_Type o wartości TABLE, uzyskujemy wyłącznie informacje o tabelach utworzonych przez nas. Inne tabele są ignorowane. To chyba dobry pomysł – w 99% przypadków użytkownika będą interesować tylko takie tabele.

Uwaga: Co z pozostałym 1% przypadków? Nic prostszego, po prostu wykasujcie instrukcje If-Then oraz End If, a otrzymacie informacje na temat wszystkich tabel w bazie danych.

Zakładamy, że mamy do czynienia z tabelą utworzoną przez użytkownika, wywołujemy więc metodę OpenSchema i tym samym otrzymujemy informację zwrotną związaną z polem dla pierwszej tabeli w zestawie rekordów:

Set objFieldSchema = objConnection.OpenSchema(adSchemaColumns, _

    Array(Null, Null, strTableName))

Następnie używamy poniższego wiersza kodu w celu dodania „nagłówka” na ekranie:

Wscript.Echo "============================================================"

Wscript.Echo UCase(objRecordset("Table_Name"))

Wscript.Echo "============================================================"

Wscript.Echo

Niczego fikuśnego tutaj się nie doszukacie, to tylko nazwa (TABLE_NAME) wzięta w ramkę ze znaków równości (znak równości wymyślił ponoć Walijczyk, tak przynajmniej twierdził, bynajmniej niepytany, jedyny Walijczyk, jakiego dane mi było spotkać) – dzięki temu nazwa jest widoczna, a tablice są wyraźnie rozdzielone. Innymi słowy, daje nam to następujący nagłówek:

============================================================

COMPUTERS

============================================================

Następnie naszym oczom ukazują się następujące dwa wiersze kodu:

objRecordset2.Open "SELECT * FROM " & strTableName, objConnection

objRecordset2.MoveFirst

Po co? Znamy już nazwę każdego pola w tabeli (informacja ta jest przechowywana w zestawie rekordów objFieldSchema), informacja ta dotyczy jednak tylko metadanych tych pól. Zawiera w sobie nazwę pola, jego typ oraz rozmiar, ale nie zawiera wartości pola.

Pierwszego wiersza używamy w celu utworzenia starego dobrego zestawu rekordów ADO, składającego się ze wszystkich informacji na temat danych w tabeli strTableName. Następnie używamy drugiego wiersza kodu i przemieszczamy pierwszy rekord w zwróconym zestawie rekordów. Ten pierwszy rekord będzie służył nam jako źródło przykładowego rekordu, który ma się pokazywać na ekranie.

Następnie uruchamiamy kolejną pętlę Do Until, która przechodzi ona przez dane pola przechowywane w objFieldSchema. Wewnątrz pętli wywołujemy wszystkie informacje podstawowe na temat każdego pola, łącznie z jego właściwością Character_Maximum_Length (maksymalna długość znaków). Właśnie ta właściwość mówi nam o rozmiarze pola:

Wscript.Echo "Field Size: " & objFieldSchema("Character_Maximum_Length")
Uwaga: Wypada nadmienić na tym etapie, że pola będą miały jakiś określony rozmiar, jeżeli ich typ danych posiada taką właściwość. Pole, które zawierać może maksymalnie 100 znaków, zwróci nam wartość Character_Maximum_Length równą 100. Nie wszystkie pola mają jednak taką właściwość, przykładem są tu pola numeryczne, które w tym samym wypadku zwrócą nam wartość zerową.

Teraz zaczynamy zapisywanie – aby zapisać nazwę pola wraz z obecną wartością pola dla pierwszego rekordu w tabeli w zmiennej strSample, używamy poniższego wiersza kodu:

strSample = strSample & strColumn & " -- " & _

    objRecordset2.Fields.Item(strColumn) & vbCrLf

Jeżeli pierwsze pole w pierwszej tabeli ma nazwę ComputerName, a pierwszy rekord w tabeli ma wartość, atl-ws-01, to oznacza to, że nasza zmienna strSample będzie równa właśnie tyle co:

ComputerName -- atl-ws-01

Teraz już tylko po raz kolejny uruchamiamy pętlę i powtarzamy proces dla następnego pola w tabeli, dodając jego nazwę (i przykładową wartość) do zmiennej strSample. Po przejściu przez wszystkie pola w tabeli, wywołujemy echo wartości strSample, zamykamy objRecordset2, po czym robimy to samo od początku dla drugiej tabeli w bazie danych:

Kiedy już mamy to za sobą, otrzymujemy następujący raport:

============================================================

COMPUTERS

============================================================



Field Name: ComputerName

Data Type: 130

Field Size: 50



Field Name: SerialNumber

Data Type: 130

Field Size: 50





SAMPLE RECORD

ComputerName -- atl-ws-01

SerialNumber -- 1





============================================================

DISKDRIVES

============================================================



Field Name: Drive

Data Type: 130

Field Size: 50



Field Name: DriveSize

Data Type: 2

Field Size:



Field Name: SerialNumber

Data Type: 130

Field Size: 50



Field Name: Type

Data Type: 130

Field Size: 50





SAMPLE RECORD

Drive -- C:

DriveSize -- 50

SerialNumber -- 1

Type --

To bardzo interesujące!

Mamy nadzieję, że udało nam się odpowiedzieć na Twoje pytanie, SP. Jeżeli czyta to Skrypciarka Jean Ross, to przypominamy, że w społecznościach Skrypciarzy jaskiniowych to kobiety zajmowały się dbaniem o ognisko domowe (czytaj – wypieki) każdej (skrypciarskiej) rodziny. Przypominamy tylko, nic nie sugerujemy…

 Do początku strony Do początku strony

Centrum skryptów - Microsoft Office