rackzak
Goto Top

Excel-Dateien in Textdatei umwandeln mit VBS-Skript

Hallo!

Das ist ein wrikliches tolles Forum hier. Ich habe schon mehrfach sehr gute Beiträge gefunden und finde die Hilfestellungen und die Antworten klasse! face-smile.

Torztdem habe ich jetzt ein Problem, was ich nicht selber lösen kann (bestimmt, wenn ich ein oder zwei Jahre noch VBS lerne ;)).


Jetzt zu meinem Problem:

Ich habe eine mehrere Exceldateien, die ich per VBS Skript in Textdatei umwandeln möchte. Dafür habe ich hier schon dieses Tool Skript gefunden (siehe unten).
Leider ist das Problem, dass die Namen der Dateien von den des Datenblattes unterscheiden z.B. Name der Datei -> 1234.xls und des Blattes in der Excelmappe -> Blatt1.

Ich habe mir mit Batch und dem VBS-Skript eine Möglichkeit geschaffen, den Inhalt eines Ordners aufzulisten, daraus mehrere Batchdateien zu generieren, die mir wiederrum die Exceldateien (die sich in dem besagten Ordner befinden) umwandeln. Das funktioniert auch klassen, wenn der Dateiname mit dem Namen des Daten-Blattes in der Excelmappe enspricht, ansonsten läuft das VBS-Skript nicht durch (ist ja auch logisch, da er nicht auf das Tabellenblatt zugreifen kann).

Mal abgesehen von meinem Wahsinnskonstrukt in als Batchfile (möchte ich so behalten *g*) gibt es eine Möglichkeit in VBS das aktive Tabellenblatt zu verwenden und keinen festen Namen anzugeben?

Hier das VBS-Skript:

Const ABZEILE = 1
Const ABSPALTE = 1
Const ANZSPALTEN = 20
Const TRENN =	"	"  

Dim oDatei
Set fso = CreateObject("Scripting.FileSystemObject")  

	If WScript.Arguments.Count < 3 Then
		WScript.Echo "Angabe der Excel-Datei erforderlich!"  
		WScript.Quit(1)
	End If



Set oArgs = WScript.Arguments
sXLDat = oArgs(0) 'datei zum lesen  
outDat = oArgs(1) 'datei zum speichern  
TABELLE = oArgs(2) 'tabelle der exceldatei  

	If Not fso.FileExists(sXLDat) Then
		WScript.Echo sXLDat & " nicht gefunden!"  
		WScript.Quit(1)
	End If

