CSV-Datei importieren

  • Excel

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    CSV-Datei importieren

    Hallo an Alle, ich hab ein kleines Problem und würde mich freuen, wenn mir hier Jemand behilflich sein kann.

    Ich möchte in eine bestehende Excel Datei eine CSV-Datei auf ein ganz betimmtes Tabellenblatt mit dem Tabellennamen "Import" importieren. In der CSV-Datei sind die einzelnen Zellen durch Semikolon getrennt und zusätzlich mit einem Texterkennungszeichen (Anführungszeichen) versehen. Nach dem Import soll mit den importierten Daten auf einem anderen Arbeitsblatt gerechnet werden. Die Verknüpfungen sind bereits da, ich habe eine CSV-Datei manuell importiert und alle Verknüpfungen erstellt. Es ist also auch noch erforderlich, dass die alten Daten zuvor gelöscht werden, bzw. dass die alten Daten von der neuen CSV-Datei einfach überschrieben werden, damit die Verknüpfungen nicht verloren gehen.

    Ich habe hier schonmal einen Ansatz dazu, der aber leider nicht funktioniert. Das Auswählen der CSV-Datei funktioniert bereits, aber dann stürzt das Programm mit der Fehlermeldung "Einlesen hinter Dateiende" ab. Ich kann den Fehler leider nicht korrigieren, kann mir Jemand behilflich sein???

    Hier der Code:

    Quellcode

    1. Sub Datei_Importieren()
    2. Dim strFileName As String, arrDaten, arrTmp, lngR As Long, lngLast As Long
    3. Const cstrDelim As String = ";" 'Trennzeichen
    4. With Application.FileDialog(msoFileDialogFilePicker)
    5. .AllowMultiSelect = False
    6. .Title = "Datei wählen"
    7. .InitialFileName = "d:\Pfad\*.csv" 'Pfad anpassen
    8. .Filters.Add "CSV-Dateien", "*.csv", 1
    9. If .Show = -1 Then
    10. strFileName = .SelectedItems(1)
    11. End If
    12. End With
    13. If strFileName <> "" Then
    14. Application.ScreenUpdating = False
    15. Open strFileName For Input As #1
    16. arrDaten = Split(Input(LOF(1), 1), vbCrLf)
    17. Close #1
    18. For lngR = 0 To UBound(arrDaten)
    19. arrTmp = Split(arrDaten(lngR), cstrDelim)
    20. If UBound(arrTmp) > -1 Then
    21. With ActiveSheet
    22. lngLast = .Cells(Rows.Count, 1).End(xlUp).Row + 1
    23. lngLast = Application.Max(lngLast, 10)
    24. .Cells(lngLast, 1).Resize(, UBound(arrTmp) + 1) _
    25. = Application.Transpose(Application.Transpose(arrTmp))
    26. End With
    27. End If
    28. Next lngR
    29. End If
    30. End Sub

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

    Workbooks.OpenText funktioniert auch bei CSVs mit 2 Zeilen ;)

    Zacki schrieb:

    In der CSV-Datei sind die einzelnen Zellen durch Semikolon getrennt und zusätzlich mit einem Texterkennungszeichen (Anführungszeichen) versehen.
    Das lässt sich doch alles mit Excel-Bordmitteln lössen, ohne dass du von Hand splitten musst.
    Du kennst den Row-Delimiter nicht genau.
    Du musst die Anführungszeichen parsen.
    Das kann Excel alles selbst.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Ich bin inzwischen ein bischen weiter gekommen. Was noch nicht funktioniert, die CSV-Datei wird inzwischen korrekt geöffnet, aber sie wir in eine ganz neue Excel-Mappe geschrieben. Ich würde diese gern in die aktuell geöffnete Excel Mappe hinein über ein bestehendes Tabellenblatt mit dem Namen Tabelle2 schreiben, damit meine Verknüpfungen in der Excel-Mappe erhalten bleiben und die CSV-Daten ausgewertet werden können.

    Hier nun mein aktueller Code, es wäre schön, wenn Jemand helfen kann:

    Quellcode

    1. Sub Datei_Importieren()
    2. Dim strFileName As String, arrDaten, arrTmp, lngR As Long, lngLast As Long
    3. Const cstrDelim As String = ";" 'Trennzeichen
    4. With Application.FileDialog(msoFileDialogFilePicker)
    5. .AllowMultiSelect = False
    6. .Title = "Datei wählen"
    7. .InitialFileName = "d:\Pfad\*.csv" 'Pfad anpassen
    8. .Filters.Add "CSV-Dateien", "*.csv", 1
    9. If .Show = -1 Then
    10. strFileName = .SelectedItems(1)
    11. End If
    12. End With
    13. If strFileName <> "" Then
    14. Workbooks.OpenText Filename:=strFileName, _
    15. DataType:=xlDelimited, Semicolon:=True
    16. End If
    17. End Sub
    Das habe ich nun soweit hin bekommen, nur daraus ergibt sich leider an ganz neues Problem, in meiner Excel Mappe gehen sämtlich Bezüge verloren, die auf die importierte CSV-Datei verweisen. Gibt es dafür eine Lösung, um die Bezüge nicht zu verlieren? Sonst nützt mir ja der Import der CSV-Datei nichts, wenn ich alle Bezüge jedes Mal neu herstellen muss...

    Hier nochmal mein aktueller Code:

    Quellcode

    1. Sub Datei_Importieren()
    2. Dim strFileName As String, arrDaten, arrTmp, lngR As Long, lngLast As Long
    3. Const cstrDelim As String = ";" 'Trennzeichen
    4. With Application.FileDialog(msoFileDialogFilePicker)
    5. .AllowMultiSelect = False
    6. .Title = "Datei wählen"
    7. .InitialFileName = "d:\Pfad\*.csv" 'Pfad anpassen
    8. .Filters.Add "CSV-Dateien", "*.csv", 1
    9. If .Show = -1 Then
    10. strFileName = .SelectedItems(1)
    11. End If
    12. End With
    13. If strFileName <> "" Then
    14. Workbooks.OpenText Filename:=strFileName, _
    15. DataType:=xlDelimited, Semicolon:=True
    16. ActiveSheet.Move After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
    17. Worksheets("ffexport").Delete
    18. ActiveSheet.Name = "ffexport"
    19. End If
    20. End Sub
    Ich probiere nach viel googlen und lesen nun folgendes, was ich nach Zeile 20 einfügen möchte um die Bezüge wieder neu zu erstellen:

    Quellcode

    1. Range("Tabelle1!B3").FormulaLocal = "=WVERWEIS("FIRMA";ffexport!A1:CM2;2;FALSCH)"


    Funktioniert aber leider nicht! Weiß Jemand, wie das richtig sein muss?? Oder hat Jemand eine bessere Lösung für das Problem??

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

    Dann überschreibe einfach die Die Values der Zellen, die du als Verweis irgendwo verwendest.
    AlteZelleMitBezug.Value = NeueZelle.Value
    Dass die Bezüge sich nicht automatisch auf das neue Sheet anpassen ist klar.

    Oder du verwendest meinen Vorschlag aus Post#2 mit Use4dRange.Copy
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hmmm, verstehe ich nicht was Du damit meinst. Ich würde mir denken, dass ich in entsprechenden Zellen, in denen die Verweise auf das Arbeitsblatt getanden haben einfach nach jedem Import einer CSV-Datei neu erstelle. Das sollte der Zweck sein, den ich mit meinem Code erreichen wollte. Ich muss immer wieder CSV-Dateien mit ähnlichem Inhalt aber gleicher Struktur einlesen und auswerten. Somit brauche ich eine möglichst einfache Funktion, um die alten Bezüge wieder herzustellen. Wenn ich einmal im Makro alle Bezüge neu eingebe, ist der Aufwand ja noch vertretbar.

    Mit Deinem Vorschlag aus dem 2-ten Post kann ich leider nichts anfangen, ich verstehe nicht was damit erreicht werden soll.

    Ich danke Dir aber trotzdem schonmal für Deine Hilfe und Deine Geduld. Es wäre schön, wenn ich das mit dem importieren heute oder morgen noch irgendwie hin bekomme.
    Wie sehen denn die Formeln aus, die auf die neuen Zellen verweisen sollen?
    So wie oben angegeben?
    =WVERWEIS("FIRMA";ffexport!A1:CM2;2;FALSCH)

    In VBA musst du die englische Schreibweise der Formeln verwenden.
    WVERWEIS wäre HLOOOKUP.
    Auch die Semikoli werden durch Kommata ersetzt.

    Am besten kriegst du das raus, wenn du ein Makro aufzeichnest, während du eine Formel einfügst.
    Dort kriegst du zumindest die korrekte Syntax raus.
    Den Inhalt kannst du dann dynamisch umschreiben.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Leider kommt trotzdem eine Fehlermeldung. Ich habe die Zelle eingegeben und das Makro aufgezeichnet, und dann kopiert.
    Hier das Makro:

    Quellcode

    1. Sub Makro2()
    2. '
    3. ' Makro2 Makro
    4. '
    5. '
    6. ActiveCell.FormulaR1C1 = _
    7. "=HLOOKUP(""FIRMA"",ffexport!R[-2]C[-1]:R[-1]C[89],2,FALSE)"
    8. Range("B4").Select
    9. End Sub


    Und hier mein aktueller geänderter Code, das sollte doch eigentlich funktionieren, oder???

    Quellcode

    1. Sub Datei_Importieren()
    2. Dim strFileName As String, arrDaten, arrTmp, lngR As Long, lngLast As Long
    3. Const cstrDelim As String = ";" 'Trennzeichen
    4. With Application.FileDialog(msoFileDialogFilePicker)
    5. .AllowMultiSelect = False
    6. .Title = "Datei wählen"
    7. .InitialFileName = "d:\HBZ\Energieausweise\Berechnungsgrundlagen\*.csv" 'Pfad anpassen
    8. .Filters.Add "CSV-Dateien", "*.csv", 1
    9. If .Show = -1 Then
    10. strFileName = .SelectedItems(1)
    11. End If
    12. End With
    13. If strFileName <> "" Then
    14. Workbooks.OpenText Filename:=strFileName, _
    15. DataType:=xlDelimited, Semicolon:=True
    16. ActiveSheet.Move After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
    17. Worksheets("ffexport").Delete
    18. ActiveSheet.Name = "ffexport"
    19. Range("Wohngebäude!B3").FormulaLocal = "=HLOOKUP(""FIRMA"",ffexport!R[-2]C[-1]:R[-1]C[89],FALSE)"
    20. End If
    21. End Sub
    Leider kommt trotzdem eine Fehlermeldung
    Ich liebe diese Antwort.
    Ohne die Meldung ist sie sehr aussagekräftig. ;)

    Wenn du RC-Adresssierung in der Formel verwendest, solltest du auch die FormulaR1C1-Property verwenden.
    Sheets("Wohngebäude").Range("B3").FormulaR1C1 = "=HLOOKUP(""FIRMA"",ffexport!R[-2]C[-1]:R[-1]C[89],FALSE)"
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Du bist Spitze!!!! Vielen Dank für Deine unermüdliche Hilfe...

    2 Fragen habe ich noch zu dem Thema: Kannst Du mir evtl. sagen, was die exotischen Zeichen und Ziffern hinter "ffexport!" zu bedeuten haben, ich kann das dem normalen Raster von Excel nicht zuordnen. Ich hätte doer eigentlich A1:CM2 erwartet!

    2. Frage: Hast Du eine Ahnung, ob man die Nachfrage von Excel weg bekommt, wenn das Tabellenblatt gelöscht werden soll "In den Arbeitsblättern, die Sie löschen möchten, könnten Daten vorhanden sein. um die Blätter endgültig zu löschen, drücken Sie Löschen."
    Die Abfrage brauche ich nicht, ich weiß ja, dass dort Daten sind, die weg können!
    1)
    R bedeutet Row, C bedeutet Column.
    Die Zahlen nach R und C sind die absolutien bzw. relativen Positionen.
    In Klammern sind die relativen R[1]C[-1] heisst eine Zeile nach unten und eine Spalte nach links (gesehen von der Zelle, in der die Formel verwendet wird)
    Für 0 kannst du die Angaben auch ganz weglassen. RC[1] ist dasselbe wie R[0]C[1]

    Ohne Klammern kannst du auch absolut adressieren. R2C2 ist die Zelle B2

    Wichtig ist die Art der Adressierung (absolut oder relativ) dann, wenn du die Inhalte nach unten oder rechts ziehst bzw. kopierst.
    So wie bei der A1-Adressierung "A1" vs. "$A$1"

    2) Application.DisplayAlerts = False
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --