Access

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

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

ULIC (Centralny katalog ulic)

• Stan na dzień 03 marca 2018 roku

Centralny katalog ulic ULIC prowadzony jest w ramach systemu identyfikacji adresowej ulic, nieruchomości, budynków i mieszkań NOBC, który jest składnikiem Krajowego Rejestru Urzędowego Podziału Terytorialnego Kraju TERYT. Obejmuje nazwy ulic zgodne z brzmieniem uchwał o ich nadaniu oraz ich identyfikatory. Pozwala na lokalizację ulicy w danym mieście i gminie, a na terenach wiejskich również na lokalizację w konkretnej miejscowości wiejskiej gminy. Przetwarzanie zbioru z systemu ULIC następuje łącznie ze zbiorem z systemu TERC (zawierającym identyfikatory i nazwy jednostek podziału terytorialnego) i zbiorem SIMC (zawierającym identyfikatory i nazwy miejscowości).

Na stronach: Zbiór SIMC oraz Zbiór TERC oraz Zbiór WMRODZ omówiona została struktura plików: SIMC.xml, TERC.xml oraz WMRODZ.xml oraz sposób zapisu danych zawartych w tych plikach do tabel MS Access.

Do przetworzenia pozostał ostatni, ogólnie dostępny plik z rejestru TERYT. Jest nim plik ULIC.xml zawierający zbiór identyfikatorów i nazw ulic. Plik ten, jak i pozostałe, możemy pobrać ze strony Głównego Urzędu Statystycznego (GUS) Pliki pełne rejestru TERYT.

Centralny katalog ulic ULIC zawiera:
• przynależność miejscowości do gminy, powiatu i województwa,
• identyfikator miejscowości umożliwiający lokalizację ulicy w miejscowości (wsi),
• identyfikator ulicy,
• główny człon nazwy ulicy, np. nazwisko,
• dodatkowy człon nazwy ulicy, np. imię,
• rodzaj ulicy, np. ulica, skwer, aleja, plac, itp.

Przetwarzanie pliku ULIC.xml

Plik ULIC.xml zawiera zbiór identyfikatorów i nazw ulic. Plik ten, został pobrany do bieżącego katalogu bazy danych, do folderu o nazwie TERYT. Na stronie Opis struktury zbioru ULIC możemy zapoznać się ze strukturą tego pliku.

Opis struktury zbioru ULIC
WOJ - symbol województwa - 2 zn. C
POW - symbol powiatu - 2 zn. C
GMI - symbol gminy - 2 zn. C
RODZ_GMI (*) - symbol rodzaju jednostki - 1 zn. C
 
1 - gmina miejska,
2 - gmina wiejska,
3 - gmina miejsko-wiejska,
4 - miasto w gminie miejsko-wiejskiej,
5 - obszar wiejski w gminie miejsko-wiejskiej,
8 - dzielnica w m.st. Warszawa,
9 - delegatury w gminach miejskich
SYM - identyfikator miejscowości - 7 zn. C
SYM_UL - identyfikator ulicy - 5 zn. C
CECHA - określenie rodzaju ulicy - 5 zn. C
(ul., al., pl., skwer, bulw., rondo, park, rynek, szosa, droga, os., ogród, wyspa, wyb., inne)
NAZWA_1 - część nazwy począwszy od słowa, które decyduje o pozycji ulicy w układzie alfabetycznym, - 100 zn. C
NAZWA_2 - pozostała część nazwy lub pole puste - 100 zn. C (**)
STAN_NA - data aktualizacji danych w podsystemie ULIC w formacie RRRR-MM-DD - 10 zn. C

(*)   - w opisie struktury zbioru TERC element nazwany jest: RODZ.
(**) - w przypadku, gdy pole Nazwa_2 nie jest puste, aby otrzymać nazwę ulicy w pełnym brzmieniu,
         człony nazwy należy ułożyć w kolejności: Nazwa_2, Nazwa_1.

Struktura pliku ULIC.xml

Ponieważ struktura pliku ULIC.xml została zmieniona, funkcja przetwarzający plik ULIC.xml musiała zostać dostosowana do obowiązującej struktury pliku (nazw zmienionych elementów) przetwarzanego pliku ULIC.xml. Tabele tblULIC_NazwytblULIC_Ulice pozostały bez zmian, ponieważ nie zostały zmienione wielkości elementów.

