MS-Office-Forum

Zurück   MS-Office-Forum > Microsoft Access & Datenbanken > Microsoft Access
Registrieren Forum Hilfe Alle Foren als gelesen markieren

Banner und Co.

Antworten
Ads
Themen-Optionen Ansicht
Alt 12.02.2019, 15:54   #1
trawideli
Neuer Benutzer
Neuer Benutzer
Standard DAO - Tabellenstruktur vergleichen

Hallo,
ich brauche Hilfe beim Abändern der Datenbank, die ich betreue.

Hier wurde eine Möglichkeit eingebaut während dem Update auf eine neue Datenbank-Version die Tabellenstruktur zu prüfen. Wurden Tabellen, Felder, Indizes usw. in der Testversion hinzugefügt, gelöscht oder geändert, sollen diese jetzt übertragen werden.
Da bei meinem nächsten Update sich drei Feldeigenschaften ändern, habe ich die Prozeduren überprüft und festgestellt, dass min. eine nicht übernommen wird. Beim Vergleichen mit anderen Prozeduren fiel auf, dass nicht nur die Properties zugewiesen werden, sondern auch die Propertie-Auflistung durchlaufen wird.
Jetzt habe ich mich ganz viel schlau gelesen dazu und ausprobiert und schaffe es aber nicht das, was ich gefunden habe, in meine Datenbank zu implementieren.

Diesen Code habe ich bereits in meiner Datenbank dort gefunden, wo es darum geht neue Felder oder Tabellen zu erstellen:
Code:

Private Sub AddFieldToTDF(src As Field, tdf As TableDef)
    Dim p As Property, dst As Field
    'Neues Feld erzeugen
    Set dst = tdf.CreateField
    'Feld-Eigenschaften kopieren (auch den Namen)
    For Each p In dst.Properties
        On Error Resume Next
        p.Value = src.Properties(p.Name).Value
    Next p
    'Feld hinzufügen
    tdf.Fields.Append dst
    'Zusätzliche Feldeigenschaften der Quelle kopieren
    For Each p In src.Properties
        On Error Resume Next
        dst.Properties.Append dst.CreateProperty(p.Name, p.Type, p.Value)
    Next p
End Sub
Auch bei dem was ich im Internet gefunden habe, ging es immer darum, dass etwas neu hinzu kommt. Hier mal ein paar Links:

https://www.ms-office-forum.net/foru...d.php?t=158474 Der darin angegebene Link funktioniert allerdings nicht mehr. Ich habe die Seite hier gefunden: https://www.tksoft-online.de/21-code...en-mittels-dao

https://www.ms-office-forum.net/foru...d.php?t=257167 Auch bringt mich der enthaltene Link nicht zu der Information, sondern der Startseite der Kulpas. In den Tutorials konnte ich auf die Schnelle nicht das gewünschte finden. Allerdings habe ich enen alten Forumseintrag von Manuela Kulpa gefunden, der darauf eingeht: https://www.ms-office-forum.net/foru...ad.php?t=75016

Und noch ein Link von Allen Browne zu dem Thema: http://allenbrowne.com/func-DAO.html#SetPropertyDAO

Trotz all dieser Information komme ich an der Stelle, wo es hin soll. nicht weiter. Es geht darum, dass geprüft wird, welche Eigenschaften sich bei den Tabellenfeldern geändert haben und nur diese dann eingetragen oder erstellt werden. So sieht das momentan aus:
Code:

Private Sub CheckTableInDB(src As TableDef, db As Database)
    ' Tabelle aus scr in Ziel-Datenbank wählen
    Dim dst As TableDef
    Set dst = db.TableDefs(src.Name)
    ..
    ...
    ' 6.    Felder finden, die in Src und in Dst sind.
    '       Diese Felder vergleichen!
    If src.Fields.count = dst.Fields.count Then
        For j = 0 To src.Fields.count - 1
            On Error Resume Next
            Set f = src.Fields(j)           ' Feld in Quelle nach Index bestimmen
            Set fNew = dst.Fields(f.Name)   ' Feld nach Namen in Ziel suchen
            If err <> 0 Then
                Call RenameField(dst.Fields(j), f.Name) ' Umbenennen
            Else
                For Each p In fNew.Properties
                    On Error Resume Next
                    p.Value = f.Properties(p.Name).Value
                Next p
            End If
        Next j
    End If
...
End Sub
An der Stelle, wo die Zuweisung der Properties ist, muss auch noch irgendwie die Properties-Auflistung durchlaufen werden. Außerdem denke ich, dass das ganze aus der If-Anweisung raus muss, da ja neben dem Namen auch andere Eigenschaften geändert worden sein könnten.
Die dritte Überlegung war diese Abläufe in eine eigene Prozedur/Funktion zu packen, da sie ja an mehreren Stellen benötigt werden. Das hat aber auch nicht geklappt.

Da einige der Links auf dieses Forum verweisen habe ich mich hier mal angemeldet und hoffe, dass jemand die Knoten in meinem Hirn lösen kann.

Vielen Danke schon mal für eure Unterstützung und die Geduld so viel Text zu lesen.

Grüße,
trawideli
trawideli ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 12.02.2019, 16:40   #2
ebs17
MOF Guru
MOF Guru
Standard

Strukturänderungen an der Datenbank

Tabellenstrukturen vergleichen finde ich desorientiert. Die Strukturen im Backend der Arbeitsversion sollten bekannt sein. Welche Dinge bei einem Update der Anwendung auch am Backend vorgenommen werden müssen, ist ja im Augenblick der entsprechenden Entwicklung bekannt. Da würde man sich diese Maßnahmen merken statt irgendwann später über alles vergleichen und neu ermitteln zu müssen.

Ich gehe also so vor: Wenn am Entwickler-Backend ein Feld, ein Index oder irgendetwas anderes zu ergänzen wäre, erfolgt das nicht per Hand, sondern sofort mit einer Codelösung aus obiger Funktionssammlung. Immer in dem Stil "erst prüfen, dann handeln". So kann man alle Maßnahmen kumulativ in einem Script sammeln und das Script immer voll durchaufen lassen.
So ein Script bietet dann folgende Vorteile:
- Es ist bereits entwicklerseitig getestet und stimmig mit den einhergehenden FE-Änderungen.
- Die Anwendung am Arbeits-BE erfolgt sehr schnell und fehlerfrei, man denke ja auch daran, dass ggf. ein Mehrnutzerbetrieb unterbrochen werden muss wegen des notwendigen exklusiven Zugriffes.
- Mit dem Script hat man auch gleich eine Dokumentation, was genau man ausgeführt hat - nicht dass man Fehler angelastet bekommt, die zeitnah mit dem Updatevorgang passieren könnten und die aber ganz andere Ursachen haben.

__________________

Ein freundliches Glück Auf!

Eberhard

Abfrageperformance ist kein Geheimnis
SQL ist leicht: {0}:{1}:{2}:{3}:{4}:{5}:{6}:{7}:{8}:{9}:{10}:{11}:{12} <= geklammerte Zahlen sind Einzelthemen
Dein Dankeschön: DBWiki => Spende
ebs17 ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 12.02.2019, 17:54   #3
hcscherzer
MOF Guru
MOF Guru
Standard

Vielleicht als Ergänzung zu Eberhards Anmerkungen und auch zum Code hinter dem Link, auf den er verweist:

Ich scripte solche Änderungen der Struktur am BackEnd generell nicht mit VBA-Code sondern mit SQL-Befehlen. Das hat den Vorteil, dass auch nicht-Access BackEnds bedient werden können.

__________________

Freundlichen Gruß
Hans-Christian
-----------------------------------------
Oft erwünscht, selten beachtet: nach Erledigung des Problems den Thread als erledigt zu markieren
-----------------------------------------
Ich möchte nur Mitglied in einem Verein sein, der Leute wie mich nicht als Mitglied aufnimmt (Groucho Marx).
-----------------------------------------
Ab sofort regelmässig: MOF Stammtisch in Bremen. Näheres hier.
hcscherzer ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 12.02.2019, 18:25   #4
trawideli
Threadstarter Threadstarter
Neuer Benutzer
Neuer Benutzer
Standard

Danke ebs17 für den Link, den werde ich mir dann mal in Ruhe zu Gemüte ziehen.

Diese Vorgehensweise ist vllt ganz standardmäßig, es ist aber das, was ich zur Zeit habe.
Ich habe schon angefangen mir ein anderes Konzept zu überlegen und bin auch bereits mehrfach über die von hcscherzer erwähnte SQL-Lösung gestolpert. Aber das bedarf noch einiger weiterer Überlegungen und Informationen bevor ich diesen Schritt gehen kann.

Die Prozeduren sind ja bereits vorhanden, um alles zu vergleichen. Nur bei den Eigenschaften fehlt mir etwas. Wenn ich z. B. die Caption-Eigenschaft ändern würde, wäre sie mit der aktuellen Prozedur nicht übertragen worden. Das sollte aber passieren.

Grüße,
trawideli
trawideli ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 26.02.2019, 16:17   #5
trawideli
Threadstarter Threadstarter
Neuer Benutzer
Neuer Benutzer
Standard

Hallo nochmal,
ich habe es jetzt doch geschafft. Meine Lösung sieht jetzt so aus:
Code:

    '6.    Felder finden, die in Src und in Dst sind.
    '      Diese Felder vergleichen!
    Dim intSaveErr As Integer                      'zur Speicherung von Fehlermeldungen
    If src.Fields.count = dst.Fields.count Then
        Logging ("Vergleichen der Felder in " & src.Name & ":")
        For j = 0 To src.Fields.count - 1
            On Error Resume Next
            Set f = src.Fields(j)           'Feld in Quelle nach Index bestimmen
            Set fNew = dst.Fields(f.Name)   'Feld nach Namen in Ziel suchen
            If err <> 0 Then
                Call RenameField(dst.Fields(j), f.Name, confirm)    'Umbenennen
                Set fNew = dst.Fields(f.Name)                       'Feld nach Namen in Ziel suchen
                If err <> 0 Then
                    Logging ("-Umbenennung von " & dst.Fields(j) & " nach " & f.Name & " nicht erfolgreich")
                    Set fNew = dst.Fields(j)                        'Feld nach Index in Ziel suchen
                End If
            End If
            'Else
            '    For Each p In fNew.Properties
            '        On Error Resume Next
            '        p.Value = f.Properties(p.Name).Value
            'Die "For Each"-Schleife wurde aus der "Else"-Anweisung herausgenommen, da sich neben dem Namen
            'auch andere Eigenschaften geändert haben könnten. Es werden jetzt alle Eigenschaften durchlaufen,
            'z. B. "Caption" oder "Description" und nicht nur die, die bereits gesetzt oder vordefiniert waren.
            intSaveErr = 0
            For Each p In f.Properties
                On Error Resume Next
                'Versuche die Eigenschaft anzulegen
                fNew.Properties.Append fNew.CreateProperty(p.Name, p.Type, p.Value)
                intSaveErr = err.Number
                On Error GoTo 0
                Select Case intSaveErr
                    Case 0
                        Logging ("-Hinzufügen der Eigenschaft " & p.Name & "=" & p.Value & " bei Feld " & fNew.Name)
                    Case 3367
                        'Property existiert schon
                        'Fehler beim Vergleich oder Setzen des Wertes werden ignoriert, damit die Prozedur nicht unterbrochen wird.
                        On Error Resume Next
                        If fNew.Properties(p.Name).Value <> p.Value Then
                            fNew.Properties(p.Name).Value = p.Value
                            'Nur bei fehlerfreiem Durchlauf Log-Eintrag erstellen
                            If err = 0 Then Logging ("-Eintragen der Eigenschaft " & p.Name & "=" & p.Value & " bei Feld " & fNew.Name)
                        End If
                    Case Else
                        'keine Aktion nötig
                End Select
            Next p
        Next j
    End If
Das Hauptproblem war, dass ich gedacht hatte, ich könnte eine eigene Prozedur oder Funktion dafür machen, weil an mehreren Stellen eine Überprüfung der Properties nötig ist. Allerdings brauche ich nur an dieser Stelle diese Verschachtelung.
Das zweite Problem war den richtigen Fehlercode abzufangen. Gibt es hier noch andere Fälle, die abgefangen werden sollten, um die Eigenschaften von einer DB richtig in die andere zu übertragen?
Das dritte Problem war, dass bereits in der If-Anweisung beim Vergleichen der Eigenschaften Fehler auftreten können und die Prozedur sang- und klanglos abgebrochen wurde. (Ja, hier fehlt(e) eine Fehlerroutine.) Die "On Error Resume Next"-Anweisung musste vor die If-Anweisung.

Ich fange nur so langsam an zu verstehen, wie Access aufgebaut ist. Also, wenn es noch weitere Dinge gibt, die zu beachten sind, bin ich für jede Information dankbar. Z. B. habe ich irgendwo gelesen, dass man erst die Beziehungen lösen muss, bevor man Felder löschen kann. Ist das auch beim Ändern nötig?

__________________

Grüße,
trawideli
-----------------------
Win10 mit Access07
------------------------------
Nur Di und Do anwesend
trawideli ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Ads
Antworten


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Besucher: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge anzufügen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

vB Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist An.
Gehe zu


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 Uhr.



Powered by: vBulletin Version 3.6.2 (Deutsch)
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.

Copyright ©2000-2018 MS-Office-Forum. Alle Rechte vorbehalten.
Copyright ©Design: Manuela Kulpa ©Rechte: Günter Kramer
Eine Verwendung der Inhalte in anderen Publikationen, auch auszugsweise,
ist ohne ausdrückliche Zustimmung der Autoren nicht gestattet.