Forum

Makro (schon wieder)

Gesperrt

Seite: 1

Autor Beitrag
Mitglied
Registriert: Mar 2005
Beiträge: 29
Hallo,

es ist mir ja langsam ein wenig peinlich aber ich brauche schon wieder Hilfe in Excel. Ich habe mir da etwas ausgedacht, habe aber keine Ahnung, wie ich es umsetzen kann.

Also es geht um folgendes:

Ich habe gut 200 Datein deren Inhalt in ein Programm eingespielt werden muss. Diese Dateien haben aber nicht die richtige "Form" um sie einspielen zu können. Jetzt habe ich mir eine Datei mit der richtigen "Form" aufgebaut. Mit einem Makro möchte ich nun die benötigten Daten aus der Datei in die neue Form ziehen. Problem dabei ist, dass die 200 Datein zwar alle die gleichen Spalten haben aber unterschiedlich viele Zeilen.

Zum Ablauf des Makro:

Das Makro soll in der neuen Datei eingebaut werden, also in diejenige, die die passende Form enthält, um die Daten in das Programm einspielen zu können. Ich nenne die Datei jetzt der Einfachheit halber mal Plan_1. Also Plan_1 enthält die neue Spaltenanordnung. Nach einem klick auf einen Button startet das Makro. Es soll sich ein Fenster öffnen, das den Ordner mit den 200 Dateien enthält die in die neue Form gebracht werden sollen. Ich makiere die Datei und die Daten werden in Plan_1 kopiert. Problem bei der Sache ist, wie vorher schon erwähnt, dass die 200 Dateien unterschiedlich viele Zeilen haben. Sind alle Daten nach Plan_1 kopiert soll die Datei automatisch in einem neuen Ordner gespeichert werden. Dabei soll Plan_1 jedes mal automatisch unter einem neuen Namen speichern. Beispiel: Eine der 200 Dateien heißt Umsatz2006, dann soll die Datei automatisch als Umsatz2006_Plan_1 gespeichert werden. Gibt es da eine Möglichkeit, dass das Makro jedes mal diesen Zusatz an den ursprünglichen Dateinamen anhängt?

Wenn die Datei gespeichert wurde, sollen alle Zeilen in Plan_1 wieder gelöscht werden und ein Fragefenster aufpoppen. z.B. "Weitere Dateien umwandeln?" =>ja oder nein.

Klickt man dann auf ja, beginnt das ganze von vorn. Bei nein wird das Makro beendet.

Ich hoffe mir kann wieder geholfen werden :-). Mein Problem sind mal wieder hauptsächlich die richtigen Befehle. Vielen Dank schon mal im Voraus.
Mitglied
Registriert: Apr 2004
Beiträge: 7407
Ort: Erfurt
Also, ich versuche mal ein paar Tips zu den Befehlen zu geben... Du willst offenbar einen Dialog, wie er durch Datei --> Offnen in den meisten Programmen zu haben ist, ja? Hierfür mußt Du sagen

[code:1]Datei = Application.GetOpenFilename("Fenstertitel (*.ext), *.ext")[/code:1]

".ext" ist hierbei die Dateimaske mit dem Zusatz. "*.*" listet bekanntlich alle Dateien. Prüfe das Vorhandensein der angeklickten Datei mit

[code:1]If Datei <> False Then
[...]
end if[/code:1]

Zum Lesen aus der Datei muß Du einfach einen Kanal in das Dateisystem öffnen:

[code:1]Open Datei For Input As #1[/code:1]

Lesen der einzelnen Zeilen dann:

[code:1]Input #1, x[/code:1]

Wobei "x" die Variable ist, und Du natürlich auf die entsprechende Dateitypdefinition acht geben mußt.

Ach ja, mit einem Dateisystemobjekt kannst Du das Vorhandensein von Dateien prüfen:

[code:1]Set fs = CreateObject("Scripting.FileSystemObject")
[...]
If fs.fileexists(Datei) Then [...][/code:1]

Hier muß natürlich in der Variable "Datei" der Dateiname stehen; der kann z.B. auf die oben beschriebene Weise da reinkommen (oder auch automatisch generiert werden). Wenn deine 200 Dateien irgendeinem Muster folgen, kann das Programm z.B. die Dateinamen der Reihe nach innerhalb einer Schleife (Do...Loop, for...Next oder sowas) generieren udn auf diese Art auf Vorhandensein prüfen.

Wenn ich Dich weiter richtig verstehe, willst Du eine unbekannte Zahl von Zeilen anfassen. Mach das mal so:

[code:1]i=1
Do
[irgendwassverarbeiten]
i=i+1
Loop while Cells(i,j)<>""[/code:1]

i ist hier der Zilenzähler; da meine Schleife nicht abweisend ist, wird vorausgesetzt, daß in der 1. Zeile imemr etwas steht. j ist die Spalte, in der Du was machen oder lesen willst. Mit Cells(i,j)<>"" prüfst Du, ob die jeweils folgende Zelle noch besetzt ist. Wenn ja, wird die Schleife fortgesetzt. Die Schleife setzt voraus, daß keine der aufzurufenden Dateien genau 65.536 Zeilen hat, denn dann würde am Schluß kein Ende gefunden und ein Fehler bei der (nicht mehr vorhandenen) 65.537ten Zeile entstehen. Sollte das verhindert werden, könntest Du die Loop-Zeile modifizieren:

[code:1]Loop while Cells(i,j)<>"" and i<=65536[/code:1]

Hilft Dir das erstmal weiter?
Mitglied
Registriert: Mar 2005
Beiträge: 29
Hallo Harry,

danke erstmal für die Tips. Ich habe heute ein paar Stunden daran herum probiert, aber leider hat es nicht funktioniert. Das einzige, was funktioniert hat, war das Öffnen des Datei-Auswahlfensters. Also das Datei = Application.GetOpenFilename......

Ab dem Input #1, x hat es nicht mehr geklappt. Das x soll ja für die Dateitypdefinition stehen. Leider konnte ich damit nichts anfangen. Muss ich da angeben, dass es eine Excel-Datei ist? Hatte ich schon mal erwähnt, dass ich ein blutiger Anfänger bin, was Makros betrifft? :-)

Wenn ich nun eine der 200 Datein geöffnet habe, wie bekomme ich dann die Daten von dort in meine vorbereitete Datei mit der richtigen Struktur? Diesen Punkt hatte ich noch nicht verstanden. Ich muss doch vorher die Spalten angeben, aus denen ich die Daten holen möchte oder? Ich glaube ich hatte auch noch vergessen zu erwähnen, dass in den Dateien, aus denen ich die Daten holen möchte, auch Leerzeilen sind, die ich überspringen möchte. Diese sollen also nicht mit kopiert werden.

Wenn ich nun die Daten kopiert habe möchte ich, dass die Datei automatisch gespeichert wird und das soll so funktionieren: Angenommen die Datei heißt ursprünglich Umsatz2006.xls, dann soll sie als Umsatz2006-Plan.xls gespeichert werden. Es soll also immer das -Plan an den ursprünglichen Dateinamen angehängt werden.

Kannst Du vielleicht auch ein Buch für diese Makrothematik ? Ich glaube ich sollte mich da mal einlesen, sonst wird das nie was.

Hoffe Du kannst mir nochmal helfen. Vielen Dank dafür im Voraus
Mitglied
Registriert: Apr 2004
Beiträge: 7407
Ort: Erfurt
Hi,

Zitat
Ab dem Input #1, x hat es nicht mehr geklappt. Das x soll ja für die Dateitypdefinition stehen.


Nein, das x ist die Variable, über die durch den zuvor mit Open eröffneten Kanal Daten eingelesen werden. Die daten stehen in der Variable x.

Zitat
Muss ich da angeben, dass es eine Excel-Datei ist?


Die oben skizzierte Methode mit Input erlaubt, Daten aus beliebigen Dateien einzulesen; allerdings mußt du das Datenformat selbst handhaben. Wenn Du versucht, Excel-Dateien auf diese Art zu öffnen, kriegst du nur Datensalat rüber, weil die Tabelleninhalte nicht im Klartext in der XLS stehen. Die Application-Methode eignet sich i.d.R. nur für ASCII-Daten. Ein möglicher Weg wäre, aus allen 200 Daten, aus denen Du offensichtlich Daten exportieren willst, die Informationen in TXT-Dateien zwischenzulagern. Dann kannst du sie auf die beschriebene Art importieren. Hierzu müßtest du ein Makro schreiben, das von den 200 Dateien aufgerufen wird. Das ist möglich, aber etwas sackstandig. Es könnte in diesem Fall einfacher sein, eine Access-Datenbank zu machen, die die Daten in 200 Tabellen zwischenspeichert. Access kann Excel als Datenquelle definieren. Du mußt Dich dann u.U. nicht mit der Application-Methode rumschlagen; allerdings wäre es dann erforderlich, die systeminternen Variablen der Datei COMDLG32.DLL zu benutzen. Ich bin nicht sicher, ob ich Dir hier zeigen sollte, wie Du das mit einem öffentlichen Modul anstellst... Du kannst es aber in meinem Einnahme-Überschuß-Rechner ausprobieren, woe Kundendaten z.B. aus Bestellungen direkt per mausklick importiert werden können. Außerdem ist das umgehen mit Tabellen in Access komplexer als in Excel: Während Du in Excel mit Schleifen und Cells(i,j) arbeiten kannst, werden es in Access Variablen, die als database definiert werden müssen, und SQL-Kommandos, die viele Zeilen gleichzeitig behandeln - eher unanschaulich, aber auch viel (!) schneller.

Bevor Du dich aber mit der Frage herumschlägst, wie Du Leerzeilen ausblenden und die Datenstruktur analysieren kannst (eigentlich ganz einfach), mußt Du Dich mit dem Datenimport befassen. Das mit den Leerzeilen ist dann vermutlich ohnehin kein problem mehr, weil man das u.a. in einer SQL-Zeile mit dem WHERE-Clause machen kann.

Ein grundsätzlicher Rat: Es ist vermutlich eine gute Idee, die Datenaustausch, wenn er absehbar ist, vorher zu planen um nachher nicht festzuhängen. ich würde daher die reine Excel-Version mit Zwischendateien in ASCII vorziehen; das ist - auch um es selbst zu lernen - viel einfacher als Access, aber bei großen Datenmengen etwas langsam.

Zitat
Kannst Du vielleicht auch ein Buch für diese Makrothematik ?


Hmmm... ich habe nie eines benutzt, aber von DataBecker und ähnlichen Verlagen gibt es gewiß eine Zahl guter Bücher.
Mitglied
Registriert: Mar 2005
Beiträge: 29
Hallo,

danke erstmal für den Rat. Ich habe heute mal versucht die Daten in eine Textdatei umzuwandeln, was auch geklappt hat, und dann die Daten in das Excel zu kopieren. Die schwierigste Sache scheint wirklich das Importieren der Daten zu sein. Das Makro sah dann so aus:

Klick auf Button:

Datei = Application.GetOpenFilename("Fenstertitel (*.ext), *.ext")
If Datei <> False Then
[...]
end if
Open Datei For Input As #1
Input #1, x

Ich habe hier das End Sub und Click_Button o.ä. nicht mit hingeschrieben. Irgendwie scheint der Kanal geöffnet zu werden aber es wird nix angezeigt, ist ja auch logisch, denn da steht ja noch nicht wo. Trotzdem kam ich mal wieder nicht weiter :-(. Also mal angenommen ich wandle die 200 Exceldateien in Textdateien um, dann müßte ich es doch mit diesem obenstehenden Befehl importieren können oder? Wenn es eine Textdatei ist, kann ich dann trotzdem noch bestimmte Spalten der Textdatei importieren oder kann ich dann nur noch die ganze Datei rüberziehen? Im Moment steige ich hier gar nicht mehr durch und so langsam verzweifle ich ein wenig. Heute habe ich stundenlang in der Hilfedatei gelesen, was mich aber keinen mm weiter gebracht hat.

Vielleicht kannst Du ja nochmal etwas dazu schreiben? Vielen Dank im Voraus.
Mitglied
Registriert: Apr 2004
Beiträge: 7407
Ort: Erfurt
Moin,

mit

[code:1]Input #1, x [/code:1]

wird jeweils eine Zeile der Textdatei importiert. Falls die Zeile leer ist, ist auch x leer. Man kann also mit einem Befehl wie

[code:1]if x="" then ...[/code:1]

auf den Import einer leeren Zeile prüfen. Die Inputs gehen sequentiell vom ersten zum letzten Eintrag und mit eof kann geprüft werden, ob man das Ende erreicht hat:

[code:1]Do While not EOF(1)
Input #1, x
[...]
Loop[/code:1]

importiert die gesamte Datei. "[...]" steht natürlich für die Bearbeitung, die die einzeln nacheinander importierten Elemente der geöffneten Datei bearbeitet, also sie z.B. in die aktuelle Excel-Datei schreibt.
Mitglied
Registriert: Mar 2005
Beiträge: 29
Hallo Harry,

es bleibt eigentlich gleich am Anfang hängen. Ich denke es liegt daran, dass dieser Kopiervorgang so häufig hintereinander ausgeführt wird. Ich habe das mit nur einem Kopiervorgang getestet, also nur eine Spalte markieren, kopieren und einfügen und da ging es. Weiß jetzt nicht, was ich ändern muss.

Gruß

BWL-Studi
Mitglied
Registriert: Apr 2004
Beiträge: 7407
Ort: Erfurt
Hi,

Zitat
es bleibt eigentlich gleich am Anfang hängen. Ich denke es liegt daran, dass dieser Kopiervorgang so häufig hintereinander ausgeführt wird.


Nein, glaube ich kaum - bedenke, daß VBA auch am Anfang stehenbleibt, wenn der Fehler ganz woanders steht. Schon ein

[code:1]datsuch = Application.GetOpenFilename[/code:1]

kann eigentlich nicht sein - die Methode braucht immer Parameter. Das darf nie so isoliert im Nichts herumstehen. Falls Du Deine Dateinamen schon weißt. und diese feststehen sollen, brauchst du diese Methode gar nicht.
Mitglied
Registriert: Mar 2005
Beiträge: 29
Guten Morgen Harry,

eigentlich hat das mit dem datsuch.... ganz gut funktioniert. Im Übrigen weiß ich nicht, wie die Dateien heißen, da es ja so viele sind. Diese haben alle unterschiedliche Namen. In meinen Versuchen hat das mit dieser Methode ganz gut geklappt. Man klickte den Button, dann öffnete sich das Dateiauswahlfenster und man konnte die Datei auswählen. Daran liegts dann wahrscheinlich nicht. Ich könnte Dir das Makro auch mal mailen, wenn Du willst. Vielleicht würde das schneller gehen mit der Fehlersuche?

Wünsche einen schönen Tag.

Gruß

BWL-Studi
Mitglied
Registriert: Apr 2004
Beiträge: 7407
Ort: Erfurt
Hi,

OK, Du kannst mir das ja schicken, aber die nächsten drei Tage sind Lehrveranstaltungen. Kann Dir nicht versprechen, daß es gleich wird...


Gesperrt

Seite: 1

Parse-Zeit: 0.062 s · Memory usage: 1.48 MB · Serverauslastung: 1.40 · Vorlagenbereich: 2 · SQL-Abfragen: 9