Textdatei importieren in xls und Zeilenzahl ermitteln, beeinflussen oder teilen

  • Excel

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

    Textdatei importieren in xls und Zeilenzahl ermitteln, beeinflussen oder teilen

    Ein freundliches Hallo an alle Online-Forumsmitglieder,

    folgende Frage:
    ich will verschiedene Textdateien mit unterschiedlicher Anzahl von Datensätzen, Daten (=Spalten) sind per Komma getrennt (Ausgabe aus einem CAD-Programm, ähnlich Stückliste) in xls einlesen.
    Eine Textdatei in (mind.) ein Tabellenblatt.
    Ich bin momentan im Anfangsstadium und mache das mit einem erweiterten Makro mit internem Aufruf des Textkonvertierungsassistenten (siehe Anhang). Erweitert habe ich um manuelle Dateiwahl am Anfang über application.GetOpenFilename und manuell gewählter Einfügezelle für mehr Flexibilität.
    Die Daten werden mit Beibehalten des Tabellenformates eingelesen, da die Tabelle ein festes Layout hat.
    Die Daten bestehen aus einer variablen Anzahl von Zeilen und festen Anzahl von Spalten und enthalten Texte und Zahlen.
    Die Tabelle in der ausgedruckten Form hat eine feste Länge (Din A4 quer) mit festem Zoomfaktor im Druck, jedes Tabellenblatt in der ausgedruckten Form hat ganz unten einen fixen Datenbereich mit projektbezogenen Angaben (z.B. zwischen Zeile 41 und 45), und vorher eine Summenzeile, die alle Zahlenspalten summiert (z.B. auf Zeile 40). Dieser fixe Tabellenbereich soll nicht durch die Textdatei gefüllt werden.

    Denkbar ist, dass 1) die eingelesenen Daten (auch wenn zu viele Zeilen) alle in ein Tabellenblatt kommen und der fixe Datenbereich mit Summenzeile wird immer wieder nach einer bestimmten Zeilenzahl eingefügt + Summenübertrag für nächste Druckseite
    oder vielleicht 2) die eingelesenen Daten nur bis zur maximalen Zeilenzahl 39 auf das erste Tabellenblatt eingefügt werden und der Rest wieder bis Zeilenzahl 39 auf das nächste Tabellenblatt usw.
    und der fixe Summen- und Projektbereich unten auf der Seite ist vorbereitet und unverändert in allen Tabellenblättern.

    Hat da jemand eine nützliche Idee, wie das Problem am besten zu lösen ist? Im Anhang ist der Code des bisherigen Makros.

    Wie kann ich die Anzahl der vom Textkonvertierungsassistenten eingefügten Zeilen im VBA ermitteln?
    Ich kann zwar die Startzeile der auszulesenden Daten aus der Textdatei im Assistenten einstellen, nicht aber die Endzeile. Gibt es da einen Trick?

    Im Voraus besten Dank für die Unterstützung. :thumbup:
    Dateien
    • Sub Makro.txt

      (1,61 kB, 208 mal heruntergeladen, zuletzt: )

    Visual Basic-Quellcode

    1. Option Explicit
    2. Private Sub Zeilenzahl() 'Nicht notwendig für die Frage, nur zum Testen der Funktion
    3. Dim sDateiName As String
    4. sDateiName = Application.GetOpenFilename
    5. MsgBox "Die Datei " & sDateiName & vbCrLf & "hat " & CStr(Zeilen(sDateiName)) & " Zeilen", vbOKOnly + vbInformation
    6. End Sub
    7. Private Function Zeilen(ByVal sDateiName As String) As Long
    8. Dim sEnde As String
    9. Dim arrInput() As String
    10. If Dir(sDateiName) > "" Then
    11. Open sDateiName For Binary As #1
    12. sEnde = Space(LOF(1))
    13. Get #1, , sEnde
    14. arrInput = Split(sEnde, vbCrLf)
    15. Close #1
    16. Zeilen = UBound(arrInput) + 1
    17. ReDim arrInput(0)
    18. Else
    19. Zeilen = -1
    20. End If
    21. End Function


    Edit:
    Bei großen Dateien ist zu beachten, dass diese komplett in den Speicher geladen wird. Da ist es dann besser die Zeilen einzeln einzulesen und mitzuzählen, was meist länger dauert.
    Gruß
    Peterfido

    Keine Unterstützung per PN!

    Antwort: Effizienterer Code für Leerzeilen einfügen/Zeilenhöhe anpassen/kopieren

    Hallo peterfido,

    vielen Dank für deine Antwort,

    deine Funktion läuft gut, die Anzahl der einzulesenden Zeilen aus dem textfile schon vor dem Einlesen zu ermitteln. Ich habe das zwischenzeitlich anders gelöst (siehe unten), indem ich die Zeilenzahl nach dem Einlesen ermittle.
    Die Zeilenzahl ist interessant, weil in der Tabelle, die später im Format DINA4 quer ausgedruckt wird, am Ende jeder Seite (nach einer bestimmten Zeilenzahl) eine Projekt-Fußzeile mit Summenbildung eingebaut werden muss.
    Ich mache das so, indem ich (siehe Makro3)
    1) aus der Zeilenzahl ermittle, wie oft die Fußzeile (bestehend aus 5 Zeilen) benötigt wird (= Zahl r) also wie lang die Tabelle ist/wieviele Seiten ausgedruckt werden müssen),
    2) die 5 Zeilen für die Fußzeile werden dann als Leerzeilen eingefügt und die Zeilenhöhe wird aus der Muster-Fußzeile übernommen, da die Höhe anders ist als bei den normalen Zeilen
    3) die Fußzeile wird dann aus einer anderen Mappe (eigentlich soll es später eine frei wählbare xls.Datei sein) auf die vorher eingefügten Zeilen drauf kopiert.

    Sub Makro3()

    Dim r As Integer

    'Ermitteln der Zeilenzahl des eingefügten Datenbereiches aus dem Textfile (Spalte B wird nur von Textfile-Daten beschrieben)
    ErsteZeile = Range("B1").End(xlDown).Row
    'MsgBox "Erste Zeile: " & ErsteZeile
    LetzteZeile = Range("B" & Rows.Count).End(xlUp).Row
    'MsgBox "Letzte Zeile: " & LetzteZeile

    r = (LetzteZeile - ErsteZeile) / 32 'Anzahl des zu kopierenden Fußzeilen-Bereiches
    'MsgBox "Anzahl Seiten = benötigter Fußzeilen-Bereiche: " & r

    For x = 1 To r
    Z = 44 'Zeilenposition Fußzeilen-Bereich aus Muster
    s = 12 + x * 32 + (x - 1) * 5 'Startzeile
    e = s + 4 'Endzeile
    'MsgBox "Startzeile/Endzeile: " & s & ", " & e

    For i = s To e
    ActiveSheet.Rows(i).Insert 'leere Zeile einfügen
    Sheets("Blatt 11").Range("A" & i).RowHeight = _
    Sheets("Blatt 10").Range("A" & Z).RowHeight 'Zeilenhöhe aus Muster-Fußzeile übernehmen
    Z = Z + 1
    Next i
    Sheets("Blatt 10").Range("A44:BF48").Copy _
    Sheets("Blatt 11").Range("A" & s) 'Inhalt der Muster-Fußzeile übernehmen
    Next x

    End Sub

    Da das etwas lange dauert und man beim Leerzeilen einfügen, Zeilenhöhe übernehmen und Textinhalte rüberkopieren quasi "zusachen" kann, ist die Frage, ob man das auch etwas schneller vielleicht in einem Schritt machen kann. Quasi kopieren inkl. Zeilenhöhe und Einfügen zwischen Zeile s und s+1 (d.h. Einfügen in zusätzliche Zeilen, ohne den bisherigen Inhalt der Zeilen zu überschreiben).

    Gibt es für 1-3 einen etwas effizienteren Code? Danke!
    Mit copy und pastespecial habe ich das vorher versucht, bin aber wieder davon abgekommen, weil einige Forumsmiglieder die Verwendung von copy und pastespecial nicht so positiv bewertet haben.
    Aber das wäre nicht so wichtig, wenn es gut uznd schnell funktioniert.
    Ich habe mit den Parametern/Konstanten von pastespecial aber nur die Spaltenbreite hinbekommen, nicht aber die Zeilenhöhe, die gerade das Problem ist. Weiterhin wird ja bei copy/paste auf den Zielbereich einfach drauf kopiert und nicht dazwischen eingefügt, oder?
    Könntest Du mir bitte mit etwas Code noch einmal auf die Sprünge helfen. Danke. :rolleyes:
    Jo, die Höhe übernimmt er tatsächlich nicht. Würde ich dann auch wie Du zu Fuß machen.

    Ob es effizienter geht, kann ich ohne Quellcode und Quelldaten nicht sagen. Evtl. bringt schon ein Application.screenupdating = false vorher und =true nachher etwas Zeit einsparen. Oder die Daten gleich einzeln eintragen und die Fußzeilen an entsprechender Stelle setzen.?.

    Im schlimmsten Fall dauert es so lange, wie es dauert.

    Pastespecial kenne ich nur mit einem Copy vorneweg, da ich ein Copyspecial so nicht gefunden habe. Da ist dann wichtig darauf zu achten, dass kein anderes Programm / keine weitere Excelinstanz die Zwischenablage nutzt. Also einfach während der Makroausführung die Beobachterrolle einnehmen und Finger wech.
    Gruß
    Peterfido

    Keine Unterstützung per PN!
    Das Ausschalten der Aktualisierung der Anzeige hilft enorm!
    Hätte ich nicht gedacht. Das geht nun so schnell, dass die Code-Optimierung nicht mehr notwendig ist.
    Danke vielmals. Dieses Thema ist hiermit beantwortet.

    Hast Du noch Zeit gefunden, mein anderes Thema noch einmal durchgelesen. Ich habe dort auf deine Frage geantwortet. :D