Access

 MS Access & XML & Baza miejscowości i ulic TERYT.

Krajowy Rejestr Urzędowy Podziału Terytorialnego Kraju (TERYT)

Klasa clsTeryt. Przygotowanie tabel (relacji) na pobranie danych z Rejestru TERYT.

• Stan na dzień 03 marca 2018 roku

Główny Urząd Statystyczny (GUS) umożliwia pobranie z bazy Krajowego Rejestru Urzędowego Podziału Terytorialnego Kraju Pliki pełne rejestru TERYT. w formacie XML oraz CSV i kodowaniu UTF-8, poniższych katalogów:

  • TERC - system (zbiór) identyfikatorów i nazw jednostek podziału terytorialnego.
  • SIMC - system (zbiór) identyfikatorów (urzędowych) i nazw miejscowości.
  • ULIC - system (zbiór) identyfikatorów i nazwy ulic.
  • WMRODZ - zbiór (wykaz) symboli i nazw rodzajów miejscowości.

Potrzebne tabele MS Access

Na poprzednich stronach • Zbiór WMRODZ, • Zbiór TERC, • Zbiór SIMC, • Zbiór ULIC przedstawiłem sposób przetwarzania plików *.XML za pomocą biblioteki Microsoft XML,v6.0. Dla dwóch największych plików zawierających zbiór SIMC oraz zbiór ULIC biblioteka Microsoft XML,v6.0 niezbyt się sprawdziła ze względu na bardzo długi czas przetwarzania i zapisu danych do tabel. Dlatego w celu pobranie danych z tych plików zostały użyte wbudowane funkcje tekstowe VBA.

Według mojego projektu mającego na celu zapis wszystkich danych w „Relacyjnej bazie danych MS Access” dla każdego pliku trzeba utworzyć co najmniej jedną tabelę:

Plik WMRODZ.xml wymaga jednej tabeli:
• tblWMRodz,
Plik SIMC.xml wymaga czterech tabel:
• tblRodz_Gmi,
• tblWojewodztwa,
• tblPowiaty,
• tblTERC_Gminy,
Plik TERC.xml wymaga jednej tabeli:
• tblSIMC_Miejscowosci,
Plik ULIC.xml wymaga dwóch tabel:
• tblULIC_Nazwy,
• tblULIC_Ulice,

Wszystkie tabele powinny zawierać indeks podstawowy (Primry Key) i zostać połączone Relacjami wymuszającymi integralność danych. Wszystkie pola tabel, za wyjątkiem pola tNazwa_2 w tabeli tblULIC_Nazwy, są wymagane (muszą zawierać dane).
Najprościej jest dla każdej tabeli napisać procedurę, za pomocą której utworzymy tabelę, dodamy do niej pola, ustawimy wymagane właściwości pól tabeli. Mając utworzone tabele ustawiamy Relacje pomiędzy polami tabel i po robocie.

Słów kilka o module klasy

Zamiast wielokrotnie pisać taki sam, lub bardzo podobny kod dla 8-miu tabel, łatwiej i prościej będzie utworzyć moduł klasy (klasę) clsTeryt, zawierającą właściwości i metody za pomocą których w prosty sposób będziemy mogli wykonać wyżej opisane czynności.
Aby wstawić do naszego projektu moduł klasy należy w oknie edytora VBA wybrać z menu pozycję „Insert” i następnie kliknąć na podmenu „Class Module”.

Wstawianie modułu klasy z menu

lub po kliknięciu prawym przyciskiem myszy w oknie Eksplorator projektu „Project” wybrać z menu podręcznego pozycję „Insert”, a potem pozycję „Class Module”.

Wstawianie modułu klasy z menu podręcznego

Następnie w oknie właściwości nowo wstawionego modułu klasy „Properties Class1” nadajemy właściwości Name wartość clsTeryt. Od tej pory będziemy się mogli odwoływać do naszej klasy za pomocą jej nazwy clsTeryt.

