Centrum Skrypciarzy - Microsoft Office

Jak utworzyć listę wszystkich tabel znajdujących się 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 utworzyć listę wszystkich tabel znajdujących się w bazie danych programu Access?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak utworzyć listę wszystkich tabel znajdujących się w bazie danych programu Access?

-- KW

Cześć Skrypciarze! Odpowiedź

Cześć, KW. Muszę się przyznać, ze najbardziej w pisaniu codziennych artykułów o skryptach administracyjnych podoba mi się to, że czytelnicy widzą tylko ostateczny rezultat. Nie widzą w ogóle wszystkich tych pomyłek, ślepych uliczek i innych frustrujących problemów, jakie muszę pokonać przed opracowaniem gotowego skryptu. Dlaczego jest to takie fajne? Otóż na pewno każdy sobie myśli: „Jacy ci Skrypciarze są mądrzy! Znają odpowiedź na każde pytanie, jakie im można zadać! Jeden z nich wie nawet, jak utworzyć listę wszystkich tabel znajdujących się w bazie danych programu Access!” Nie przyznam się przecież, że nie miałem zielonego pojęcia, jak to zrobić i musiałem spędzić ładnych parę godzić, grzebiąc się w instrukcjach, poradnikach i informatorach. Znaczy, chyba się właśnie przyznałem, ale to nieważne – po prostu nie czytajcie poprzedniego zdania!

Oto gotowy skrypt:

Const adSchemaTables = 20



Set objConnection = CreateObject("ADODB.Connection")

Set objRecordSet = 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

    Wscript.Echo "Table name: " & objRecordset.Fields.Item("TABLE_NAME")

    Wscript.Echo "Table type: " & objRecordset.Fields.Item("TABLE_TYPE")

    Wscript.Echo

    objRecordset.MoveNext

Loop

Spójrzmy prawdzie w oczy – ktoś nie mający takiego doświadczenia w skryptach administracyjnych, jak Skrypciarze, mógłby spróbować zaatakować ten problem przy użyciu modelu obiektów Microsoft Access. Skrypciarze są na to jednak za sprytni. Wiemy, że do pobrania tych informacji trzeba użyć obiektów ADO.

Właściwie to tym lepiej – możemy bowiem zastosować bardzo podobne podejście do innych typów baz danych (uwaga: Microsoft Access wbrew pozorom nie jest jedynym programem bazodanowym!).

Przyjrzyjmy się bliżej działaniu skryptu. Na początek definiujemy stałą o nazwie adSchemaTables, której wartość ustawiamy na 20; posłuży nam ona do poinstruowania skryptu o rodzaju obiektów schematu bazy danych, jaki nas interesuje (nie trzeba chyba mówić, że w tym wypadku chodzi o tabele). Czy istnieją inne obiekty schematu, które moglibyśmy pobrać? Jasne. Można o nich poczytać w dokumentacji SchemaEnum (j.ang.) w witrynie MSDN.

Po zdefiniowaniu stałej tworzymy dwa obiekty: ADODB.Connection i ADODB.Recordset. Jeśli pracowaliście już trochę z obiektami ADO, obiekty Connection i Recordset powinny być wam znajome. Co jednak z osobami, które nie mają pojęcia, o czym mówimy? No cóż - odsyłamy ich do naszego webcastu Database Scripting for System Administrators (j.ang.), dzięki któremu można poznać najważniejsze, podstawowe informacje potrzebne do zrozumienia działania dzisiejszego skryptu.

Mając oba obiekty na podorędziu, możemy użyć metody Open do otwarcia pliku C:\Scripts\Test.mdb:

objConnection.Open _

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

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

Następnie możemy wywołać metodę OpenSchema i pobrać informacje o samej bazie danych. Jakie informacje nas interesują? W naszym wypadku przekazujemy metodzie OpenSchema stałą adSchemaTables; oznacza to, że uzyskamy zestaw rekordów składający się z informacji o wszystkich tabelach w bazie.

Teraz musimy uruchomić pętlę Do Until, która przejdzie przez uzyskany zestaw i wyświetli echo informacji o rekordach (czyli tabelach) w nim zawartych. To właśnie robimy w tym fragmencie kodu:

