Excel-Daten mit bestehenden Datatable verbinden

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von raist10.

    Excel-Daten mit bestehenden Datatable verbinden

    Hallo zusammen,

    ich bin neu hier, programmiere schon eine Weile immer mal wieder mit VB.NET
    Nur nun komme ich nicht weiter udn hoffe auf Hilfe.

    Zu meinem Problem:

    Ich habe ein Datagridview mit Daten aus einer SQL-Datenbank. Nun soll ich nur die Zeilen anzeigen, deren Produkte auch in einer Excel-Liste vorhanden sind.

    Die Listen sind leider nicht immer im gleichen Format, sodaß ich eine Import-Routine vorschalten wollte. Ich plane in einem Datagridview den Inhalt der Excel-Liste anzuzeigen und der Benutzer definiert mir die Spalten mit dem eindeutigen Schlüssel (Artikelnummer) und die zu übernehmende Spalte (Menge).

    Also 1. Wie kann ich das aktuelle Worksheet in einem Datagridview anzeigen?

    Wenn der Benutzer die Angaben gemacht hat, möchte ich in meinem ursprünglichen Datagridview nur die Zeilen anzeigen, deren Produkte in Execl enthalten ist und die Menge mit dem Wert aus der Excel-Liste vorbelegen. Ich habe den ursprünglichen Datatable um 2 Felder erweitert und beim durchlaufen des Excel-datatables könnte ich die betreffenden Zeilen markieren und dann mit einem View einen Filter setzen.

    Aber geht das nicht noch anders?
    Kann man aus 2 Datatable-Objekten (ich habe keinen Dataspace) mit einer Abfrage ein Ergebnis-datatable machen?

    Ich hoffe, Ihr wisst was ich meine und hoffe auf Hilfe.

    Vielen Dank schon mal
    Karline
    Hast du mal daran gedacht, die Excel-Tabelle direkt per OLEDB-Connection einzubinden?

    So in etwa (ungetestet):

    VB.NET-Quellcode

    1. connExcel = New OleDbConnection
    2. cmdExcel = New OleDbCommand
    3. connExcel.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=c:\MyExcel.xlsx;Extended Properties=""Excel 12.0;HDR=YES"""
    4. connExcel.Open
    5. cmdExcel.Connection = connExcel
    6. cmdExcel.CommandText = "SELECT * FROM [Tabelle1$]"
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    ja klar habe ich schon drüber nachgedacht, aber ich weiß nicht genau, wie das Worksheet heißt (Also Tabelle1 muss es nicht geben)
    Unter VB6 konnte man immer noch auf das ActiveWorksheet zugreifen, aber das ist auch schon so lange her...

    und wie dann weiter, doch die Datensätze einzeln durchgehen und die Information in das andere datatable übernehmen?
    Du kannst mit connExcel.GetOleDbSchemaTable die Tabellennamen rausfinden.
    msdn.microsoft.com/de-de/libra…schematable(v=vs.80).aspx

    ActiveWorksheet geht nur, wenn du mit Excel.Application.OpenWorkbook die Datei öffnest.
    Das ist aber mühevoller als der OleDB-Ansatz.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo,

    das habe ich jetzt geschaft:

    Erst lese ich die Tabellennamen ein:

    Quellcode

    1. Public Function GetSchemaTable(ByVal connectionString As String) As DataTable
    2. Using connection As New OleDbConnection(connectionString)
    3. connection.Open()
    4. ' Dim returnValue As DataTable
    5. Dim schemaTable As DataTable = _
    6. connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, _
    7. New Object() {Nothing, Nothing, Nothing, "TABLE"})
    8. Return schemaTable
    9. End Using
    10. End Function


    und Anzeige der Sheets in einem Datagridview, damit der Benutzer das betreffende Blatt wählen kann
    und dann das auslesen des Blatts:

    Quellcode

    1. connExcel = New OleDbConnection
    2. cmdExcel = New OleDbCommand
    3. connExcel.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=D:\datei.xlsx;Extended Properties=""Excel 12.0;HDR=YES"""
    4. connExcel.Open()
    5. cmdExcel.Connection = connExcel
    6. cmdExcel.CommandText = "SELECT * FROM [" & Table_name & "]"
    7. Dim dataAdapter As OleDbDataAdapter = New OleDbDataAdapter(cmdExcel)
    8. Dim dt As New DataTable
    9. dataAdapter.Fill(dt) ' Alle Daten werden ins Datatable gefüllt. Danache kannst du wohl mit Dataset arbeiten.
    10. DGV.DataSource = dt
    11. connExcel.Close() 'brecht Excel_verbindung ab


    Also besten Dank schon mal.

    Nun zum zweiten Problem. Gibt es eine Möglichkeit die Daten beider Datatables (dtSQLServer und dtExcel) meit einer Abfrage zu verknüpfen? Wenn ja, bitte kurzes Codebeispiel, Danke!

    Viele Grüße
    Karline
    @ Karline

    Mal so als generell Hinweis zu Deinem Problem:

    Einen DB untauglichen WorkFlow-Prozess in einer Firma durch Konvertierung/Import-Mechanismen an eine DB anzubinden ist meistens ein hoffnungsloses Unterfangen. Einfach weil man nicht wirklich an alle Möglichkeiten die die User sich so einfallen lassen denken kann und man daher immer wieder für Sonderfall XYZ oder besonders depperten User ABC irgendwelche Speziallösungen nachreichen/entwicklen muss. Das wird ein Faß ohne Boden und am Ende gibt es doch nur Datensalat weil irgendjemand den Konvertierungsmechanismus/Importmechanismus falsch bedient hat.

    Das Letzteres passieren wird (falsche Auswahl der Excel-Datei oder des Sheets oder Datums-/Währungs-/Nummerische-Angaben mit Text-Angaben in einer Spalte vermischt hat) ist so sicher wie das Amen in der Kirche.

    Sinnvoller wäre der Ansatz das Du einen Standard-Vorlage entwickelst die die User befüllen können frei Schnauze und nur Excel-Sheets die dieser Standard-Vorlage entsprechen verarbeitest.

    Damit hättest Du schonmal für den Import der Daten in die DB ein Standardmechanismus der nicht x Sonderfälle berücksichtigen muss und Du tust Dich um Welten leichter.

    Noch besser wäre es die Excel-Sheets über eine XML-Datei in die Datenbank einzulesen. Durch die "Schnittstelle" XML-Datei bleibt dann die komplette Methode sogar unabhängig von Excel-Sheets und wenn jemand mit einer CSV kommt musst Du nur noch die Umwandlung der CSV in die XML-Datei durchführen, aber der einmal geschriebenen Import-Vorgang in die DB bleibt unverändert.

    Für die User brauchst Du dann eigentlich nur noch ein Object das die Umwandlung von Datenquellen (wie eben Excel-Sheet, CSV-Datei or what ever) in die XML vor nimmt.

    Der riesen Vorteil ist die Aufgaben-Trennung und Du bist wesentlich flexibeler für Sonderfälle/Erweiterungen der Datenquellen und dabei deutlich sicherer im Import der Daten in die Datenbank. einfach weil die DB die Daten nur nach festgelegter Spezifikation der XML übernimmt und Du die Einhaltung beim Befüllen der XML aus der Datenquelle ja individuell auf den Typ der Datenquelle bezogen proggen kannst.

    Just my 5 Cents. ;)

    Gruß

    Rainer
    Hi Rainer,

    ich stimme dir voll und ganz zu, nur ist hier der Prozess ein anderer.

    Es kommt vom Endkunden eine Liste mit Artikeln in Excel (an der Stelle kann ich nicht ansetzen, der Kunde gibt uns nichts anderes) Im Programm gibt es eine Artieklliste zum Bearbeiten und um es nun den Usern einfacher zu machen, sollen eben nur die Artikel angezeigt werden, die in der Excel-Liste enthalten sind. Es geht also um einen reinen Filter für die Bearbeitungsanzeige.

    Und da wir an den Ausgangslisten nicht viel machen können, zeige ich die Tabellenblätter an udn lasse den User sagen, welche Spalte den Artikel indentifiziert udn lese eine Menge mit ein. Wird da was falsches angegeben, schlägt der Filter feht udn der Benutzer hat eben keine Liste zum Bearbeiten. Da passiert noch nichts in der Datenbank.

    Ich würde nun als nächstes den Inhalt der Exel-Liste sequentiell durchgehen udn immer schauen, welche tietl sind enthlaten udn das in der ursprünglichen Liste markieren. Anschließen mit einem View einen Filter auf das Feld setzen.

    nur einfacher wäre dann schon, wenn ich beide Datatables mit einem Inner-Join verbinden könnte.

    Also habe ich hier mal gefragt, ob es auch einfacher geht, denn seit dem ich auf VB.NEt umgestiegen bin, habe ich gerlernt, es gibt immer viele Wege nach Rom... ;)

    Viele Grüße
    Karline
    @ Karline

    Ah oki.

    Dann guck Dir mal das Thema typisierte DataSets mit dem DataSet-Designer an.

    Dort kannst Du "virtuelle" Tables einrichten und diesen dann den Excel-Inhalt zu weisen als wenn Du ein DB-Table nutzen würdest. Durch die Einfügung in dieses virtuelle Table kannst Du dann auch genauso darauf mit SQL zugreifen wie auch ein reales DB-Table.

    Durch die Typisierung hast Du zumindest Datantyp-Sicherheit beim Abgleich erreicht und kannst danach dann noch weitere Dinge dank
    DataBinding an NET-Forms anstellen.

    Einen kleinen aber für Dich vielleicht nützlichen Vorteile gäbe es noch zusätzlich: Man kann diese typisierten DataSets mit einer einzigen Code-Zeile in ein XML-Dokument umwandlen und mit einer einzigen Zeile Code woanders wieder einlesen.

    Gruß

    Rainer