Klasa clsTeryt

Poniżej przedstawiam spis metod jakie oferuje klasa clsTeryt, za pomocą których możemy utworzyć nową tabelę, dodać do niej nowe pola określonego typu i rozmiaru (dla pól tekstowych), utworzyć klucz podstawowy tabeli oraz utworzyć indeksy na wybranych polach. Pomiędzy tabelami możemy utworzyć Relacje wymuszające integralność referencyjną danych tj. „kaskadową aktualizację pól pokrewnych” oraz „kaskadowe usuwanie rekordów pokrewnych”.

Metody klasy clsTeryt

• Metoda

terytCreateTable(sTableName As String) As Boolean

tworzy nowy obiekt TableDef, (nową tabelę o nazwie sTableName). Należy zauważyć, że tabela ta nie jest jeszcze zapisana w bazie, więc nie może być widoczna w oknie bazy danych.

• Metoda 

terytCreateField( _
                          sFieldName As String, _
                          iType As Long, _
             Optional lSize As Integer = 0, _
             Optional fRequired As Boolean = True, _
             Optional fAllowZeroLength As Boolean = False) As Boolean

tworzy nowy obiekt Field określonego typu i rozmiaru (dla pola tekstowego), ustawia właściwość RequiredAllowZeroLength, następnie dołącza obiekt Field do kolekcji Fields obiektu TableDef (m_tdf). Innymi słowy, tworzy nowe pole sFieldName o określonym typie iType i rozmiarze lSize w tabeli i określa, czy pole to jest Wymagane (fRequired) tzn. użytkownik musi wpisać jakieś dane oraz czy dozwolony jest ciąg zerowej długości "" (fAllowZeroLength) tzn. użytkownik nie zna danych, ale wpisuje "" co oznacza, że pole zostało edytowane i nie zawiera wartości Null.

• Metoda 

terytAppendTable() As Boolean

dołącza obiekt TableDef (m_tdf) do kolekcji TableDefs obiektu Database (m_dbs). Tabela m_tdf o nazwie sTableName zostaje zapisana w bazie i jest widoczna w oknie bazy danych.

• Metoda 

terytCreateIndex( _
                          sFieldName As String, _
             Optional fPrimary As Boolean = False, _
             Optional fUnique As Boolean = False) As Boolean

tworzy nowy obiekt Index typu Podstawowy, Unikatowy (bez Duplikatów) lub Indeks (Duplikaty OK). Utworzony obiekt Index dołącza do kolekcji Indexes obiektu TableDef (m_tdf).

• Metoda 

terytCreateIndexMulti( _
                          sFieldName As String, _
             Optional sFieldName1 As String = "", _
             Optional sFieldName2 As String = "", _
             Optional fPrimary As Boolean = False, _
             Optional fUnique As Boolean = False) As Boolean

tworzy nowy, wielopolowy (maksymalnie 3 pola) obiekt Index typu Podstawowy, Unikatowy (bez Duplikatów) lub Indeks (Duplikaty OK). Utworzony obiekt Index dołącza do kolekcji Indexes obiektu TableDef (m_tdf).

• Metoda 

terytCreateRelation( _
                          sPrimaryTableName As String, _
                          sPrimaryFieldName As String, _
                          sForeignTableName As String, _
                          sForeignFieldName As String, _
             Optional fUpdateCascade As Boolean = False, _
             Optional fDeleteCascade As Boolean = False) As Boolean

tworzy obiekt Relation pomiędzy polem sPrimaryFieldName tabeli podstawowej sPrimaryTableName i polem sForeignFieldName tabeli obcej sForeignTableName zapewniając integralność referencyjną. Następnie tworzy obiekt Field kolekcji Fields należącej do nowego obiektu Relation i dołącza obiekt Field do kolekcji Fields obiektu Relation. Ustawia atrybuty, wymuszające integralność referencyjną UpdateCascade („kaskadowo aktualizuj pola pokrewne”) lub (i) RelationDeleteCascade („kaskadowo usuń rekordy pokrewne”) tak by zmiany, lub usuwanie rekordów z powiązanych pól zostały wykonane z zachowaniem reguł. Utworzony obiekt Relation dołączany jest do kolekcji Relations obiektu Database (m_dbs).

• Metoda 

terytDeleteAllRelations() As Boolean

usuwa wszystkie relacje w obiekcie Database m_dbs.

• Metoda

terytDeleteTable(sTableName As String) As Boolean

usuwa tabelę sTableName. Przed usunięciem tabeli sTableName sprawdza, czy usuwana tabela jest powiązana relacjami z innymi tabelami. Jeżeli tak, to usuwa wszystkie relacje, którymi powiązana jest tabela sTableName z innymi tabelami w obiekcie Database (m_dbs).

Właściwości klasy clsTeryt

• Właściwość

Property Get prpTableExists(sTableName As String) As Boolean

sprawdza w kolekcji TableDefs obiektu Database (m_dbs), czy tabela sTableName istnieje.

Kod klasy clsTeryt

Option Compare Database
Option Explicit
Dim m_dbs   As DAO.Database
Dim m_tdf   As DAO.TableDef
Dim m_fld   As DAO.Field
Private Const conClassName As String = "clsTeryt"


Private Sub Class_Initialize()
	' ustaw odwołanie do bieżącej bazy danych
	Set m_dbs = CurrentDb
End Sub

Private Sub Class_Terminate()
	' zniszcz zmienne obiektowe
	Set m_fld = Nothing
	Set m_tdf = Nothing
	Set m_dbs = Nothing
End Sub

' Metoda terytCreateTable(...) tworzy nowy obiekt TableDef (m_tdf) o nazwie sTableName
Public Function terytCreateTable(sTableName As String) As Boolean

  ' utwórz nowy obiekt TableDef
  Set m_tdf = m_dbs.CreateTableDef(sTableName)
  terytCreateTable = True

End Function

' Metoda terytCreateField(...) tworzy obiekt Field o nazwie sFieldName i dołącza
'	utworzony obiekt Field do kolekcji Fields obiektu TableDef (m_tdf)
' argumenty:
'   sFieldName
'     nazwa pola, które ma być utworzone
'   iType
'     argument opcjonalny określający typ danych nowego obiektu Field.
'     Dla wartości domyślnej lType = 0, przyjmowane jest domyślne ustawienia rozmiaru
'     pola tekstowego. Może przyjmować jedną z predefiniowanych stałych:
'     dbBinary, dbBoolean, dbByte, dbCurrency, dbDate, dbDecimal, dbDouble, dbGUID,
'			dbInteger, dbLong, dbMemo, dbSingle, dbText, dbTime.
'   lSize
'     dla pola tekstowego (dbText) określa w bajtach maksymalny rozmiar pola sFieldName.
'     Argument ten jest ignorowany dla pól numerycznych i pól o stałej szerokości.
'     Dla wartości domyślnej lSize = 0 pola tekstowego, przyjmowana jest wartość domyślna
'     rozmiaru pola (maksymalnie 255 bajtów).
'   fRequired
'     argument opcjonalny określający, czy obiekt Field może zawierać wartości Null.
'     Dla wartości domyślnej fRequired = True, pole jest wymagane (nie może zawierać
'     wartości Null)
'   fAllowZeroLength
'     argument opcjonalny określający, czy dopuszczalne jest ustawienie ciągu
'     o długości zerowej ("") dla
'     właściwości Value obiektu Field o typie danych Text lub Memo.
'     Dla wartości domyślnej fAllowZeroLength = False, pole jest wymagane
'     (nie może zawierać wartości Null)
' zwraca:
'   Przy powodzeniu zwraca True
' autor: Zbigniew Bratko
' data: 30.03.2018
'=============================================================================================
Public Function terytCreateField( _
                           sFieldName As String, _
                           iType As Long, _
                  Optional lSize As Integer = 0, _
                  Optional fRequired As Boolean = True, _
                  Optional fAllowZeroLength As Boolean = False) As Boolean

	If iType = dbText And lSize > 0 Then
		' pole typu tekstowego o określonym rozmiarze
		Set m_fld = m_tdf.CreateField(sFieldName, iType, lSize)
	Else
		' pole typu tekstowego o domyślnym rozmiarze
		Set m_fld = m_tdf.CreateField(sFieldName, iType)
	End If

	' ustaw właściwość Required i AllowZeroLength obiektu Field (m_fld)
	With m_fld
		.Required = fRequired
		.AllowZeroLength = fAllowZeroLength
	End With

	'dołącz utworzony obiekt Field (m_fld) do kolekcji Fields obiektu TableDef (m_tdf)
	m_tdf.Fields.Append m_fld

	terytCreateField = True

End Function

' Metoda terytAppendTable(...) dołącza utworzony obiekt TableDef (m_tdf)
' do kolekcji TableDefs obiektu Database (m_dbs)
Public Function terytAppendTable() As Boolean

  m_dbs.TableDefs.Append m_tdf
  terytAppendTable = True

End Function

' Metoda terytCreateIndex(...) tworzy nowy obiekt Index typu Podstawowy,
' Unikatowy (bez duplikatów) lub Indeks (duplikaty OK). Utworzony indeks dołącza
' do kolekcji Indexes obiektu TableDef (m_tdf)
' argumenty:
'   sFieldName
'     nazwa pola, które ma być indeksowane
'   fPrimary
'     argument opcjonalny określający, czy indeks ma być indeksem (kluczem) podstawowym
'   fUnique
'     argument opcjonalny określający, czy indeks ma być indeksem unikatowym (bez duplikatów)
' zwraca:
'   Przy powodzeniu zwraca True
' autor: Zbigniew Bratko
' data: 30.03.2018
'=============================================================================================
Public Function terytCreateIndex( _
                         sFieldName As String, _
                Optional fPrimary As Boolean = False, _
                Optional fUnique As Boolean = False) As Boolean

Dim idx As DAO.Index
Dim sPrefixIndex As String

	' ustaw prefiks nazwy indeksu
	If fPrimary Then
		sPrefixIndex = "Primary_"
	ElseIf fUnique Then
		sPrefixIndex = "Unique_"
	Else
		sPrefixIndex = "Index_"
	End If
	sPrefixIndex = sPrefixIndex & m_tdf.Name

	' utwórz nowy indeks
	Set idx = m_tdf.CreateIndex(sPrefixIndex & "_" & sFieldName)

	With idx
		'dołącz obiekt Field do kolekcji Fields obiektu Index (idx)
		.Fields.Append .CreateField(sFieldName)
		' jeżeli indeks Podstawowy (klucz podstawowy)
		If fPrimary Then .Primary = fPrimary
		' jeżeli indeks Unikatowy (bez duplikatów)
		If fUnique Then .Unique = fUnique
		' jeżeli oba warunki nie, to utworzony zostanie indeks (Duplikaty OK)
	End With

	' dołącz nowy obiekt Index (idx) do kolekcji Indexes obiektu TableDef (m_tdf)
	m_tdf.Indexes.Append idx

	terytCreateIndex = True

End Function