Do Until objRecordset.EOF

    Wscript.Echo "Table name: " & objRecordset.Fields.Item("TABLE_NAME")

    Wscript.Echo "Table type: " & objRecordset.Fields.Item("TABLE_TYPE")

    Wscript.Echo

    objRecordset.MoveNext

Loop

Jak widać, pętla Do Until będzie działać, dopóki właściwość EOF (oznaczająca koniec pliku) nie osiągnie wartości True; innymi słowy, chcemy, by pętla działała, dopóki nie skończą się nam rekordy. Zwróćcie uwagę na ostatni wiersz kodu pętli Do Until: objRecordset.MoveNext. Czy to ważne? Jasne, i to jak! Ten wiersz kodu instruuje skrypt, by po zakończeniu działania z jednym rekordem przeszedł do kolejnego. Brak metody MoveNext spowodowałby utknięcie skryptu na pierwszym rekordzie. Bardziej szczegółowy opis można znaleźć w artykule Yes, Ken, We See You Already! (j.ang.)

Co jest jeszcze w pętli, oprócz metody MoveNext? Jest fragment wywołujący echo wartości właściwości TABLE_NAME i TABLE_TYPE:

Wscript.Echo "Table name: " & objRecordset.Fields.Item("TABLE_NAME")

Wscript.Echo "Table type: " & objRecordset.Fields.Item("TABLE_TYPE")

Czy to też jest ważne? Owszem. W końcu w ten sposób otrzymujemy interesującą nas listę tabel i odpowiadających im typów, znajdujących się w bazie C:\Scripts\Test.mdb:

Table name: UserInformation

Table type: TABLE



Table name: ComputerInformation

Table type: TABLE



Table name: MSysAccessObjects

Table type: ACCESS TABLE



Table name: MSysACEs

Table type: SYSTEM TABLE



Table name: MSysObjects

Table type: SYSTEM TABLE



Table name: MSysQueries

Table type: SYSTEM TABLE



Table name: MSysRelationships

Table type: SYSTEM TABLE

Jak zapewne zauważyliście, skrypt zwraca informacje o wszystkich tabelach, w tym o tabelach systemowych, z którymi użytkownik się właściwie nie styka. Czy można ograniczyć zakres zwracanych danych tylko do tych tabel, z którymi użytkownicy rzeczywiście mają do czynienia (jak np. UserInformation i ComputerInformation)? Jasne. Wystarczy zmodyfikować skrypt w taki sposób:

arrCriteria = Array(Empty, Empty, Empty, "Table") 



Set objRecordSet = objConnection.OpenSchema(adSchemaTables, arrCriteria)

Utworzyliśmy tu tablicę o nazwie arrCriteria i nakazaliśmy jej wyszukiwanie tabel, których właściwość TABLE_TYPE ma wartość Table. (Trzy parametry Empty oznaczają inne kryteria, których moglibyśmy użyć w filtrowaniu; informacje na ten temat można znaleźć w dokumentacji SchemaEnum (j.ang.). Następnie używamy zmiennej arrCriteria jako opcjonalnego, drugiego parametru metody OpenSchema.

Co uzyskamy po uruchomieniu tego zmodyfikowanego skryptu? Coś takiego:

Table name: UserInformation

Table type: TABLE



Table name: ComputerInformation

Table type: TABLE

Here’s what the entire script looks like:

Const adSchemaTables = 20



Set objConnection = CreateObject("ADODB.Connection")

Set objRecordSet = CreateObject("ADODB.Recordset")



objConnection.Open _

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

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



arrCriteria = Array(Empty, Empty, Empty, "Table") 



Set objRecordSet = objConnection.OpenSchema(adSchemaTables, arrCriteria)



Do Until objRecordset.EOF

    Wscript.Echo "Table name: " & objRecordset.Fields.Item("TABLE_NAME")

    Wscript.Echo "Table type: " & objRecordset.Fields.Item("TABLE_TYPE")

    Wscript.Echo

    objRecordset.MoveNext

Loop

Nie było wcale trudne. A na pewno nie dla Skrypciarzy…

 Do początku strony Do początku strony

Centrum Skrypciarzy - Microsoft Office