Aus zwei Access DBs eine neue Access DB erstellen

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Aus zwei Access DBs eine neue Access DB erstellen

    :) Hallo VB-Gemeinde,

    Vorab, ich bin dabei VB zu erlernen und daher Anfänger. Ich verwende Grundlagenliteratur und suche hilfreiche Forenbeiträge, hier und in anderen Foren, bevor ich mit Fragen daher komme.

    Ich habe ein Berechnungsmodell, dass ich mit VB als Stand-Alone-Tool umsetzen möchte. Dabei gibt es unterschiedliche lokale Access (v2010-2013) Datenbanken als Datengrundlage. Diese werden durch bestimmte Parameter, Parameter sollen in Zukunft über eine Eingabemaske durch den User zur Verfügung gestellt werden, bearbeitet und in einer neuen Datenbank als Zwischenrechnungen angelegt werden.

    In diesem Beispiel sollen es zwei Datenbanken sein db1 und db2 mit jeweils einer Tabelle db1table1 und db2table1:

    db1table1:

    db1table1_ID | Group | Amount
    1 | A | 2
    2 | A | 4
    3 | B | 6
    4 | B | 8
    5 | C | 10
    6 | C | 12

    db2table1:

    db2table1_ID | Group | Factor
    1 | A | 2
    2 | B | 3
    3 | C | 4

    Basierend auf diesen beiden Tabellen soll eine neue Tabelle erstellt werden - tempdbtable1 (Amount2 ist hierbei eine Multiplikation von Amount und Factor bei einem Abgleich der Variable Group:

    db1table1_ID | Group | Amount1 | Amount2
    1 | A | 2 | 4
    2 | A | 4 | 8
    3 | B | 6 | 18
    4 | B | 8 | 24
    5 | C | 10 | 40
    6 | C | 12 | 48

    Mit SQL Code an sich habe ich kein Problem. Jedoch komme ich an einigen Stellen des VB Codes nicht weiter, um überhaupt mal etwas mit SQL machen zu können. Mein bisheriger Code sieht wie folgt aus, dabei versuche ich die beiden lokalen Datenbanken (db1 & db2) anzubinden und eine neue Datenbank (tempdb) auf Knopfdruck zu erstellen:

    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Public Class Form1
    3. 'Connect DB1
    4. Public con1 As New OleDb.OleDbConnection
    5. Public cmd1 As New OleDb.OleDbCommand
    6. Public reader1 As OleDb.OleDbDataReader
    7. Public anzahl1 As IntegerPublic Sub Provider1()
    8. con1.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\VB\Project\Input\db1.accdb"
    9. cmd1.Connection = con1
    10. End Sub
    11. 'Connect DB2
    12. Public con2 As New OleDb.OleDbConnection
    13. Public cmd2 As New OleDb.OleDbCommand
    14. Public reader2 As OleDb.OleDbDataReader
    15. Public anzahl2 As IntegerPublic Sub Provider2()
    16. con2.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\VB\Project\Input\db2.accdb"
    17. cmd2.Connection = con2
    18. End Sub
    19. 'Create TempDB Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    20. Dim catalog1 As New ADOX.Catalog()Dim table1 As New ADOX.Table()catalog1.Create("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\VB\Project\Temp\tempdb.accdb")
    21. End SubEnd Class

    Ich habe sehr bewusst den Ansatz über mehrere DBs gewählt und mich nicht nur auf eine DB mit allen Grundtabellen, sowie temporären und Ergebnistabellen eingeschränkt.


    ?( Meine Fragen lauten wie folgt:


    Wie kann ich eine neue Tabelle, basierend auf db1table1 und db2table1 erstellen und in tempdb ablegen?
    Muss ich in tempdb zuerst eine leere Tabelle erstellen mit allen erwünschten Variablen und ihren Eigenschaften oder kann ich eine bereits existierende Tabelle nehmen, wie etwa db1table1, diese bearbeiten und dann in tempdb ablegen, sodass auch die meisten definierten Variablen und Eigenschaften bereits vorhanden sind?
    Gibt es grundsätzliche Probleme bei meinem derzeitigen Ansatz bezüglich dem Zweck, den ich verfolge?


    Jegliche Lösungsansätze, Hinweise oder Verweise sind sehr willkommen. Danke.
    Ahoi,

    habe ich das richtig verstanden, es ist ein einmaliger Vorgang ?
    Noch ein Hinweis, die Spaltenköpfe werden als Attribute bezeichnet, nicht als Variablen.

    Ich würde Vorschlagen, du holst dir die Daten erstmal in ein von dir erstelltes Dataset.
    Das kannst du dann schön verarbeiten und an deine neue DB geben.
    Am besten ist es natürlich, wenn du eine fertige DB mit den gebrauchten Eigenschaften und Tabellen erstellt hast.
    Sonst kannst du auch per Laufzeit deine Tabellen erstellen.
    ich würde auch keine temporäre DB nutzen, um dann DB1 mit den neuen Daten zu füttern.
    Das würde ja bedeuten, dass du die vorhandene DB1 per Laufzeit veränderst. Das ist wohl leichter wenn man eine neue DB erstellt und diese
    als Endlager verwendet.

    Und Amount2 ist ja, wie du sagst, das Produkt einer Multiplikation. So etwas würde ich nicht in die DB speichern, sondern
    erst bei Gebrauch aus den vorhanden Daten berechnen lassen.

    Ich hoffe mal ich habe dich richtig verstanden, ansonsten können wir gerne Stück für Stück durchegehen.
    Grüße Manu

    Was Gott dem Menschen erspart hat, kann der Computer.
    Billy ©, (*1932), Schweizer Aphoristiker
    Quelle: www.Aphorismen.de
    Hallo Manü und danke für deine Antwort. :thumbup:

    Im Moment ist es als einmaliger Vorgang gedacht um es einfach zu halten. In Zukunft soll dieses Modell wie ein Taschenrechner laufen, der Benutzer macht einen gewissen Input und das Programm bearbeitet diesen Input und spuckt entsprechend etwas aus.

    Sorry für die untypische Bezeichnung, mir war unbekannt, dass Spaltenköpfe als Attribute bezeichnet werden. :)

    Ok, da kommen schon einige Hinweise mit denen ich sehr gut etwas anfangen kann und mich auch von der theoretischen Seite einarbeiten kann, bzw. z.T. schon gemacht habe - im nächsten Schritt im Programm ein DataSet erstellen und die Daten von den Access Datenbanken übertragen. Daraufhin mit SQL usw. bearbeiten, und schließlich an die neue TempDB übergeben.

    Des Weiteren sollten die Datenbanken und Tabellen, die in Temp DB zu füllen sind, bereits vorbereitet sein.

    Die Input DBs sollen nicht verändert werden, zumindest nicht vom Programm. Die Input DBs sollen von den Benutzern aufbereitet werden, das Format ist an sich vorgegeben und der Benutzer muss dieses nur füllen mit seinen Daten. Die Temp DBs dienen der Übersicht der Zwischenrechnungen des Modells und sollen nach einem Durchlauf erhalten bleiben (in Zukunft sollen diese Temp DBs vor jedem Modelldurchlauf geleert werden, ist für den Augenblick aber nicht wichtig, da ich noch immer bei den Basics bin). Schließlich soll eine weitere DB erstellt werden, die auf den Temp DBs basiert und die endgültigen Ergebnisse in Form eines Reportings aufweist. Ich habe diesen Schritt bisher nicht erwähnt, da es dem Schritt von Input DBs zu Temp DBs ähnelt. Auch hier möchte ich die Daten "roh" in Access-Form erhalten, bis zumindest der nächste Modelldurchlauf erfolgt.

    Ich werde mir überlegen, in wie Weit es Sinn macht Temp DBs zu erstellen oder doch alles einfach nur im DataSet zu halten, bis dann schließlich die finalen Tabellen mit Ergebnissen in Access Form zur Verfügung gestellt werden müssen.

    Danke nochmal für deine Antwort, ich denke sie gibt mir schon mal die richtigen Impulse für die nächsten Schritte und das Angebot fürs Stück für Stück durchgehen, nehme ich gerne an :)

    Ich werde jetzt erstmal versuchen die nächsten Schritte (orange) umzusetzen und melde mich dann wieder. :)
    ich würde sagen, das ist kein gutes Datenmodell, die beiden Tabellen, zwischen denen doch eindeutig eine Beziehung besteht, in 2 Dbs zu halten.

    Sauber wäre der Kram in einer DB untergebracht, also die beiden Tabellen

    Group
    ID Name Faktor

    Value
    ID GroupID Value

    Mehr Daten dürfen nicht gespeichert werden, denn sonst entsteht Redundanz, und das verstößt gegen das oberste Datenverarbeitungs-Gesetz überhaupt.
    Also die Multiplikationen sind berechnete Werte, und für sowas gibts ja auch mächtige Unterstützung.

    Die DataRelation wäre also Group->Value, und der Value-Tabelle könnte man dann problemlos eine berechnete Spalte spendieren, die die Multiplikation in Abhängigkeit von der Gruppe ausführt.

    gugge vlt. DataExpressions

    So geht das jdfs. im typisierten Dataset, und solch lässt sich ja aus einer DB befüllen: "Datenbank in 10 Minuten" auf Movie-Tuts
    (Man kann auch verschiedene DataTables aus verschiedenen DBs befüllen, aber dafür langt das Tut nicht hin)
    Ich hab das so verstanden, dass er beide DBs in einer mit mehreren Tables integrieren will.
    Grüße Manu

    Was Gott dem Menschen erspart hat, kann der Computer.
    Billy ©, (*1932), Schweizer Aphoristiker
    Quelle: www.Aphorismen.de
    Guten Abend :)

    Ich habe die erwähnten Punkte versucht zu verstehen und entsprechend in mein Programm zu implementieren. Ich denke, das Verständnis is schon besser geworden, jedoch habe ich Probleme bei der Umsetzung.

    Ich habe inzwischen beide Tabellen in ein DataSet bekommen.
    Darüber hinaus glaube ich, dass ich mit dem FillSchema-Code auch die PrimaryKeys erfasst habe für die folgende Relation-Bildung (db1table_ID ist der PKey in DT1 und Group is der PKey in DT2; db2table1_ID ist inzwischen aus der Input Access DB gelöscht -> DT2 hat somit nur zwei Spalten).
    Um die beiden DataTables kombinieren zu können muss eine Relation generiert werden basierend auf der Spalte "Group", die PKey in DT2 ist (somit parent) und auch in DT1 (child) vorhanden ist. Hier habe ich Probleme die Relation so umzusetzen. Wenn ich den untenstehenden Code debugge und auf den Knopf drücke, erhalte ich eine Fehlermeldung bezüglich der Relation: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt." mit Hervorhebung von "DS", ich verstehe nicht, was das Problem mit dem DataSet ist im Relation-Zusammenhang. Alle Beispiele die ich gefunden habe, haben keinen Bezug zu dieser Meldung.

    Mein Verständnis ist bisher, dass sobald ich eine Beziehung zwischen Tabellen habe, ich auch Werte übertragen kann wie etwa durch einen Inner Join. Die Umsetzung an dieser Stelle mit Expressions ist mir auch noch nicht wirklich verständlich.


    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Public Class Form1
    3. Public Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    4. Dim DS As System.Data.DataSet
    5. Dim DT1 As System.Data.DataTable
    6. Dim DT2 As System.Data.DataTable
    7. Dim MyCommand1 As System.Data.OleDb.OleDbDataAdapter
    8. Dim MyCommand2 As System.Data.OleDb.OleDbDataAdapter
    9. Dim MyConnection1 As System.Data.OleDb.OleDbConnection
    10. Dim MyConnection2 As System.Data.OleDb.OleDbConnection
    11.  
    12. 'Create new DataSet DS
    13. DS = New System.Data.DataSet()
    14. 'Create new DataTable DT1
    15. MyConnection1 = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\VB\Project\Input\db1.accdb")
    16. MyCommand1 = New System.Data.OleDb.OleDbDataAdapter("SELECT db1table1_ID, Group, Amount FROM db1table1", MyConnection1)
    17. DT1 = New System.Data.DataTable()
    18. MyCommand1.FillSchema(DS, SchemaType.Source, "db1table1")
    19. MyCommand1.Fill(DT1)
    20. MyConnection1.Close()
    21. 'Create new DataTable DT2
    22. MyConnection2 = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\VB\Project\Input\db2.accdb")
    23. MyCommand2 = New System.Data.OleDb.OleDbDataAdapter("select Group, Factor from db2table1", MyConnection2)
    24. DT2 = New System.Data.DataTable()
    25. MyCommand2.FillSchema(DS, SchemaType.Source, "db2table1")
    26. MyCommand2.Fill(DT2)
    27. MyConnection2.Close()
    28. 'Create a Relation with column Group in DT1 and DT2
    29. DS.Relations.Add("RelationGroup", DS.Tables("DT2").Columns("Group"), DS.Tables("DT1").Columns("Group")) 
    30. 'Create DataTable DT3 to calculate values and produce connection between Groups to display inner join tables
    31. Dim DT3 As DataTable = DT1.Copy()
    32. Dim tempdb_col4 As New DataColumn("MultiAmount100", GetType(System.Decimal), "Amount * 100")
    33. DT3.Columns.Add(tempdb_col4)
    34. Dim tempdb_col5 As New DataColumn("New", GetType(System.Decimal), "MultiAmount100 * 4")
    35. DT3.Columns.Add(tempdb_col5)
    36. 'Create DataGridView to see if changes applied
    37. DataGridView1.DataSource = DT3
    38.  
    39. End Sub
    40. End Class


    Ich hoffe ich kann an dieser Stelle weitere Impulse und Hilfestellungen erhalten :thumbup:

    Vielen Dank.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Sensation“ ()

    du arbeitest mit untypisierten Datasets, dassis unpraktisch, anfällig, umständlich.
    Das ganze Gesummse mit den Spalten, Spaltentypen, Tabellen, Relations etc. kannst du dir viel einfacher im Dataset-Designer zusammenklicksen, und noch vieles mehr.
    guggemol vier Views-Videos, da wird ein Dataset mit 3 Tabellen und 2 Relations aufgesetzt.