' Metoda terytCreateIndexMulti(...) tworzy nowy, wielopolowy obiekt Index typu Podstawowy,
' Unikatowy (bez duplikatów) lub Indeks (duplikaty OK). Utworzony indeks dołącza
' do kolekcji Indexes obiektu TableDef (m_tdf)
' argumenty:
'   sFieldName
'     argument obowiązkowy, nazwa pierwszego pola, które ma być indeksowane
'   sFieldName1, sFieldName2,
'     argument opcjonalny, określający nazwę drugiego i trzeciego pola indeksu wielopolowego,
'     jeżeli oba opcjonalne argumenty będą puste utworzony zostanie indeks pojedynczy.
'   fPrimary
'     argument opcjonalny określający, czy indeks ma być indeksem (kluczem) podstawowym
'   fUnique
'     argument opcjonalny określający, czy indeks ma być indeksem unikatowym (bez duplikatów)
' zwraca:
'   Przy powodzeniu zwraca True
' autor: Zbigniew Bratko
' data: 30.03.2018
'=============================================================================================
Public Function terytCreateIndexMulti( _
                         sFieldName As String, _
                Optional sFieldName1 As String = "", _
                Optional sFieldName2 As String = "", _
                Optional fPrimary As Boolean = False, _
                Optional fUnique As Boolean = False) As Boolean


Dim idx           As DAO.Index
Dim sIndexName    As String
Dim sFieldNames() As String
Dim i             As Long

	' ustaw prefiks nazwy indeksu
	If fPrimary Then
		sIndexName = "Primary_"
	ElseIf fUnique Then
		sIndexName = "Unique_"
	Else
		sIndexName = "Index_"
	End If
	sIndexName = sIndexName & m_tdf.Name

	' zapisz nazwy pól w tablicy
	ReDim sFieldNames(0)
	sFieldNames(0) = sFieldName

	If Len(sFieldName1) > 0 Then
		ReDim Preserve sFieldNames(0 To 1)
		sFieldNames(1) = sFieldName1
	End If

	If Len(sFieldName2) > 0 Then
		ReDim Preserve sFieldNames(0 To 2)
		sFieldNames(2) = sFieldName2
	End If

	' utwórz nazwę indeksu
	For i = LBound(sFieldNames) To UBound(sFieldNames)
		sIndexName = sIndexName & "_" & sFieldNames(i)
	Next

	' utwórz nowy indeks
	Set idx = m_tdf.CreateIndex(sIndexName)

	With idx
		'dołącz obiekty Field do kolekcji Fields obiektu Index (idx)
		For i = LBound(sFieldNames) To UBound(sFieldNames)
			.Fields.Append .CreateField(sFieldNames(i))
		Next

		' jeżeli indeks Podstawowy (klucz podstawowy)
		If fPrimary Then
			.Primary = fPrimary
		Else
			' jeżeli indeks Unikatowy (bez duplikatów)
			If fUnique Then .Unique = fUnique
			' jeżeli oba warunki nie, to utworzony zostanie indeks (Duplikaty OK)
		End If
	End With

	' dołącz nowy obiekt Index (idx) do kolekcji Indexes obiektu TableDef (m_tdf)
	m_tdf.Indexes.Append idx

	terytCreateIndexMulti = True

End Function

' Metoda terytCreateRelation(...) tworzy obiekt Relation pomiędzy polem sPrimaryFieldName
' tabeli podstawowej sPrimaryTableName i polem sForeignFieldName tabeli obcej sForeignTableName
' zapewniając integralność referencyjną. Następnie tworzy obiekt Field
' kolekcji Fields należącej do nowego  obiektu Relation i dołącza obiekt Field
' do kolekcji Fields obiektu Relation.
' Ustawia atrybuty, wymuszające integralność referencyjną UpdateCascade
' (kaskadowo aktualizuj pola pokrewne) lub (i) RelationDeleteCascade
' (kaskadowo usuń rekordy pokrewne) tak by zmiany, lub usuwanie rekordów
' z powiązanych pól zostały wykonane z zachowaniem reguł. Utworzony obiekt
' Relation dołączany jest do kolekcji Relations obiektu Database (m_dbs).
' argumenty:
'   sPrimaryTableName
'     nazwa tabeli podstawowej
'   sPrimaryFieldName
'     nazwa pola tabeli podstawowej
'   sForeignTableName
'     nazwa tabeli obcej
'   sForeignFieldName
'     nazwa pola tabeli obcej
'   fUpdateCascade
'     argument opcjonalny określający, czy uaktualnianie będzie wykonywane kaskadowo.
'     Jeżeli użytkownik zmieni zawartość powiązanych ze sobą pól (pól klucza
'     głównego w tabeli nadrzędnej), zmiana ta będzie uwzględniona we wszystkich
'     powiązanych tabelach.
'   fDeleteCascade
'     argument opcjonalny określający, czy usuwanie będzie wykonywane kaskadowo.
'     Jeżeli użytkownik usunie rekord nadrzędny, to zostaną usunięte
'     wszystkie powiązane rekordy pokrewne .
' zwraca:
'   Przy powodzeniu zwraca True
' autor: Zbigniew Bratko
' data: 30.03.2018
'=============================================================================================
Public Function terytCreateRelation( _
                              sPrimaryTableName As String, _
                              sPrimaryFieldName As String, _
                              sForeignTableName As String, _
                              sForeignFieldName As String, _
                     Optional fUpdateCascade As Boolean = False, _
                     Optional fDeleteCascade As Boolean = False) As Boolean