sXLSDatei = fso.GetFile(sXLDat).Path
sXLSPfad = Left(sXLSDatei, InStrRev(sXLSDatei, "\"))  
sXLSName = Mid(sXLSDatei, InStrRev(sXLSDatei, "\") + 1)  
sDateiName = Left(sXLSName, Len(sXLSName) - 4)

DATEI = outDat 'Zieldatei  
Set oDatei = fso.OpenTextFile(DATEI, 2, True) 'Datei immer neu erstellen  

On Error Resume Next
Set XL = WScript.CreateObject("Excel.Application")  
If Err.Number Then Fehler Err.Number, Err.Description
Set oWB = XL.Workbooks.Open(sXLSDatei)

iZeile = ABZEILE
With oWB.Worksheets(TABELLE)
    		Do While (iZeile < 50)
        		sZeile = .Cells(iZeile, ABSPALTE).Value
        		For i = 2 To ANZSPALTEN
            			sZeile = sZeile & TRENN & .Cells(iZeile, ABSPALTE + i - 1).Value
        		Next
			IF .Cells(iZeile, ABSPALTE).Value = "" THEN  
				sZeile = "	"  
				oDatei.WriteLine sZeile
			END IF
			IF .Cells(iZeile, ABSPALTE).Value <> "" THEN  
				oDatei.WriteLine sZeile
			END IF
				iZeile = iZeile + 1
				IF Zeile > 65536 Then Exit Do
    		Loop
	End With

oDatei.Close
oWB.Saved = True
XL.Application.Quit

Hier:
 With oWB.Worksheets(TABELLE)
sollte die Konstante durch eine Option ersetzt werden, die das aktive Tabellenblatt verarbeitet. Die Konstante "Tabelle" und der Tabellenname wird sonst über das Batch-Skript übergeben.

Des Weiteren habe ich auch noch nicht herausgefunden, wie man als Abbruchbedingung setzen kann, dass er aufhört den Text umzuwandeln, wenn mehr als fünf Zeilen ohne Inhalt sind.
Hier die Zeile:
Do While (iZeile < 50)
.
Ich habe es schon mit Vergleichen der aktuellen Ziele mit der nachfolgenden, der daruaffolgenden etc. versucht, aber das hat nicht funktioniert, leider face-sad. Vielleicht gibt es da eine elegantere Lösung, als immer alle 50 Zeile zu nehmen.

Ich freue mich schon auf eure Tipps! face-smile...

Content-Key: 114763

Url: https://administrator.de/contentid/114763

Printed on: April 24, 2024 at 05:04 o'clock

Member: RackZak
RackZak Apr 27, 2009 at 14:08:01 (UTC)
Goto Top
Das erste habe ich schon einmal gelöst...

...irgendwie hatte es vorher nicht funktioniert jetzt geht es mit:
With oWB.ActiveSheet
Vorher habe ich das OWB vergessen.

Hat noch jemand eine Idee für die Schleife?
Member: bastla
bastla Apr 27, 2009 at 14:19:42 (UTC)
Goto Top
Hallo RackZak und willkommen im Forum!

Ein Ansatz für beides (mit der Möglichkeit, weiterhin auch Tabellennamen übergeben zu können):
Const ABZEILE = 1
Const ABSPALTE = 1
Const ANZSPALTEN = 20
Const TRENN =	"	"  

Dim oDatei
Set fso = CreateObject("Scripting.FileSystemObject")  

If WScript.Arguments.Count < 2 Then 'zumindest Ein- und Ausgabedatei müssen übergeben werden  
    WScript.Echo "Angabe der Excel-Datei erforderlich!"  
    WScript.Quit(1)
End If



Set oArgs = WScript.Arguments
sXLDat = oArgs(0) 'datei zum lesen  
outDat = oArgs(1) 'datei zum speichern  
If WScript.Arguments.Count >2 Then
    TABELLE = oArgs(2) 'tabelle der exceldatei  
End If

If Not fso.FileExists(sXLDat) Then
    WScript.Echo sXLDat & " nicht gefunden!"  
    WScript.Quit(1)
End If

sXLSDatei = fso.GetFile(sXLDat).Path
sXLSPfad = Left(sXLSDatei, InStrRev(sXLSDatei, "\"))  
sXLSName = Mid(sXLSDatei, InStrRev(sXLSDatei, "\") + 1)  
sDateiName = Left(sXLSName, Len(sXLSName) - 4)

DATEI = outDat 'Zieldatei  
Set oDatei = fso.OpenTextFile(DATEI, 2, True) 'Datei immer neu erstellen  

On Error Resume Next
Set XL = WScript.CreateObject("Excel.Application")  
If Err.Number Then Fehler Err.Number, Err.Description
Set oWB = XL.Workbooks.Open(sXLSDatei)

iZeile = ABZEILE
If TABELLE <> "" Then  
    Set WS = oWB.Worksheets(TABELLE)
Else
    Set WS = oWB.ActiveSheet
End If

With WS
    Do While iLeer < 5
        sZeile = .Cells(iZeile, ABSPALTE).Value
        For i = 2 To ANZSPALTEN
            sZeile = sZeile & TRENN & .Cells(iZeile, ABSPALTE + i - 1).Value
        Next
        If .Cells(iZeile, ABSPALTE).Value = "" THEN  
            sZeile = "	"  
            iLeer = iLeer + 1 'Zähler für leere Zellen erhöhen  
        Else
            iLeer = 0 'Letzte Zelle war nicht leer - Zählung rücksetzen  
        End If
        oDatei.WriteLine sZeile

        iZeile = iZeile + 1
        If iZeile > 65536 Then Exit Do
    Loop
End With

oDatei.Close
oWB.Saved = True
XL.Application.Quit
Grüße
bastla
Member: RackZak
RackZak Apr 27, 2009, updated at Oct 18, 2012 at 16:38:04 (UTC)
Goto Top
Klasse!

Wie immer bin ich begeistert face-smile)))...

Vielen Dank!

P.S. Wenn du dich erinnerst hast du das Gerüst mal gebastelt....

Hier der Link von 2007:

Batch-Datei um Excel-Datei in Text-Datei zu wandeln

Kann man den Abbruch nicht auch mit mehreren Bedingungen machne? Zum Beispiel:

 Do While (.Cells(iZeile1, ABSPALTE).Value = "" AND .Cells(iZeile2, ABSPALTE).Value = "" AND .Cells(iZeile3, ABSPALTE).Value = "")   

Ich hatte irgendwie gelesen, dass man in VB mehrere Bedingungen verknüpfen kann (nicht mit AND aber mit einen anderen Junktor, doch hat das bei mir nie funktioniert) Ich würde dann nach jedem durchzählen iZeile1 und iZeile2 und iZeile3 erhöhen, sodass iZeile2=iZeile1+1 und iZeile3=iZeile2+1 ist...

...oder geht das nicht? (nur rein interessehalber, ob ich auf der richtigen Spur war *g*)
Mitglied: 77559
77559 Apr 27, 2009 at 16:36:23 (UTC)
Goto Top
Zitat von @RackZak:
Mal abgesehen von meinem Wahsinnskonstrukt in als Batchfile
(möchte ich so behalten *g*) gibt es eine Möglichkeit in VBS
das aktive Tabellenblatt zu verwenden und keinen festen Namen
anzugeben?

> On Error Resume Next
> Set XL = WScript.CreateObject("Excel.Application")  
> If Err.Number Then Fehler Err.Number, Err.Description
> Set oWB = XL.Workbooks.Open(sXLSDatei)
> 
Hier kannst du doch einfach alle Tabellen durchlaufen und den Bneutzten Bereich abfragen mit:
For Each objWorkSheet In oWB.Sheets
  objWorkSheet.Activate
  Set Datenbereich=objWorkSheet.UsedRange
    ErsteZeile = Datenbereich.Cells(1).Row
    ErsteSpalte = Datenbereich.Cells(1).Column
    LetzteZeile = Datenbereich.Cells(Datenbereich.Cells.Count).Row
    LetzteSpalte = Datenbereich.Cells(Datenbereich.Cells.Count).Column

'  Dein Code hierher  
Next 
Ich habe es schon mit Vergleichen der aktuellen Ziele mit der nachfolgenden, der daruaffolgenden etc. versucht, aber das hat nicht > funktioniert, leider face-sad. Vielleicht gibt es da eine elegantere Lösung, als immer alle 50 Zeile zu nehmen.

S.o.

Gruß
LotPings

PS: Habe das aus alten Code-Schnipseln zusammengesucht, habe im Moment kein MS Office im Zugriff. Also keine Garantie für nichts face-wink
Member: RackZak
RackZak Apr 27, 2009 at 16:57:21 (UTC)
Goto Top
Ist auch gut face-smile. In die Richtung (benutzter Bereich) habe ich auch schon einmal meine Gedanken schweifen lassen, aber ich kann halt kein VB. *G*

Danke!
Member: bastla
bastla Apr 27, 2009 at 17:50:10 (UTC)
Goto Top
Hallo RackZak!

Abgesehen davon, dass sich die Schleifenbedingung von "While" auf "Until" ändern würde, könntest Du das natürlich auch mit AND (und etwas abgekürzt, da "Value" per Default verwendet wird) lösen:
Do Until (.Cells(iZeile, ABSPALTE) = "" AND .Cells(iZeile+1, ABSPALTE) = "" AND .Cells(iZeile+2, ABSPALTE) = "")
Wie Deine Anforderung - 5 leere Ze(i/l)len ist als Abbruchbedingung doch eher ungewöhnlich - genau aussieht, hast Du ja nicht wirklich beschrieben, daher kämen natürlich (zumindest als Berechnungsbasis) die von LotPings aufgezeigten "UsedRange"-Varianten ebenso infrage wie etwa
.Range("A65536").End(xlUp).Row
zur Ermittlung der letzten verwendeten Zeile der Spalte A (unter Excel <= 2003) oder vielleicht doch auch nur die einfache Version
Do While .Cells(iZeile, ABSPALTE) <> ""
Grüße
bastla
Member: RackZak
RackZak Apr 27, 2009 at 18:26:43 (UTC)
Goto Top
Genauso hatte ich mir das vorgestellt.

In der ursprünglichen Variante hattest du angegeben, dass wenn eine leere Zeile ist, dass er dann die Schleife beendet. (sofern ich es richtig verstanden hatte - Programmierung ist nicht wirklich mein Gebiet)

Bei mir kann es sein, dass mehrere leere Zeilen existieren, aber nie mehr als fünf (deswegen so komische Abbruchbedingungen)...

...das es eine Alternative gibt, in dem man die "UsageRange"-Variante verwende, war mir nicht klar (sonst wäre ich hier ja das VB-Genie ;) ...) aber es ist natürlich besser als meine Variante. (Unwissenheit halt *g*)

Die Until-Schleife hatte ich auch gefunden, aber das hat irgendwie nicht fkt. Mit deinem Aufbau klappt es aber perfekt face-smile.

Also vielen Dank nochmal! Fünf von fünf Sternen für Schnelligkeit und die guten Tipps! face-smile

Gruß

RackZak