Excel in DataGridView importieren

  • VB.NET

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

    Excel in DataGridView importieren

    Hi,

    ich schreibe ein Programm für die Arbeit das u.A. Werte aus mehreren DataGridViews in ein einziges Excel-File speichert. Natürlich soll es auch die Werte aus dem File wieder laden können. Ersteres klappt, nur der Import nicht. Ich Google schon den 2. Tag und finde nichts passendes, auch weil VBA 2010 neu für mich ist. Als OOP kenne ich nur Java, habe damit aber andere Sachen gemacht. Hatte auch erst gedacht dass es nur mit Access geht oder SQL.

    Ich habe mehrere Codes aus dem Netz geholt und versucht nachzuvollziehen und zu modifizieren. Der einzige, der halbwegs funktioniert ist unten stehender. Allerdings kommt "Argument Exception nicht behandelt" in Zeile 21.
    Was muss ich machen damit das läuft?

    Visual Basic-Quellcode

    1. Imports System.Data.OleDb
    2. Dim connection As OleDbConnection
    3. Dim dataadapter As OleDbDataAdapter
    4. Dim cmd As OleDbCommand
    5. Dim datatable As DataTable
    6. Dim excel As String
    7. Dim OpenFileDialog As New OpenFileDialog



    Visual Basic-Quellcode

    1. Private Sub btn_import_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_import.Click
    2. OpenFileDialog.InitialDirectory = savePath 'Pfadangabe des Speicherorts
    3. OpenFileDialog.Filter = "All Files (*.*)|*.*|Excel files (*.xlsx)|*.xlsx|CSV Files (*.csv)|*.csv|XLS Files (*.xls)|*xls"
    4. 'Filter nach excel-files
    5. If (OpenFileDialog.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK) Then
    6. Dim fileinfo As New FileInfo(OpenFileDialog.FileName)
    7. Dim FileName As String = OpenFileDialog.FileName
    8. Excel = fileinfo.FullName
    9. 'Stelle Verbindung her
    10. connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Excel + ";Extended Properties=Excel 12.0;")
    11. 'Öffne Leitung
    12. connection.Open()
    13. dataadapter = New OleDbDataAdapter("Select * From [Tabelle1$]", connection)
    14. DataTable = New DataTable
    15. dataadapter.Fill(DataTable, "[Tabelle1$]")
    16. DataGridView1.DataSource = DataTable
    17. DataGridView1.DataMember = "[Tabelle1$]"
    18. 'Schließe Leitung
    19. connection.Close()
    20. End If
    21. End Sub

    @Cistbesser
    Versuche es so:
    Verwende keine für VB reservierten Wörter.
    Guck dir die Fill-Methode an und lasse die Zuweisung des DataMembers.

    VB.NET-Quellcode

    1. Using connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & xlsFile & ";Extended Properties=Excel 12.0;")
    2. connection.Open()
    3. Using dataadapter = New OleDbDataAdapter("Select * From [Tabelle1$]", connection)
    4. tbl = New DataTable("Tabelle1")
    5. dataadapter.Fill(tbl)
    6. DataGridView1.DataSource = tbl
    7. End Using
    8. End Using

    Und verwende Using, da kannst du das Close beim Connection dann weglassen...
    @Cistbesser Willkommen im Forum. :thumbup:
    Kannst Du bitte mal Deinen Thread von VB6 in VB.NET umbenennen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So geht's. Es kommt keine Fehlermeldung mehr :D
    Danke VB1963 für das snippet. Das using hat so leider nicht funktioniert.
    Allerdings tritt jetzt ein neues Problem auf: In meinem Datagridview habe ich 4 Spalten: Vorname, Nachname, PLZ, Wohnort.
    Nachdem ich das Excelfile exportiert habe und mit der Funktion wieder importiere, wird das Datagridview
    1. in den ursprünglichen Spalten nicht befüllt.
    2. um 4 Spalten erweitert, allerdings sind die Bezeichnungen in anderer Reihenfolge.
    Statt: (Vorname, Nachname, PLZ, Wohnort) steht jetzt (Nachname, Vorname, Wohnort, PLZ)

    Nach was muss ich denn suchen wenn ich was dazu lesen will (OleDB usw)? Ich kann das nicht ganz einordnen wozu es gehört.
    Edit: Es wundert mich sowieso, warum ich mit den Befehlen arbeiten kann und was zurückbekomme, obwohl ich außer einem Datagridview nichts eingefügt habe, also kein Dataset, Access Datenbank, ...
    Edit 2: Da ich im Originalprogramm über 10 Datagridviews benutze, wo später hinter vielen Zellen Funtkionen mit Berechnungen hinterlegt sind bzw. der Zelleninhalt durch Eingaben verändert wird, ist es sinnvoll das so zu machen? Je mehr ich darüber in Erfahrung bringe, umso mehr drängt sich mir der Verdacht auf, dass ich um SQL-Zeug nicht drumrum komme.

    VB.NET-Quellcode

    1. Private Sub btn_import_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_import.Click
    2. OpenFileDialog.InitialDirectory = savePath 'Pfadangabe des Speicherorts
    3. OpenFileDialog.Filter = "All Files (*.*)|*.*|Excel files (*.xlsx)|*.xlsx|CSV Files (*.csv)|*.csv|XLS Files (*.xls)|*xls"
    4. 'Filter nach excel-files
    5. If (OpenFileDialog.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK) Then
    6. Dim fileinfo As New FileInfo(OpenFileDialog.FileName)
    7. Dim FileName As String = OpenFileDialog.FileName
    8. Excel = fileinfo.FullName
    9. 'Stelle Verbindung her
    10. connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excel + ";Extended Properties=Excel 12.0;")
    11. 'Öffne Leitung
    12. connection.Open()
    13. dataadapter = New OleDbDataAdapter("Select * From [Tabelle1$]", connection)
    14. datatable = New DataTable("Tabelle1")
    15. dataadapter.Fill(datatable)
    16. DataGridView1.DataSource = datatable
    17. 'Schließe Leitung
    18. connection.Close()
    19. End If
    20. End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Cistbesser“ ()

    Das using hat so leider nicht funktioniert.
    Was hat denn dabei nicht funktioniert?

    Es wundert mich sowieso, warum ich mit den Befehlen arbeiten kann und was zurückbekomme, obwohl ich außer einem Datagridview nichts eingefügt habe, also kein Dataset, Access Datenbank, ...
    Doch - schaue einmal nach, was du bei DataGridView1.Datasource zugewiesen hast. Das ist eine DataTable in untypisierter Weise und die hast du mit dem DataAdapter befüllt...

    Nach was muss ich denn suchen wenn ich was dazu lesen will (OleDB usw)? Ich kann das nicht ganz einordnen wozu es gehört.
    Dazu würde ich dir die ganzen Video-Tut's und Links vom @ErfinderDesRades dazu vorschlagen.

    zu den Fragen 1 und 2:
    Ich schlage dir jetzt vor, du fügst dir ein typ. DataSet in dein Projekt ein und bildest sämtliche Tabellen analog deiner XLS-Datei darin ab.
    Als nächstes gehst du dann in die Datenquellen und ziehst dir eine Tabelle als DGV in eine Form und schaue, was dabei alles automatisch mit generiert wurde.
    Wichtig ist dabei zu beachten, dass dein neu generiertes DGV mit einer BindingSource an die Tabelle gebunden wurde...

    VB.NET-Quellcode

    1. Dim dts As New TestExcel.DataSetXLS ' typisiertes Dataset mit deinen darin befindlichen Tabellen
    2. Using connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & xlsFile & ";Extended Properties=Excel 12.0;")
    3. connection.Open()
    4. Using dataadapter = New OleDbDataAdapter("Select * From [Tabelle1$]", connection)
    5. dataadapter.Fill(dts.Tablle1) 'hier wird zum Beispiel die Tabelle1 im DataSet mit Daten gefüllt
    6. Me.Tablle1BindingSource.DataSource = dts
    7. Me.Tablle1BindingSource.DataMember = dts.Tablle1.TableName
    8. End Using
    9. End Using

    Der Vorteil einer BS ist, dass du das DGV dann mit dem Formdesigner gestalten kannst, wie es dir beliebt (Spalten ausblenden, Reihenfolge ändern etc. u.v.m.)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „VB1963“ ()

    du fügst dir ein typ. DataSet in dein Projekt ein und bildest sämtliche Tabellen analog deiner XLS-Datei darin ab.

    Das habe ich bereits probiert. Allerdings habe ich auf dem PC kein Access zur Verfügung. Ich kann die Dateien nur mit einem Viewer öffnen...
    2 Tage hab ich zu dem Scheiß schon gegoogled und nur geschützte Tutorials gefunden, wo die wichtigen Stellen natürlich geschwärzt sind.
    Ich habs in Visual Studio 2010 Express versucht, bekomms aber nicht hin.

    Ich habs mit ADO versucht, geht aber auch nicht weil behauptet wird es wäre ISAM nicht installiert oder w/e.

    Meine letzte Hoffnung ist jetzt, dass ich das Excel-File in .csv konvertiere und das dann irgendwie ins DGV bekomm.

    Cistbesser schrieb:

    connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Excel + ";Extended Properties=Excel 12.0;")
    Extended Properties müssen in Quotes.

    VB.NET-Quellcode

    1. connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Excel + ";Extended Properties=""Excel 12.0"";")
    bzw.

    VB.NET-Quellcode

    1. connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Excel + ";Extended Properties=""Excel 12.0;HDR=YES"";")
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    @Cistbesser
    Ich dachte du willst Daten aus einer XLS-Datei laden?
    Ich glaube, da suchst du komplett in einer anderen Richtung...
    Ein typ. Dataset bindest du manuell ganz einfach wie folgt in dein Projekt ein:
    Wähle das Menü (Rechtsklick mit der Maus über den Projektordner) Projekt/Neues Element hinzufügen... und dann die Vorlage »DataSet« aus. Aus der Toolbox zuiehst du dir dann deine Tabellen in das Dataset. Fügst dann entsprechend deine Spalten in jeder Tabelle ein und benamst alles analog deiner XLS-Datei...
    Weitere Vorgehensweise und Code siehe weiter oben...

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

    VB1963 schrieb:

    Warum funzt dann mein obiges Codesnippet
    Gute Frage.
    Ich könnte mir vorstellen, dass der Treiber so intelligent ist, wenn nur eine Property angegeben wird, dass er es richtig macht.
    Spätestens wenn mehr als eine Property angegeben wird, also z.B. ​Excel 12.0;HDR=YES verlangt er aber die offizielle Syntax, weil er dann nicht mehr unterscheiden kann, ob der zweite Parameter zu den Properties oder zum Connectionstring gehört (beides wird mit Semikoli separiert).
    Sicherer ist es jedenfalls mit Quotes.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Edit 2: Da ich im Originalprogramm über 10 Datagridviews benutze, wo später hinter vielen Zellen Funtkionen mit Berechnungen hinterlegt sind bzw. der Zelleninhalt durch Eingaben verändert wird, ist es sinnvoll das so zu machen? Je mehr ich darüber in Erfahrung bringe, umso mehr drängt sich mir der Verdacht auf, dass ich um SQL-Zeug nicht drumrum komme.
    Sowas nennt man Präsentation und Business-Logik.
    Dazu brauchst du kein Sql, aber sehr wohl datenbänkerisches Denken, und solltest dich in Databinding und die typisierte Dataset-Technologie einarbeiten.
    Datenbänker-Denke: erfinderdesrades.unitweb.de/Pr…ationale%20Grundidee.html
    Dataset & Databinding: vier Views-Videos

    VB1963 schrieb:

    Fügst dann entsprechend deine Spalten in jeder Tabelle ein und benamst alles analog deiner XLS-Datei...
    Weitere Vorgehensweise und Code siehe weiter oben...


    Done. Dataset erstellt, Spalten per Rechtsklick eingefügt und benannt, im Entwurfsfenster DataTable1 auf DGV gezogen.
    Allerdings habe ich keine Ahnung wie die Zeilen reinkommen.

    VB.NET-Quellcode

    1. DataSet1.DataTable1.Rows.Add("Müller", "Heinz", "Berlin", "12990")
    funzt leider nicht. Aber sowas muss es doch geben! :cursing:
    Und wo ich das einbinden muss schweigt sich auch jeder aus. Kommt das in die Form.Load oder in die PartialClass Dataset ?!

    MSDN Hilfe ist mal wieder fürn Ar***, YT liefert nichts, Google ebenfalls nicht. So langsam komme ich mir beim Arbeiten mit Datasets vor wie Asterix und der Passierschein...
    wenn du mal einfach das vier Views-Videos-Tutorial durchmachen tätest.
    Da sind ja auch Codesamples bei, die schweigen sich nicht weiter aus, sondern funktionieren einfach. Da kann eiglich keine Frage aufkommen, was wohin muss.
    Und da werden auch die typisierten Add-Funktionen vorgeführt, zum Download gestellt und durchgesprochen.
    Also es **gibt** "sowas", und du hast es vor der Nase, du musst nur hingucken.

    Ist richtig, dass Msdn da nicht groß hilft, denn Msdn kann nur Text und bestenfalls - wenn mans denn findet - auch Bilder, aber kein Video. Und diese grafische Programmierung, und mit den generierten typisierten Klassen eignet sich sehr schlecht als Text zu erklären, schon weil die Methoden und Zeugs individuell auf dein typDataset hin generiert und benannt ist.
    Also wende dich bei typDataset nicht an Msdn, sondern an den ObjectBrowser.
    Visual-Studio richtig nutzen

    Und vorrangig erstmal wirklich die Videos angucken - da wird alles gezeigt: von Anlage Dataset, Nutzung typisierter Methoden, bis hin zu Ansätzen ausgefeilten Designs, aber auch die Inspektion der generierten Klassen im ObjectBrowser.

    Und du musst halt programmieren können, also wenn der ObjectBrowser sowas anzeigt:
    Public Overloads Function AddArticleRow(Name As String, Price As Decimal, parentCategoryRowByFK_Category_Article As FourViews.FourViewsDts.CategoryRow, parentDelivererRowByFK_Deliverer_Article As FourViews.FourViewsDts.DelivererRow) As FourViews.FourViewsDts.ArticleRow

    Member von FourViews.FourViewsDts.ArticleDataTable
    dann musst du die Datentypen der Argumente und den Rückgabewert erkennen, und welche Objekte über diese Methode verfügen.
    Wie du also hoffentlich sehen kannst, ist diese Methode selbsterklärend.
    Und da sie generiert ist, findest du die nicht auf Msdn, sondern nur im OB - wie im Film "Inspection" gezeigt.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()

    @VB1963
    Jetzt check ich was du gemeint hast. Ich hatte erwartet, dass das DGV beim Programmstart schon was anzeigt, da ich es ja in der Load befülle. Man muss aber erst die xls importieren.
    Das werde ich dann wohl so machen, dass das letzte bearbeitete Projekt beim Start automatisch geladen wird.

    Allerdings gibt's noch ein Problem beim Importieren (siehe Bild im Anhang): Die Spalten werden doppelt erstellt und der erste Eintrag ("Nachname") wird aus Excel nicht geladen. Edit2: Das Kursive konnte behoben werden indem ich die Initialisierung des DGV rausgeschmissen habe.

    Edit: Zu deinem geposteten Code:
    Zeile1 Fehler: TestExcel.DataSetXLS -> damit kann er nichts anfangen, auch nicht mit Excel.blabla
    Zeile4 Fehler: Die Variable "dataadapter" verbirgt eine Variable in einem einschließenden Block

    Das obige Ergebnis kam durch meinen Code. Also zwischen Öffnen und Schließen der Verbindung dieser Teil:

    XML-Quellcode

    1. dataadapter = New OleDbDataAdapter("Select * From [Tabelle1$]", connection)
    2. dt = New DataTable("Tabelle1")
    3. dataadapter.Fill(dt)
    4. DataGridView1.DataSource = dt


    Interessant ist, dass die Spalte Nachnamen auch dann ausgelassen wird, wenn "Select * From [Tabelle1$A0:D5]" explizit angegeben wurde.

    @ErfinderDesRades
    Deine Videos habe ich mir angeschaut, allerdings ohne Ton. Geht hier im Großraumbüro nicht. Kopfhörer habe ich (noch) keine.
    Bilder
    • progr.jpg

      90,91 kB, 1.700×484, 390 mal angesehen

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Cistbesser“ ()

    man befüllt kein Dgv, und man importiert keine xls.
    Man designed ein typisiertes Dataset, bindet Dgvs daran, und befüllt das Dataset (nicht das Dgv).

    Die Videos ohne Ton haben dir sicherlich nicht ansatzweise die notwendigen Inhalte vermitteln.




    Bitte verwende die Datei-anhang-Funktion des Forums - so kann ich dein Bildle nicht sehen.
    Nur soweit: Du scheinst da iwie eine Vorgehensweise anzusprechen, die ich nicht kenne, und die ich dir auch garnet vermitteln wollte, und die scheinbar nicht so ganz funktioniert.

    Ich würde dir empfehlen, weiteres Herumgesuche und Gewurstel erst einmal zu lassen, bis du die Inhalte der Videos aufnehmen kannst. Andernfalls kannst du dich nur verwirren, und produzierst einen Wust, den du bestenfalls in die Tonne trittst, schlimmstenfalls weiter verwendest.

    Achso - bis zu Video gucken kannst kannst du dich ja spasseshalber mit Daten laden, speichern, verarbeiten beschäftigen, dassis ohne Vid.

    Aber es geht da auch nicht um die Befüllung aus Excel.
    Aber wie gesagt: Woher ein Dataset befüllt wird ist schnuppe, und Daten laden, speichern, verarbeiten basiert auf dem Einfachsten: auf Dataset.ReadXml.

    Die Befüllung aus Excel kann relativ einfach sein, kann aber auch ganz problematisch werden, je nachdem, wie die Excel-Tabelle gestaltet ist.

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

    @Cistbesser
    Also mein Codeausschnitt befüllt im Dataset nur eine Tabelle mit Daten aus einer Excel-Datei und weist der Bindingsource die Datenanbindung neu zu.
    Dies ist zwar schon designerseitig zugewiesen muss aber nach dem Füllvorgang komischerweise nochmals zugewiesen werden. (Warum das so ist, habe ich noch nicht herausgefunden?)
    Zeile1 Fehler: TestExcel.DataSetXLS -> damit kann er nichts anfangen, auch nicht mit Excel.blabla
    Zeile4 Fehler: Die Variable "dataadapter" verbirgt eine Variable in einem einschließenden Block
    In Zeile #1 habe ich mein Dataset deklariert, weil ich es so benannt habe. Wie hast du denn deines benannt?
    Zeile #4 beruht darin, dass du 'dataadapter' mehrmals deklariert hast. Ich habe es nur im 1. Using-Block ('Connection') getan - du wahrscheinlich klassenweit und mit C&P meinen Code eingefügt...
    Zum anderen Problem: da müsstest dein Projekt hochladen...
    Ich rate dir, wie EDR vor mir schon geschrieben hat, dir seine TUT's gründlich einzuverleiben.
    na, das ist halt dein Fehler:

    VB1963 schrieb:

    VB.NET-Quellcode

    1. Dim dts As New TestExcel.DataSetXLS
    Keine new DatasetXls erstellen, sondern die bereits auf dem Form befindliche nehmen. Die ist dort durch visuelle Programmierung im Form-Designer hingekommen, und dazu bestehen die Datenbindungen.
    Und dann musst du auch die Datasource nicht neu zuweisen.