Dim rel As DAO.Relation
Dim fld As DAO.Field
Dim sRelationName As String
Dim lCascade As Long

	' utwórz unikatową nazwę relacji
	sRelationName = sPrimaryTableName & "_" & sPrimaryFieldName & "_" & _
									sForeignTableName & "_" & sForeignFieldName

	' utwórz nowy obiekt Relation dla tabeli podstawowej i obcej
	Set rel = m_dbs.CreateRelation(sRelationName, sPrimaryTableName, sForeignTableName)

	' ustaw atrybuty, wymuszające integralność referencyjną
	rel.Attributes = IIf(fUpdateCascade = True, dbRelationUpdateCascade, 0) Or _
									 IIf(fDeleteCascade = True, dbRelationDeleteCascade, 0)

	' utwórz obiekt Field kolekcji Fields
	' należącej do nowego obiektu Relation
	Set fld = rel.CreateField(sPrimaryFieldName)

	' ustaw właściwości ForeignName obiektu Field tabeli obcej,
	' który odpowiada polu w tabeli podstawowej
	fld.ForeignName = sForeignFieldName

	' dołącz obiekt Field do kolekcji Fields nowego obiektu Relation
	rel.Fields.Append fld
	' dołącz nowy obiekt Relation do kolekcji Relations obiektu Database (m_dbs)
	m_dbs.Relations.Append rel

	terytCreateRelation = True

End Function

' usuwa wszystkie relacje w obiekcie Database m_dbs
Public Function terytDeleteAllRelations() As Boolean
Dim i As Long

	With m_dbs
		' zacznij od końca usuwać obiekty Relation z kolekcji
		' Relations obiektu Database (m_dbs_
		For i = m_dbs.Relations.Count - 1 To 0 Step -1
			.Relations.Delete .Relations(i).Name
		Next
	End With

End Function

' usuwa tabelę sTableName. Przed usunięciem tabeli sprawdza, czy usuwana tabela jest
' powiązana relacjami z innymi tabelami. Jeżeli tak, to usuwa wszystkie relacje, którymi
' powiązana jest tabela sTableName z innymi tabelami w obiekcie Database (m_dbs).
Public Function terytDeleteTable(sTableName As String) As Boolean
Dim rel As DAO.Relation

	If Not prpTableExists(sTableName) Then
		' tabela nie istnieje, nie ma co usuwać
		terytDeleteTable = True
		Exit Function
	End If

	' sprawdź, czy usuwana tabela jest powiązana relacjami
	For Each rel In m_dbs.Relations
		With rel
			If StrComp(.Table, sTableName, vbTextCompare) = 0 Or _
				 StrComp(.ForeignTable, sTableName, vbTextCompare) = 0 Then
			' usuń istniejącą relację
			m_dbs.Relations.Delete rel.Name
			End If
		End With
	Next

	' usuń tabelę
	m_dbs.TableDefs.Delete sTableName

	terytDeleteTable = True

End Function

' sprawdza w kolekcji TableDefs obiektu Database (m_dbs), czy tabela istnieje
Public Property Get prpTableExists(sTableName As String) As Boolean
Dim dbs As DAO.Database

	' pułapkuj błąd wykonania dla nie istniejącej tabeli
	On Error Resume Next
			' pobierz nazwę obiektu TableDef z kolekcji TableDefs
			prpTableExists = CBool(Len(m_dbs.TableDefs(sTableName).Name))
	On Error GoTo 0

End Property


Zastosowanie metod klasy clsTeryt

Wykorzystamy większość metod klasy clsTeryt by utworzyć wszystkie potrzebne tabele na przyjęcie danych z Plików pełnych rejestru TERYT. Po utworzeniu tabel za pomocą metody .terytCreateRelation(...) utworzone zostaną wszystkie potrzebne relacje pomiędzy utworzonymi tabelami.

Private Sub btnCreateTable_Click()
On Error GoTo Err_Handler
Dim cls As clsTeryt

Set cls = New clsTeryt
	With cls
		.terytDeleteTable "tblWMRodz"
			.terytCreateTable "tblWMRodz"
			.terytCreateField "ID_RM", dbText, 2
			.terytCreateField "tNazwa_RM", dbText, 100
			.terytCreateField "tStan_Na", dbText, 10
		.terytAppendTable
		' utwórz Indeks Primary
		.terytCreateIndex "ID_RM", True
		'==================================================
		.terytDeleteTable "tblRodz_Gmi"
		.terytCreateTable "tblRodz_Gmi"
			.terytCreateField "ID_RG", dbText, 1
			.terytCreateField "tNazwa_RG", dbText, 100
			' dodatkowe, skrótowe pole opisowe
			.terytCreateField "tSkrot_RG", dbText, 21
		.terytAppendTable
		' utwórz Indeks Primary
		.terytCreateIndex "ID_RG", True
		'==================================================
		.terytDeleteTable "tblWojewodztwa"
		.terytCreateTable "tblWojewodztwa"
			.terytCreateField "ID_Woj", dbText, 2
			.terytCreateField "tWojewodztwo", dbText, 100
			.terytCreateField "tNazwa_Dod", dbText, 50
		.terytAppendTable
		' utwórz Indeks Primary
		.terytCreateIndex "ID_Woj", True
		'==================================================
		.terytDeleteTable "tblPowiaty"
		.terytCreateTable "tblPowiaty"
			.terytCreateField "ID_Pow", dbText, 4
			.terytCreateField "Id_Woj", dbText, 2
			.terytCreateField "tPowiat", dbText, 100
			.terytCreateField "tNazwa_Dod", dbText, 50
		.terytAppendTable
		' utwórz Indeks Primary
		.terytCreateIndex "ID_Pow", True
		' utwórz Indeks (duplikaty OK)
		.terytCreateIndex "Id_Woj"
		'==================================================
		.terytDeleteTable "tblTERC_Gminy"
		.terytCreateTable "tblTERC_Gminy"
			.terytCreateField "ID_Gmi", dbText, 7
			.terytCreateField "Id_Pow", dbText, 4
			.terytCreateField "Id_RG", dbText, 1
			.terytCreateField "tNazwa", dbText, 100
			.terytCreateField "tNazwa_Dod", dbText, 50
			.terytCreateField "tStan_Na", dbText, 10
		.terytAppendTable
		' utwórz Indeks Primary
		.terytCreateIndex "ID_Gmi", True
		' utwórz Indeksy (duplikaty OK)
		.terytCreateIndex "Id_Pow"
		.terytCreateIndex "Id_RG"
		'==================================================
		.terytDeleteTable "tblSIMC_Miejscowosci"
		.terytCreateTable "tblSIMC_Miejscowosci"
			.terytCreateField "ID_Sym", dbText, 7
			.terytCreateField "Id_Gmi", dbText, 7
			.terytCreateField "Id_RM", dbText, 2
			.terytCreateField "tMZ", dbText, 1
			.terytCreateField "tNazwa", dbText, 100
			.terytCreateField "tSymPod", dbText, 7
			.terytCreateField "tStan_Na", dbText, 10
		.terytAppendTable
		' utwórz Indeks Primary
		.terytCreateIndex "ID_Sym", True
		' utwórz Indeksy (duplikaty OK)
		.terytCreateIndex "Id_Gmi"
		.terytCreateIndex "Id_RM"
		.terytCreateIndex "tNazwa"
		'==================================================
		.terytDeleteTable "tblULIC_Nazwy"
		.terytCreateTable "tblULIC_Nazwy"
			.terytCreateField "ID_SymUl", dbText, 5
			.terytCreateField "tCecha", dbText, 5
			.terytCreateField "tNazwa_1", dbText, 100
			.terytCreateField "tNazwa_2", dbText, 100, False
		.terytAppendTable
		' utwórz Indeks Primary
		.terytCreateIndex "ID_SymUl", True
		' utwórz Indeksy (duplikaty OK)
		.terytCreateIndex "tCecha"
		.terytCreateIndex "tNazwa_1"
		'==================================================
		.terytDeleteTable "tblULIC_Ulice"
		.terytCreateTable "tblULIC_Ulice"
			.terytCreateField "Id_Sym", dbText, 7
			.terytCreateField "Id_SymUl", dbText, 5
			.terytCreateField "tStan_Na", dbText, 10
		.terytAppendTable
		' utwórz Indeksy (duplikaty OK)
		.terytCreateIndex "Id_Sym"
		.terytCreateIndex "Id_SymUl"

		' utwórz dwupolowy Indeks Primary
		.terytCreateIndexMulti "Id_Sym", "Id_SymUl", "", True

		' utwórz Relacje pomiędzy tabelami
		.terytCreateRelation "tblWojewodztwa", "ID_Woj", "tblPowiaty", "Id_Woj", True, True
		.terytCreateRelation "tblPowiaty", "ID_Pow", "tblTERC_Gminy", "Id_Pow", True, True
		.terytCreateRelation "tblTERC_Gminy", "ID_GMI", "tblSIMC_Miejscowosci", "Id_GMI", True, True
		.terytCreateRelation "tblWMRodz", "ID_RM", "tblSIMC_Miejscowosci", "Id_Rm", True, True
		.terytCreateRelation "tblRodz_Gmi", "ID_RG", "tblTERC_Gminy", "Id_RG", True, True
		.terytCreateRelation "tblSIMC_Miejscowosci", "ID_Sym", "tblULIC_Ulice", "Id_Sym", True, True
		.terytCreateRelation "tblULIC_Nazwy", "ID_SymUl", "tblULIC_Ulice", "Id_SymUl", True, True
	End With

' otwórz okno Relacje
DoCmd.RunCommand acCmdRelationships
' odśwież okno bazy
Application.RefreshDatabaseWindow

Exit_Here:
	' zniszcz zmienne obiektowe
	Set cls = Nothing
	Exit Sub
Err_Handler:
	MsgBox "Błąd nr " & Err.Number & vbNewLine & _
					Err.Description
	Resume Exit_Here
End Sub

Relacje. Brak relacji
Widok okna „Relacje” po utworzeniu wszystkich tabel. Tabele połączone relacjami
Widok okna „Relacje” po utworzeniu wszystkich potrzebnych Relacji.

Poniżej znajduje się link do przykładowej bazy, w której przy wykorzystaniu metody klasy clsTeryt, utworzone zostaną wszystkie potrzebne tabele i relacje pomiędzy tabelami. Do tak przygotowanych tabel będzie możliwe pobranie wszystkich danych ze zbioru "TERCPlików pełnych rejestru TERYT.

Ale o tym na następnej stronie Zapis danych z plików pełnych rejestru TERYT.