Plik ULIC.xml zawiera 267 028 elementów <row>, z których każdy z nich zawiera 10 elementów <col>, co daje 2 670 280 pojedynczych elementów. Za wyjątkiem elementu <"NAZWA_2">, który może być pusty, wszystkie pozostałe elementy zawierają dane (nie są puste).

Poniżej struktura starego pliku ULIC.xml z dnia 2015-09-25 i struktura aktualnego pliku ULIC.xml, dla dwóch pierwszych elementów <row> zbioru ULIC.xml.

<?xml version="1.0" encoding="UTF-8"?>
<teryt>
	<catalog name="ULIC" type="all" date="2015-09-25">
		<row>
			<col name="WOJ">02</col>
			<col name="POW">22</col>
			<col name="GMI">02</col>
			<col name="RODZ_GMI">2</col>
			<col name="SYM">0882939</col>
			<col name="SYM_UL">26171</col>
			<col name="CECHA">ul.</col>
			<col name="NAZWA_1">Zjazdowa</col>
			<col name="NAZWA_2"/>									
			<col name="STAN_NA">2015-09-25</col>
		</row>
		<row>
			<col name="WOJ">02</col>
			<col name="POW">22</col>
			<col name="GMI">03</col>
			<col name="RODZ_GMI">4</col>
			<col name="SYM">0987466</col>
			<col name="SYM_UL">00285</col>
			<col name="CECHA">ul.</col>
			<col name="NAZWA_1">Andersa</col>
			<col name="NAZWA_2">gen. Władysława </col>
			<col name="STAN_NA">2015-09-25</col>
		</row>

		

	</catalog>
</teryt>
<?xml version="1.0" encoding="utf-8"?>
<ULIC>
  <catalog name="ULIC" type="ALL" date="2018-03-01">
    <row>
      <WOJ>02</WOJ>
      <POW>01</POW>
      <GMI>01</GMI>
      <RODZ_GMI>1</RODZ_GMI>
      <SYM>0935989</SYM>
      <SYM_UL>00432</SYM_UL>
      <CECHA>ul.</CECHA>
      <NAZWA_1>Armii Krajowej</NAZWA_1>
      <NAZWA_2>									
      </NAZWA_2>								
      <STAN_NA>2018-03-01</STAN_NA>
    </row>
    <row>
      <WOJ>02</WOJ>
      <POW>01</POW>
      <GMI>01</GMI>
      <RODZ_GMI>1</RODZ_GMI>
      <SYM>0935989</SYM>
      <SYM_UL>00891</SYM_UL>
      <CECHA>ul.</CECHA>
      <NAZWA_1>Stefana Batorego</NAZWA_1>
      <NAZWA_2>
      </NAZWA_2>
      <STAN_NA>2018-03-01</STAN_NA>
    </row>

		

	</catalog>
</ULIC>

Struktura tabeli tblULIC_Nazwy.


Znając strukturę zbioru ULIC musimy utworzyć dwie tabelę na przyjęcie danych z pliku ULIC.xml. Struktura tabel przedstawiona jest poniżej:

Tabela tblULIC_Nazwy - struktura
Nazwa pola*) Typ Rozmiar**) Wymagane Zerowa długość Uwagi
ID_SymUl Tekst 5 Tak Nie PrimaryKey
tCecha Tekst 5 Tak Nie Indeks. Duplikaty (OK)
tNazwa_1 Tekst 100 Tak Nie Indeks. Duplikaty (OK)
tNazwa_2 Tekst 100 Nie Nie  
Zawiera zbiór niepowtarzających się nazw ulic(zgodne z brzmieniem uchwał o ich nadaniu) oraz ich identyfikatory, utworzony przez alfabetyczne ułożenie nazw ulic w ramach całego kraju.

Tworzenie tabeli tblULIC_Nazwy.

Tabelę tblULIC_Nazwy możemy utworzyć korzystając z metod klasy clsTeryt opisanej na stronie: Klasa clsTeryt

Dim clsULIC As clsTeryt
  Set clsULIC = New clsTeryt
    With clsULIC
      .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"
    End With
  Set clsULIC = Nothing

Struktura tabeli tblULIC_Ulice.


Tabela tblULIC_Ulice - struktura
Nazwa pola*) Typ Rozmiar**) Wymagane Zerowa długość Uwagi
Id_Sym Tekst 7 Tak Nie  PrimaryKey
Id_SymUl Tekst 5 Tak Nie
tStan_Na Tekst 10 Tak Nie  
Elementy <WOJ>,<POW>,<GMI>,<RODZ_GMI> ze zbioru ULIC nie są potrzebne, ponieważ pole <Id_Sym> jednoznacznie określa miejscowość i jej położenie terytorialne w tabeli tblSIMC_Miejscowosci.

