Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
832to836
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
832to836
832to836
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Open for Input - Limit für Textzeilen?

Open for Input - Limit für Textzeilen?
10.01.2007 13:27:01
MartinCH
Hallo Zusammen
In einem Makro öffne ich ein *.xml File damit ich Zeilenweise den String prüfen und gegebenfalls ersetzen kann.
Nun funktioniert das eigentlich reibungslos, bis auf die Tatsache, dass einige Zeilen ohne logischen Grund übersprungen werden.
Ist es möglich, dass es ein Limit für Textzeilen gibt ider gibt es die Möglichkeit bei "Input #1, Text" explizit eine bestimmte Textzeile zu definieren?
Oder kann ich das Ursprungsfile eventuell in zwei Teile Spitten anschliessend Umwandeln und danach wieder zusammenführen?
Es handelt sich beim original File übrigens um 411027 Textzeilen bei einer Dateigrösse von 13.5 MB.
Besten Dank für Eure Infos.
Hier für Interessierte der Script.


Sub SubstituteSave()
Dim arr() As String
Dim iCounter As Double
Dim sSource As String, sTarget As String, sTxtA As String
Dim sTxtB As String, sTxt As String, sPath As String
Dim strMatch1 As String, strMatch2 As String
Dim strMatch3 As String, strMatch4 As String
Dim strMatch5 As String, strMatch6 As String
Dim strMatch7 As String, strMatch8 As String
Dim intFront As Integer, intEnd As Integer
Dim Param1 As Integer
Dim Param2 As Integer
Dim Param3 As Integer
Dim Param3_1 As String
Dim PrüferMatch1 As Boolean
Dim TxtLines As Double
Dim Text1 As String
Dim i As Double
sPath = Range("B7").Value & "\" 'Pfad der Datei
sSource = sPath & Range("B1").Value ' Name der Textdatei
sTarget = sPath & Range("B4").Value ' Neuer Name der Textdatei
sTxtA = Range("B2").Value ' alter Text
sTxtB = Range("B3").Value ' neuer Text
strMatch1 = Range("D2").Value 'vordere Begrenzung1
strMatch2 = Range("D3").Value 'hintere Begrenzung1
strMatch3 = Range("D4").Value 'vordere Begrenzung2
strMatch4 = Range("D5").Value 'hintere Begrenzung2
strMatch5 = Range("D6").Value 'vordere Begrenzung3
strMatch6 = Range("D7").Value 'hintere Begrenzung3
strMatch7 = Range("F2").Value 'vordere Begrenzung4
strMatch8 = Range("F3").Value 'hintere Begrenzung4
PrüferMatch1 = False
Close
Open sSource For Input As #1
Do While Not EOF(1)    ' Schleife bis Dateiende.
    Input #1, Text1    ' Hilfsvariable zum einlesen verwenden
    'Zähler hochzählen
    TxtLines = TxtLines + 1
Loop
'Schliessen der Datei weil Dateiende erreicht wurde
Close #1
Open sSource For Input As #1
'Do Until EOF(1)
For i = 1 To TxtLines
    'Eine Zeile mit der Zeilennummer einlesen
    Line Input #1, sTxt
   'Zeilentext mit Vorgabe1 prüfen
    If InStr(1, sTxt, strMatch1) > 0 Then
        Param1 = Channel_Path(Mid(sTxt, Len(strMatch1) + 1, (Len(sTxt) - (Len(strMatch1) + Len(strMatch2)))))
        PrüferMatch1 = True
    End If
    'Zeilentext mit Vorgabe2 prüfen
    If InStr(1, sTxt, strMatch3) > 0 Then
        Param2 = Location_Path(Mid(sTxt, Len(strMatch3) + 1, (Len(sTxt) - (Len(strMatch3) + Len(strMatch4)))))
        PrüferMatch1 = True
    End If
    'Zeilentext mit Vorgabe3 prüfen
    If InStr(1, sTxt, strMatch5) > 0 Then
        Param3 = Product_Path(Mid(sTxt, Len(strMatch5) + 1, (Len(sTxt) - (Len(strMatch5) + Len(strMatch6)))))
        Param3_1 = Kuerzen_Product(Mid(sTxt, Len(strMatch5) + 1, (Len(sTxt) - (Len(strMatch5) + Len(strMatch6)))))
        PrüferMatch1 = True
    End If
    'Zeilentext mit Vorgabe4 prüfen und PrüferMatch1 = True
    'Application.Wait Now + TimeSerial(0, 0, 0.1)
    If InStr(1, sTxt, strMatch7) > 0 Then
        If PrüferMatch1 = True Then
            sTxtB = strMatch7 & Set_the_String(Param1, Param2, Param3, Param3_1) & strMatch8
            sTxt = sTxtB
            sTxtB = ""
            PrüferMatch1 = False
            Param1 = 0
            Param2 = 0
            Param3 = 0
            Param3_1 = ""
        Else
            sTxtB = strMatch7 & "Default" & strMatch8
            sTxt = sTxtB
            PrüferMatch1 = False
            Param1 = 0
            Param2 = 0
            Param3 = 0
            Param3_1 = ""
            sTxtB = ""
        End If
    End If
    iCounter = iCounter + 1
    ReDim Preserve arr(1 To iCounter)
    arr(iCounter) = sTxt