Tworzenie tabeli tblULIC_Ulice.

Tabelę tblULIC_Ulice możemy utworzyć korzystając z metod klasy clsTeryt opisanej na stronie: Klasa clsTeryt

Dim clsULIC_ulic As clsTeryt
  Set clsULIC_ulic = New clsTeryt
    With clsULIC_ulic
      .terytDeleteTable "tblULIC_Ulice"
      .terytCreateTable "tblULIC_Ulice"
        .terytCreateField "Id_Sym", dbText, 7
        .terytCreateField "Id_SymUl", dbText, 5
        .terytCreateField "tStan_Na", dbText, 10
      .terytAppendTable
      ' utwórz Indeks Primary
      .terytCreateIndex "Id_Sym", True
    End With
  Set clsULIC_ulic = Nothing
Uwagi dodatkowe.
Dotyczą wszystkich tabel na tej stronie.
*)   - Dla pola będącego kluczem głównym, stosuję prefiks „ID_”,
      - Klucz obcy zawsze poprzedzam prefiksem „Id_”
      - Nazwy pól nie będące kluczem głównym i kluczem obcym poprzedzam prefiksem „t
**) Minimalna długość pola. Można użyć większego rozmiaru pola.
       MS Access nie dopełnia pól tekstowych do zadeklarowanej długości.

Skoro mamy utworzone dwie nowe tabele, to możemy pobrać dane z pliku ULIC.xml i zapisać je w tabeli tblULIC_Nazwy oraz tabeli tblULIC_Ulice. Jak to zrobić ? Tym razem nie jest to takie proste.
Dokonując niewielkich zmian w kodzie, funkcję fXmlSimcToTable_DOM (...) możemy ją dostosować do przetwarzania pliku ULIC.xml.

 
Public Function fXmlUlicToTable_DOM( _
                  ByVal sFileXmlPath As String, _
                  ByVal sTblUlic As String, _
                  ByVal sTblUlic_Nazwy As String) As Boolean
#If pbl_fEarly = True Then
  Dim xmlDoc          As MSXML2.DOMDocument60
  Dim oNode           As MSXML2.IXMLDOMNode
#Else
  Dim xmlDoc          As Object
  Dim oNode           As Object
#End If
Dim sXPath          As String

Dim dbs             As DAO.Database
Dim rstUlice        As DAO.Recordset
Dim rstNazwy        As DAO.Recordset

Const cParser_XML   As String = "MSXML2.DOMDocument"
Const cModule_Name  As String = "Function fXmlUlicToTable_DOM (...)"
Dim i As Long

On Error GoTo Err_Handler

  ' Utwórz obiekt analizatora składni XML (parsera XML)
  #If pbl_fEarly = True Then
    ' Wczesne wiązanie (early binding)
    Set xmlDoc = New MSXML2.DOMDocument60
  #Else
    ' Późne wiązanie (late binding)
    Set xmlDoc = CreateObject("MSXML2.DOMDocument")
  #End If

  With xmlDoc
    .Load (sFileXmlPath)
    ' sprawdź poprawność wczytanego XML'a
    If (.parseError.errorCode <> 0) Then
      Err.Raise .parseError.errorCode, cParser_XML, .parseError.reason
    End If
    ' utwórz adres do elementów <row>
    sXPath = "/ULIC/catalog/row"
    ' utwórz zmienną obiektową  odwołującą się do pojedynczego elementu <row>
    Set oNode = .selectSingleNode(sXPath)
  End With

  Set dbs = CurrentDb
  Set rstUlice = dbs.OpenRecordset(sTblUlic, dbOpenDynaset, dbAppendOnly)
  Set rstNazwy = dbs.OpenRecordset(sTblUlic_Nazwy, dbOpenDynaset, dbAppendOnly)

  Do Until oNode Is Nothing
    With oNode.childNodes
      ' sprawdź, czy ulica znajduje się w tabeli
      rstNazwy.FindFirst ("[ID_SymUl]='" & .Item(5).Text & "'")
      ' jeżeli nie, to zapisz dane ulicy
      If rstNazwy.NoMatch Then
        rstNazwy.AddNew
          rstNazwy!Id_SymUl = .Item(5).Text
          rstNazwy!tCecha = .Item(6).Text
          rstNazwy!tNazwa_1 = .Item(7).Text
          ' jeżeli element "NAZWA_2" nie jest pusty, to go zapisz
          If Len(.Item(8).Text) > 0 Then
            rstNazwy!tNazwa_2 = .Item(8).Text
          End If
        rstNazwy.Update
      End If

      rstUlice.AddNew
        rstUlice!Id_Sym = .Item(4).Text
        rstUlice!Id_SymUl = .Item(5).Text
        rstUlice!tStan_Na = .Item(9).Text
      rstUlice.Update
    End With
    Set oNode = oNode.nextSibling
  Loop

  fXmlUlicToTable_DOM = True

Exit_Here:
    ' zniszcz zmienne obiektowe
    If Not (rstNazwy Is Nothing) Then rstNazwy.Close
    If Not (rstUlice Is Nothing) Then rstUlice.Close
    Set rstNazwy = Nothing
    Set rstUlice = Nothing
    Set dbs = Nothing
    Set xmlDoc = Nothing
  Exit Function

Err_Handler:
  MsgBox "Błąd nr " & Err.Number & vbNewLine & _
          Err.Description & vbNewLine & _
          "Źródło: Baza Miejscowości TERYT" & vbNewLine & _
          "Moduł: " & cModule_Name
  Resume Exit_Here

End Function


Czas przetwarzania przez funkcję fXmlULICToTable_DOM (...) pliku ULIC.xml, wielkości 80 MB, zawierającego 267 028 elementów <row> z których każdy zawiera 10 elementów <col> (w sumie 2 670 280 elementarnych danych) wynosi:

  • wczesne wiązanie
    wczytanie pliku ULIC.xml do pamięci 22,3 sek. przetwarzanie i zapis do tabeli 10 000 rekordów pliku: 507 sek. co dla 26 000 rekordów daje w przybliżeniu: 507 x 26 = 13 196 (ok. 3,6 godz.)
  • późne wiązanie
    wczytanie pliku ULIC.xml do pamięci 27,8 sek. przetwarzanie pliku i zapis do tabel: 13 762 sek. (ok. 3,8 godz.)

Trzeba przyznać, że są to makabrycznie długie czasy przetwarzania pliku ULIC.xml. Wyniki mówią same za siebie. Korzystanie z  obiektu MSXML2.DOMDocument jest tak przeraźliwie wolne, że wniosek może być tylko jeden. Metoda ta w przypadku dużych plików *.xml nie zdaje egzaminu i należy z niej zrezygnować.

Zobaczmy, jak sprawdzi się metoda mieszana: „późne wiązanie” + VBA. Po wstępnym przekształceniu do naszych potrzeb funkcji fXmlSimcToTable_VBA (...) przetwarzającej plik SIMC.xml, zobaczymy czy metoda mieszana spełni nasze oczekiwania podczas przetwarzania pliku ULIC.xml.

Przetestujemy dwie pierwsze kluczowe instrukcje:
• wczytanie pliku ULIC.xml metodą .loadXML obiektu MSXML2.DOMDocument
• rozdzielenie wczytanego tekstu .xml na elementy (linie) względem znaku końca linii, za pomocą funkcji Split(...)
 
  ' Utwórz obiekt analizatora składni XML (parsera XML)
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")
    With xmlDoc
      .Load (sFileXmlPath)

      ' sprawdź poprawność wczytanego XML'a
      If (.parseError.errorCode <> 0) Then
        Err.Raise .parseError.errorCode, cParser_XML, .parseError.reason
      End If
      ' rozdziel wczytany tekst .xml na elementy (linie) względem znaku końca linii
      aLines() = Split(.xml, vbNewLine, , vbBinaryCompare)

    End With
  ' obiekt "MSXML2.DOMDocument" jest już nam niepotrzebny
  Set xmlDoc = Nothing

	' dalsze instrukcje
 
I wszystko by było dobrze, gdyby nie nastąpiła zmiana struktury pliku ULIC.xml i sposób zapisu pustego elementu Pusty element [NAZWA] w pliku ULIC.xml jest zapisany w postaci:
   <NAZWA_2>
   <NAZWA_2 />
Ale gdy wrócimy do przetwarzanego już wcześniej pliku TERC.xml, to w pliku tym puste elementy zapisywanę są w postaci:
   <GMI />
   <RODZ />

W wyniku takiego zapisu instrukcja:
aLines = Split(.xml, vbNewLine, , vbBinaryCompare)
dla pustego elementu [NAZWA] zwróci o jeden element więcej w  tablicy aLines().

Rozwiązanie niby jest proste. Użyć funkcji Replace(...) by zamienić dwulinijkowy pusty element na jednolinijkowy:

  With xmlDoc
    .Load (sFileXmlPath
      sStr = Replace(.xml, "<NAZWA_2>" & vbNewLine, "<NAZWA_2>", 1, -1, vbBinaryCompare)
      aLines = Split(sStr, vbNewLine, , vbBinaryCompare)

Proste jak precelek. Tyle tylko, że zmienna znakowa .xml zawiera dane wielkości ok. 80 MB i niektóre Accessy się buntują. Access 2007, 2010 i 2016 w 64-bitowym środowisku Windows 7 działają powolutku, ale wszystko jest OK.
Ale w Windows 10 i MS Access 2010 mogą być same niespodzianki.

Przepełnienie pamięci  - plik ULIC.xml
Windows 10 i funkcja Replace w MS Access 2010 nie lubi dużych plików...

Nie jestem w stanie przeprowadzić testów dla Access 2007, 2010, 2016 w systemach operacyjnych Windows 7, Windows 8, Windows 10  i w środowisku 32-bit i 64-bit.
U mnie ... SOA#1

Dość narzekania. Ad rem


  • Dla pliku wielkości 80 MB funkcja Replace zazwyczaj daje sobie radę, ale tylko zazwyczaj. Więc wniosek jest prosty. Dla tak dużych ciągów znaków nie używać funkcji Replace.
  • Dla pliku wielkości 80 MB funkcja Split względem elementu <row> zazwyczaj daje sobie radę. Po zastosowaniu funkcji Split, dla każdego zwracanego elementu ponownie zastosować funkcję Split względem elementu "</".
    Potem jakieś tam Replace, Replace, Replace i może coś wyjdzie. Nie będzie to piękne, ale może skuteczne.
  • A za rok może dwa znowu będą walki z .xml-em.

Zmodyfikowana metoda rozdzielenia wczytanego tekstu .xml na elementy, za pomocą funkcji Split(...) polega na:

  • wczytaniu pliku ULIC.xml metodą .loadXML obiektu "MSXML2.DOMDocument"
  • rozdzielenie wczytanego tekstu .xml do tablicy aRows(), względem elementu <row>,
  • w pętli For i = LBound(aRows) + 1 To UBound(aRows)
    rozdzielenie każdego elementu tablicy aRows(i) do tablicy aCols(), względem elementu </
    i przetwarzanie kolejnych elementów tablicy aCols() za pomocą funkcji getTagValue by zapisać zwracane dane do tabel MS Access.

Skoro mamy utworzone dwie nowe tabele, to możemy pobrać dane z pliku ULIC.xml i zapisać je w tabeli tblULIC_Nazwy oraz tabeli tblULIC_Ulice. Jak to zrobić ? Po prostu skorzystać ze zmodyfikowanej starej funkcji:

Public Function fXmlUlicToTable_Split( _
			ByVal sFileXmlPath As String, _
			ByVal sTblUlic As String, _
			ByVal sTblUlic_Nazwy As String) As Boolean
Public Function fXmlUlicToTable_Split( _
                  ByVal sFileXmlPath As String, _
                  ByVal sTblUlic As String, _
                  ByVal sTblUlic_Nazwy As String) As Boolean

Dim xmlDoc          As Object
Dim aRows()         As String
Dim aCols()         As String
Dim sID_SymUl       As String
Dim sNAZWA_2        As String
Dim i               As Long

Dim dbs             As DAO.Database
Dim rstUlice        As DAO.Recordset
Dim rstNazwy        As DAO.Recordset

Const cParser_XML   As String = "MSXML2.DOMDocument"
Const cModule_Name  As String = "Function fXmlUlicToTable_Split (...)"

On Error GoTo Err_Handler

  ' Utwórz obiekt analizatora składni XML (parsera XML)
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .Load (sFileXmlPath)
    ' sprawdź poprawność wczytanego XML'a

    If (.parseError.errorCode <> 0) Then
      Err.Raise .parseError.errorCode, cParser_XML, .parseError.reason
    End If

      ' rozdziel wczytany .xml  względem oznaczenia początku elementu wiersza <row>
      aRows = Split(.xml, "<row>", , vbBinaryCompare)

    End With
  ' obiekt "MSXML2.DOMDocument" jest już nam niepotrzebny
  Set xmlDoc = Nothing

  Set dbs = CurrentDb
  Set rstUlice = dbs.OpenRecordset(sTblUlic, dbOpenDynaset, dbAppendOnly)
  Set rstNazwy = dbs.OpenRecordset(sTblUlic_Nazwy, dbOpenDynaset, dbAppendOnly)

    ' nie przetwarzaj pierwszego elementu
    For i = LBound(aRows) + 1 To UBound(aRows)
      ' rozdziel element aRows(i) na poszczególne kolumny do tablicy typu String
      aCols = Split(aRows(i), "</", , vbBinaryCompare)

      With rstNazwy
        sID_SymUl = getTagValue(aCols(5))
        ' sprawdź, czy ulica znajduje się w tabeli
        .FindFirst ("[ID_SymUl]='" & sID_SymUl & "'")
        ' jeżeli nie, to zapisz dane ulicy
        If .NoMatch Then
          .AddNew
            !Id_SymUl = sID_SymUl
            !tCecha = getTagValue(aCols(6))
            !tNazwa_1 = getTagValue(aCols(7))
            sNAZWA_2 = getTagValue(aCols(8))
            If Len(sNAZWA_2) > 0 Then !tNazwa_2 = sNAZWA_2
          .Update
        End If
      End With

      ' zapisz Id miejscowości i Id ulicy
      With rstUlice
         .AddNew
           !Id_Sym = getTagValue(aCols(4))
           !Id_SymUl = sID_SymUl
           !tStan_Na = getTagValue(aCols(9))
         .Update
      End With
    Next

  fXmlUlicToTable_Split = True

Exit_Here:
    ' zniszcz zmienne obiektowe
    If Not (rstNazwy Is Nothing) Then rstNazwy.Close
    If Not (rstUlice Is Nothing) Then rstUlice.Close
    Set rstNazwy = Nothing
    Set rstUlice = Nothing
    Set dbs = Nothing
    Set xmlDoc = Nothing
  Exit Function

Err_Handler:
  MsgBox "Błąd nr " & Err.Number & vbNewLine & _
          Err.Description & vbNewLine & _
          "Źródło: Baza Miejscowości TERYT" & vbNewLine & _
          "Moduł: " & cModule_Name
  Resume Exit_Here

End Function

Przetworzenie całego 80 MB pliku ULIC.xml zajęło ok. 125 sek. z czego ok. 25 sekund trwało wczytanie pliku ULIC.xml metodą .loadXML obiektu MSXML2.DOMDocument. Całkowity czas obróbki 267 028 rekordów wynosi ok. 2 minuty w porównaniu do 216 minut z użyciem obiektu MSXML2.DOMDocument.

Windows 10 i 64-bitowy MS Access 2010.

 

Znak Informacja dodatkowa NIESPODZIANKA!
Windows 10 i 64-bitowy MS Access 2010.
Wczesne wiązanie.
• Wczytanie pliku ULIC.xml metodą .loadXML obiektu MSXML2.DOMDocument - 2,5 sekundy
• Całkowity czas obróbki 267 028 rekordów wynosi ok. 2 minuty.
Późne wiązanie.
W tym przypadku niespodzianki nie ma. Trzeba cierpliwie czekać 3 - 4 godz.

Podsumowując całe przetwarzanie „Rejestru miejscowości i ulic” (Bazy rejestru TERYT), można stwierdzić, że opisane sposoby przetwarzania są trochę kapryśne, trochę pokomplikowane i nie da się ładnie napisać kodu przetwarzającego wszystkie Pliki pełne rejestru TERYT, czyli pliki WMRODZ.xml, TERC.xml, SIMC.xml oraz ULIC.xml. Ładny kod da się napisać, ale czekać 3-4 godziny na wykonanie tego ładnego kodu, to troszeczkę za długo.

Obecnie „Pełne pliki rejestru” TERYT zawierają pliki *.xml oraz pliki typu *.csv. Nie jestem pewien, ale chyba dawniej w pobranych skompresowanych archiwach nie było plików *.csv, ale mogę się mylić.
Pobieżnie przeszukałem internet w roku 2010 na pewno nie były dostępne pliki *.csv. Także w 2015 roku nie były dostępne pliki *.csv ponieważ z tych lat dostępne były skryptt PHP przetwarzający plik *.xml na plik *.csv.

W najbliższym, bliżej nieokreślonym, czasie postaram się zamieścić przykład przedstawiający pobieranie danych z plików rejestru TERYT o rozszerzeniu *.csv.