Next i
Close
Open sTarget For Output As #1
For iCounter = 1 To UBound(arr)
  Print #1, arr(iCounter)
Next iCounter
Close
On Error GoTo ERRORHANDLER
Shell "notepad " & sTarget, vbMaximizedFocus
MsgBox " Job erledigt!"
ERRORHANDLER:
End Sub


14
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 13:54:53
Heiko
Hallo Martin,
was machst du den mit den Texten (den Textzeilen) nach der Überprüfung?
Werden die Zeilen (also der Text) nur verändert ?
Oder löscht du auch schon mal ne Zeile ?
Gruß Heiko
PS: Rückmeldung wäre nett !
AW: Open for Input - Limit für Textzeilen?
10.01.2007 14:01:56
MartinCH
Hallo Heiko
Besten Dank für Dein Begutachten meines Treads.
Die Texte werden mit Funktionen geprüft und ausgewechselt oder wenn keine Übereinstimmung erfolgen sollte, werden die originale zurückgegeben ins Array.
Löschen sollte es auf keinen Fall, es müssen alle Zeilen unbedingt erhalten bleiben.
Gruss der am Verzweifelnde
Martin
Hier die Funktionen:


Function AnzahlZeichen(Wort As String, GesuchtesZeichen As StringAs Integer
    n = 0
    For i = 1 To Len(Wort)
        If Mid(Wort, i, 1) = GesuchtesZeichen Then
            n = n + 1
        End If
    Next
    AnzahlZeichen = n
End Function
Function Channel_Path(Kanal As StringAs Integer
Dim Digit As Integer
If Kanal = "/" Then
    Channel_Path = 1
Else
    Digit = AnzahlZeichen(Kanal, "/")
    If Digit = 1 Then
        Channel_Path = 2
    Else
        Channel_Path = 3
    End If
End If
End Function
Function Location_Path(Location As StringAs Integer
Dim Digit As Integer
If Location = "/" Then
    Location_Path = 1
Else
    Location_Path = 2
End If
End Function
Function Product_Path(Product As StringAs Integer
Dim Digit As Integer
If Product = "/" Then
    Product_Path = 1
Else
    Digit = AnzahlZeichen(Product, "/")
    If Digit = 1 Then
        Product_Path = 2
    Else
        Product_Path = 3
    End If
End If
End Function
Function Kuerzen_Product_Path(Product As String, Marker1 As String, Marker2 As StringAs String
Kuerzen_Product_Path = Mid(Product, Len(Marker1) + 1, Len(Product) - Len(Marker1) - Len(Marker2))
End Function
Function Kuerzen_Product(xText As StringAs String
    Dim i1 As Integer, i2 As Integer
     i1 = InStr(1, xText, "/", vbTextCompare)
     If i1 > 0 Then
        i2 = InStr(i1 + 1, xText, "/", vbTextCompare)
     End If
     If i2 > 0 Then
        Kuerzen_Product = Mid(xText, i1, i2 - i1 + 1)
     Else
        Kuerzen_Product = Mid(xText, i1)
     End If
End Function
Function Set_the_String(Channel1 As Integer, Location2 As Integer, Product3 As Integer, BezProd4 As StringAs String
If Channel1 = 1 And Location2 = 1 And Product3 = 1 Then
    Set_the_String = "1-Top-Top-Top"
    GoTo Gump
End If
If Channel1 = 1 And Location2 = 1 And Product3 = 2 Then
    If BezProd4 = "/S3-310 Frische Convenience" Then
        Set_the_String = "2-Frische_Convenience-Top-Top"
    ElseIf BezProd4 = "/S3-320 Ultrafrische Convenience" Then
        Set_the_String = "2-Ultrafrische_Convenience-Top-Top"
    ElseIf BezProd4 = "/S3-330 Haltbare Convenience" Then
        Set_the_String = "2-Haltbare_Convenience-Top-Top"
    ElseIf BezProd4 = "/S3-340 Tiefkuehl Convenience" Then
        Set_the_String = "2-Tiefkühl_Convenience-Top-Top"
    End If
    GoTo Gump
End If
If Channel1 = 1 And Location2 = 2 And Product3 = 2 Then
    If BezProd4 = "/S3-310 Frische Convenience" Then
        Set_the_String = "3-Frische_Convenience-Name-Top"
    ElseIf BezProd4 = "/S3-320 Ultrafrische Convenience" Then
        Set_the_String = "3-Ultrafrische_Convenience-Name-Top"
    ElseIf BezProd4 = "/S3-330 Haltbare Convenience" Then
        Set_the_String = "3-Haltbare_Convenience-Name-Top"
    ElseIf BezProd4 = "/S3-340 Tiefkuehl Convenience" Then
        Set_the_String = "3-Tiefkühl_Convenience-Name-Top"
    End If
    GoTo Gump
End If
If Channel1 = 1 And Location2 = 2 And Product3 = 3 Then
        If BezProd4 = "/S3-310 Frische Convenience/" Then
            Set_the_String = "4-Technologie_Frische"
    ElseIf BezProd4 = "/S3-320 Ultrafrische Convenience/" Then
            Set_the_String = "4-Technologie_UltraFrisch"
    ElseIf BezProd4 = "/S3-330 Haltbare Convenience/" Then
            Set_the_String = "4-Technologie_HC"
    ElseIf BezProd4 = "/S3-340 Tiefkuehl Convenience/" Then
            Set_the_String = "4-Technologie_Tiefkuehl"
    End If
    GoTo Gump
End If
If Channel1 = 2 And Location2 = 2 And Product3 = 3 Then
    If BezProd4 = "/S3-310 Frische Convenience/" Then
        Set_the_String = "5-Tec-F_Name-Name-Kundengruppe"
    ElseIf BezProd4 = "/S3-320 Ultrafrische Convenience/" Then
        Set_the_String = "5-Tec-UF_Name-Name-Kundengruppe"
    ElseIf BezProd4 = "/S3-330 Haltbare Convenience/" Then
        Set_the_String = "5-Tec-HC_Name-Name-Kundengruppe"
    ElseIf BezProd4 = "/S3-340 Tiefkuehl Convenience/" Then
        Set_the_String = "5-Tec-TC_Name-Name-Kundengruppe"
    End If
    GoTo Gump
End If
If Channel1 = 3 And Location2 = 2 And Product3 = 3 Then
    Set_the_String = "Default"
End If
Gump:
End Function


Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 14:15:08
Heiko
Hallo Martin,
ohne jetzt deinen ganzen Code zu Prüfen zu checken mal als Tipp, dieses kleine Makro.
Da siehst du wie man so ein Textfile komplett in einem Rutsch in Array einliest.
Die Größe des Strings in den die Datei eingelesen wird liegt irgendwo bei 2GB, sollte also für deine Zwecke reichen. Und bei 13MB großen Dateien sollte dein Arbeitsspeicher auch reichen.
Damit ist dann aber noch nicht geklärt warum dein Code mal ein paar Zeilen vergißt. Das liegt aber meines erachtens nicht an dem lesen und schrieben des Textfiles sondern ich vermute eher einen Fehler in deinen umfangreichen Vergleichen so das mal ne Zeile nicht verändert wird.

Sub TextDatAendernNeu3()
Dim strPfad As String, strhelp As String
Dim arrInput() As String
Dim lngPos As Long
strPfad = "H:\EXCEL\EXCEL Privat\Beispiele\Dat_Test_Dateien\Textt.txt"
' Textdatei in einem Rutsch einlesen und dann per Split aufteilen
Open strPfad For Binary As #1
strhelp = Space(LOF(1))
Get #1, , strhelp
arrInput = Split(strhelp, vbCrLf)
Close #1
For lngPos = LBound(arrInput) To UBound(arrInput)
' Hier dann dein Vergleichscode rein, und die Änderungen gleich in das Array zurückschreiben.
If InStr(1, arrInput(lngPos), "Neu") > 0 Then
arrInput(lngPos) = Replace(arrInput(lngPos), "Neu", "GanzALTNeu")
End If
Next lngPos
' Nun die Texte in einem Rutsch wieder in die Datei zurückschreiben.
Open strPfad For Binary As #1
Put #1, , Join(arrInput, vbCrLf)
Close #1
MsgBox "Ready"
End Sub

Gruß Heiko
PS: Rückmeldung wäre nett !
Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 14:34:46
MartinCH
Hallo Heiko
Danke für den Splitting Array Code, habe soeben die Datei manuell gesplittet und danch gesolved, lief einwandfrei, keine Fehler. Danach habe ich die DAteislitts wieder zusammengeführt und in undere Software als Update integriert, ist einwandfrei durchgelaufen und die anschliessende Prüfung ist ebenfalls positiv, also liegt es zu 90% an der menge der Daten und darum bedanke ich mich für deinen Code, hoffe das das mein Problem beheben wird.
Rückmeldung erfolgt nach dem Test. Habe noch so meine Probleme wie ich den aktuellen Code in Dein Script integrieren kann. Aber "Eile mit Weile" bin ich doch vor 2 Jahren noch mit weit offenem Maul dagestanden wenn ich nur schun "SUB das_erste()" stand. Dank Euch habe ich sehr viel gelernt in VBA.
Gruss
Martin
PS Gut dass es Euch gibt.... ;0)
Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 14:44:22
Heiko
Hallo Martin,
da du ja scheinbar mit großen Datenmengen arbeitest, hier nochmal zwei von deinen Funktionen etwas beschleunigt.

Function AnzahlZeichen(Wort As String, GesuchtesZeichen As String) As Integer
AnzahlZeichen = Len(Wort) - Len(Replace(Wort, GesuchtesZeichen, ""))
End Function

Soweit ich deinen alten Thread gelesen habe sollte diese kurze Version deine Wünsche auch erfüllen, mit der 2 bei Instr wird ab der zweiten Stelle nach dem Zeichen gesucht.

Function Kürzen_Text(Text As String) As String
Kürzen_Text = Left(Text, InStr(2, Text, "/"))
End Function

Gruß Heiko
PS: Rückmeldung wäre nett !
Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 15:23:27
MartinCH
Hallo Heiko
Danke für den Functionen Bonus, werde das natürlich gerne testen und wenn erfolgreich ersetzen.
Gruss
Martin
AW: Open for Input - Limit für Textzeilen?
10.01.2007 15:38:54
MartinCH
Hallo Heiko
Freut mich Dir mitzuteilen, dass die Funktion AnzahlZeichen einwandfrei arbeitet.
Die Funktion Kürzen_Text nur teilweise, weil es besteht die möglichkeit folgender Varianten:
"/blablabla/blablabla"
da sollte folgendes rauskommen und das ist auch korrekt verarbeitet von der Funktion
"/blablabla/"
und Variante 2:
"/blablabla"
da sollte folgendes rauskommen
"/blablabla"
es ist aber "" was leider nicht genügt.
Aber besten Dank für die Anzahl Zeichen da geht es ruck zuck durch...
Gruss
Martin
Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 16:18:50
MartinCH
Hallo Heiko
Die integration derner Routine hat folgendes ergeben,


Open sSource For Input As #1
Do While Not EOF(1)
    Input #1, Text1
    TxtLines = TxtLines + 1 'ergibt 411027 Zeilen
Loop
Close #1
MsgBox (TxtLines)
Open sSource For Binary As #1
    strhelp = Space(LOF(1))
    Get #1, , strhelp
    arrInput = Split(strhelp, vbCrLf)
Close #1
For lngPos = LBound(arrInput) To UBound(arrInput) 'UBound ist 411015 Zeilen


Was kann das sein? irgendwie werden Zeilen nicht gelesen oder ?
Optional könnte man die Datei in ein Array lesen ca. 250000 Zeilen und den Rest in eine Zweite Datei. Anschliessend beide Dateien dusch den Prüf und ersetz VBA laufen lassen
die Ergebnisse wieder zu einer Datei vereinen. Etwas umständlich aber es scheint als einzige mögliche Lösung. Doch wie splitte ich sauber eine Datei und wie vereine ich diese anschliessend ohne Datenverlust?
Gruss Martin
Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 16:42:22
Heiko
Hallo Martin,
das kann daran liegen das die Textzeilen in deiner Textdatei nicht alle mit vbCrLf getrennt sind, sondern vielleicht auch einige nur mit Cr oder nur mit Lf.
Lass doch mal Testweise mit vbCr und vbLf anstatt VBCrLf durchlaufen und guck was passiert.
Kannst du mir außerdem mal kurz erklären (mit ein paar Beispiel Strings) was du da eigentlich genau ersetzen willst in den Strings, ich kann deine ganzen Funktionen nämlich nicht so richtig nachvollziehen und darum auch nicht so richtig helfen weil ich nicht weis wo du hin willst.
Gruß Heiko
PS: Rückmeldung wäre nett !
Anzeige
AW: Open for Input - Limit für Textzeilen?
10.01.2007 16:56:41
MartinCH
Hallo Heiko
Danke für den Hinweis.
gerne mache ich den von Dir vorgeschlagenen Test, wir müssen aber auf Morgen verschieben. Eventuell kann ich nicht arbeiten da unser VPN Netzt einen Service erhält.
Gruss bis Morgen
Martin
"Line Input" anstelle von "Input"
10.01.2007 16:59:57
"Input"
Hallo
Mit "Input", werden die Strings nur bis zum ersten im String vorkommenden Komma eingelesen. Der Rest wird auf einen zweiten Datensatz verteilt
Gruss Rainer
@ Rainer
10.01.2007 17:19:58
Heiko
Hallo Rainer,
das wußte ich noch nicht, also wieder was gelernt!
Da weiß man doch wieder warum man hier im Forum aktiv ist ;-)
Gruß Heiko
AW: "Line Input" anstelle von "Input"
11.01.2007 08:06:50
"Input"
Hallo Ramses
Danke, Dein Hinweis hat mich auf die richtige Fährte geleitet, danke.
Ursachenbefund im Antwort Tread an Heiko.
Gruss
Martin
Anzeige
AW: Open for Input - Limit für Textzeilen?
11.01.2007 08:01:34
MartinCH
Hallo Heiko, hallo Ramses
Habe es endlich gefunden, es war wie die Nadel im Heuhaufen, ein Parameter im Programm welches den Export macht war die Ursache. Dieses Programm wurde falsch konfiguriert und hatte einen Parameter welcher mit einem "ü" versehen war und dieses Zeichen wurde beim Export in ein anderes Zeichen umgesetzt und beim Prüfen als ein anderes Zeichen Interpretiert, jedoch vom Makro (welches einwadfrei funktionierte) in die richtige Schreibweise zurückgeschrieben. Beim Import ins Ursprungsprogramm wurde nun diese korrekt umgesetzte "ü" nicht mehr erkannt.
Danke Euch beiden für Eure Mithilfe konnte ich doch wieder etwas neues Lernen von Euch.
@Heiko musste somit auch nicht das Array Splitten, Danke trotzdem für den Code.
Gruss
Martin
Anzeige

301 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige