Vereinfachung eines VBA Macros Ecxel 2010

Hi - ich brauche eine Vereinfachung meines bisherigen Macros. Anzusehen unter : https://dl.dropboxusercontent.com/u/10118892/TEST.xlsm - Das ist eine Excel Mappe „TEST“ in der 2 Tab Blätter „TN-List“ und „Protokoll“ sowie das dazu gehörige Macro vorhanden sind. Die TN-List ist eine konstanten Änderungen unterworfene Liste von Namen / Nummern und Bezeichnungen. Derzeit besteht sie aus (im Orginal) 170 Datensätzen ( 1Satz pro Zeile). Das Macro beschreibt jede einzelne Zeile und Zelle die in das Tab-Blatt " Protokoll" übernommen werden soll. Gibt es eine Routine um nicht so lange Macrolisten zu erstellen? und gibt es einen Automatismus der das Macro beendet, wenn keine Daten mehr in TN-List vorhanden sind?
Danke im Voraus

https://dl.dropboxusercontent.com/u/10118892/TEST.xlsm - Das
ist eine Excel Mappe „TEST“ in der 2 Tab Blätter „TN-List“ und
„Protokoll“ sowie das dazu gehörige Macro vorhanden sind. Die
TN-List ist eine konstanten Änderungen unterworfene Liste von
Namen / Nummern und Bezeichnungen. Derzeit besteht sie aus (im
Orginal) 170 Datensätzen ( 1Satz pro Zeile). Das Macro
beschreibt jede einzelne Zeile und Zelle die in das Tab-Blatt
" Protokoll" übernommen werden soll. Gibt es eine Routine um
nicht so lange Macrolisten zu erstellen? und gibt es einen
Automatismus der das Macro beendet, wenn keine Daten mehr in
TN-List vorhanden sind?

Hallo Franz,

Option Explicit

Sub Makro1()
Dim Zei As Long, wksTN As Worksheet
Set wksTN = Worksheets("TN-List")
Zei = wksTN.Range("B5").End(xlDown).Row
With Worksheets("Protokoll")
 For Zei = 5 To Zei
 .Range("B11").Value = wksTN.Cells(Zei, 2).Value
 .Range("D11").Value = wksTN.Cells(Zei, 3).Value
 .Range("F11").Value = wksTN.Cells(Zei, 4).Value
 .Range("J11").Value = wksTN.Cells(Zei, 5).Value
 .Range("G12").Value = wksTN.Cells(Zei, 8).Value
 .Range("J8").Value = wksTN.Cells(Zei, 9).Value
 .Range("C14").Value = wksTN.Cells(Zei, 12).Value
 .Range("G14").Value = wksTN.Cells(Zei, 13).Value
 .PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
 Next Zei
 .Range("B11, D14, F11, J11, G12, J8, C14, G14").ClearContents
End With
End Sub

Gruß
Reinhard

Kleine Anmerkung
Hallo Reinhard,

For Zei = 5 To Zei

Hast du das getestet? Ich glaub, 2x Zei geht nicht.

Gruß, Andreas

Hallo Andreas,

For Zei = 5 To Zei

Hast du das getestet?

ja, funktioniert.

Ich glaub, 2x Zei geht nicht.

Ich glaub einer geht noch also 3-mal:
For Zei = 5 To Zei Step Zei (ungetestet)

Gruß
Reinhard

Hallo Reinhard,

For Zei=5 to Zei

oder auch

For Zei=5 to Zei Step Zei

Dass das rein syntaktisch geht, ist mir klar.
Aber meiner Meinung nach (und nach meinen Tests) gibt das rein logisch nur einen Schhleifen-Durchlauf:
Egal, auf welchen Wert Zei vor der Schleife gesetzt wird, mit
For Zei = 5 To …
wird Zei auf 5 gesetzt.
Dann wird die Schleife 1x durchlaufen.
Danach wird getestet, ob Zei gleich dem Endwert der Scheife (also Zei) ist. Das ist WAHR.
Also ist die Scheife beendet.

Also: Egal ob
For Zei=5 to Zei
oder
For Zei=5 to Zei Step Zei,
die Schleife wird immer nur 1x durchlaufen. Und das war ja wohl nich im Sinne des Erfinders, oder?

Gruß und noch einen schönen, schleifenfreien Abend,
Andreas

Hallo Andreas,

For Zei=5 to Zei
oder auch
For Zei=5 to Zei Step Zei

Dass das rein syntaktisch geht, ist mir klar.
Aber meiner Meinung nach (und nach meinen Tests) gibt das rein
logisch nur einen Schhleifen-Durchlauf:

Nach deinen Tests? Zeig mal die Codes bitte.

Egal, auf welchen Wert Zei vor der Schleife gesetzt wird, mit
For Zei = 5 To …
wird Zei auf 5 gesetzt.

Ja.

Dann wird die Schleife 1x durchlaufen.
Danach wird getestet, ob Zei gleich dem Endwert der Scheife
(also Zei) ist. Das ist WAHR.

Nein, das ist falsch. Zei wird mit dem Endwert der For-Schleife verglichen
und dessen Wert ist der Wert den Zei hatte vor der For Schleife.

Nachfolgend 2 Codes die wohl überzeugen sollten.

Gruß
Reinhard

Option Explicit

Sub tt2mal()
Dim Zei As Long
Zei = 5
For Zei = 1 To Zei
 MsgBox Zei
Next Zei
End Sub

Sub tt3mal()
Dim Zei As Long
Zei = 5
For Zei = -1 To Zei Step Zei
 MsgBox Zei
Next Zei
End Sub

Des Rätsels Lösung
Hallo Reinhard,

es hängt damit zusammen, ob und wie die Variable dimensioniert wird:

Sub nurEinmal()
 zei = 5
 For zei = 1 To zei
 MsgBox zei
 Next zei
End Sub

Sub auchNurEinmal()
 Dim zei

 zei = 5
 For zei = 1 To zei
 MsgBox zei
 Next zei
End Sub

Sub fuenfMal()
 Dim zei As Long

 zei = 5
 For zei = 1 To zei
 MsgBox zei
 Next zei
End Sub

… und wieder was dazugelernt. Ist immer wieder schön hier.

Gruß, Andreas

Nachtrag
mit
Dim zei as Variant
läuft es auch nur 1x. Ist ja glaube ich das gleiche wie
Dim zei

Gruß, Andreas

For Schleife wird nur einmal ausgeführt b. Variant
Hallo Andreas,

es hängt damit zusammen, ob und wie die Variable dimensioniert
wird:

ja. Danke dir auch daß du „nachgebohrt“ hast :smile:
Und ja, nach eine der drei Varianten:

Dim Zei
Dim Zei
Dim Zei as Variant

hat Zei den Datentyp Variant. Und dann wird die For-Schleife nur einmal ausgeführt.
Mir vollkommen schleierhaft warum das so ist.

… und wieder was dazugelernt. Ist immer wieder schön hier.

Geht mir genauso.

Gruß
Reinhard

Hallo Andreas,

'n abend Reinhard,

ja. Danke dir auch daß du „nachgebohrt“ hast :smile:

Dafür sind wir hier da.

Und ja, nach eine der drei Varianten:

Mir vollkommen schleierhaft warum das so ist.

Vielleicht erzeugt
Dim
oder
Dim … as Variant
nur eine „Erinnerung“, dass da ein „Variablenname“ angelegt wurde, aber noch kein Speicherbereich.
Deswegen kann auch der Endwert der Scheife noch nirgends gespeichert werden.
Erst wenn ein „fester“ Dateintyp festgelegt wird, wird auch Speicher allokiert, in dem der Endwert der Schleife abgelegt werden kann. Nur so ein Verdacht. Bill Gates wird es dir sagen, wenn du ihn anrufst :wink:

… und wieder was dazugelernt. Ist immer wieder schön hier.

Geht mir genauso.

Freut mich.

Gruß
Reinhard

und Gruß nach Frankfurt
Andreas

Hallo Andreas,

For zei = 1 To zei


> Next zei

Dieses Konstrukt ist als solches schon unzulässig!

Ein typischer Interpreter wird immer den aktuellen Wert von zei verwenden.

Bei einem Compiler hängt es dann von der verwendeten Optimierung ab, ob der Vergleich mit einer Kopie oder dem Original von zei durchgeführt wird.

Die Abhängigkeit vom Variablentyp ist auch mehr oder weniger Zufall. Das hängt davon ab wie die Variablen intern verwaltet werden, bzw. auf sie zugegriffen wird, bzw. wie die Register der CPU verwaltet werden.
Wen du mehr Rechnerei, mit zusätzlichen Variablen in der Schlaufe hast, kann sich das Verhalten schon wieder ändern!

Auch dürften sich eine 32-Bit und eine 64-Bit Version auch schon im Verhalten unterscheiden.

In deinem Fall musst du damit rechnen, das unterschiedliche Excel-Versionen dies sogar unterschiedlich handhaben.

Garantierte Resultate bekommst du nur mit:

For i = 1 To zei


> Next i

MfG Peter(TOO)

Hallo Andreas,

Hallo Peter,

vielen Dank für die Hintergrundinfos

For zei = 1 To zei

Next zei

Dieses Konstrukt ist als solches schon unzulässig!

Ich hatte das auch zu ersten Mal hier bei Reinhard gesehen und mich gewundert. Deswegen mein Posting.

Ein typischer Interpreter wird immer den aktuellen Wert von
zei verwenden.

Das war auch mein Verständnis. Ich konnte mich nur ganz dunkel an meine fernen C-Zeiten erinnern. Irgendwie war es da glaube ich anders.

MfG Peter(TOO)

Gruß, Andreas

Vielen Dank Reinhard und auch Dir Andreas für Eure Mühen. Ich werde jetzt erstmal versuchen die ganzen Vorschläge und Anmerkungen in ein Muster zu setzen und es dann ausprobieren - braucht halt seine Zeit. Deshalb nochmals Vielen Dank .-))
Franz

Hallo Andreas,

Vielleicht erzeugt
Dim
oder
Dim … as Variant
nur eine „Erinnerung“, dass da ein „Variablenname“ angelegt
wurde, aber noch kein Speicherbereich.
Deswegen kann auch der Endwert der Scheife noch nirgends
gespeichert werden.
Erst wenn ein „fester“ Dateintyp festgelegt wird, wird auch
Speicher allokiert, in dem der Endwert der Schleife abgelegt
werden kann. Nur so ein Verdacht.

ich lese was du so schreibst, das was Peter schreibt.
Richtig er/geklärt ist das damit m.E. noch nicht.
Ich hab leider kein VB6.0 aber immerhin VB5.0. Mit VB5.0 habe ich mir
eine exe erstellt die nur die For-Schleife beinhaltet.

Dort geschieht es analog zu Vba. Ist also kein VBa-Problem sondern ein
VB Problem.
Die Exe ist natürlich kompiliert, da wird nix mehr interpretiert wie bei
Vba.
Aaah, grad ne Idee. Mal schauen/nachfragen ob diese Seltsamkeit auch
in (VB).Net auftritt. Schau halt bei Interesse ins .Net-Brett.

Bill Gates wird es dir sagen, wenn du ihn anrufst :wink:

Besorg mir die Nummer. Brauchst ja nur wie Snowdown 3 Monate zur NSA
zu gehen, dann kommste an alle Nummern.

Gruß
Reinhard

Vielen Dank Reinhard und auch Dir Andreas für Eure Mühen. Ich
werde jetzt erstmal versuchen die ganzen Vorschläge und
Anmerkungen in ein Muster zu setzen und es dann ausprobieren -
braucht halt seine Zeit. Deshalb nochmals Vielen Dank .-))

Hallo Franz,

du Armer :frowning: Ich hoffe du mußtest nicht allzusehr unter mir und Andreas
leiden :smile:
Uns war es, weil wir Excel mögen, wichtig uns über eine Winzigkeit sachlich
fachlich auszutauschen und ja, auf dich haben wir keine Rücksicht genommen.
Aber ist nicht bös gemeint gewesen. Passiert halt wenn man iws ins Plaudern
kommt.

Deiner Anfrage bzw. einer Lösung dafür war das nicht abträglich.
Hättst ja nicht mitlesen müssen *grins*
Völlig korrekt was du jetzt sagst und machst. Setz irgendwas von dem hier
gesagten um, teste und berichte.

Zu dritt kriegen wir da sicher die Lösung hin.

Gruß
Reinhard

Hallo Reinhard,

Ich hab leider kein VB6.0 aber immerhin VB5.0. Mit VB5.0 habe
ich mir
eine exe erstellt die nur die For-Schleife beinhaltet.

Dort geschieht es analog zu Vba. Ist also kein VBa-Problem
sondern ein
VB Problem.
Die Exe ist natürlich kompiliert, da wird nix mehr
interpretiert wie bei
Vba.

Ich habs gerade mal in VB6.0 getestet: Da ist es genau so wie in VBA.
Ich stöbere gerade mal noch in den Weiten des I-net, ob es da jemanden gibt, der mehr weiß.

Aaah, grad ne Idee. Mal schauen/nachfragen ob diese
Seltsamkeit auch
in (VB).Net auftritt. Schau halt bei Interesse ins .Net-Brett.

Scheint ja bisher nicht so sehr viel erbracht zu haben.

Bill Gates wird es dir sagen, wenn du ihn anrufst :wink:

Besorg mir die Nummer. Brauchst ja nur wie Snowdown 3 Monate
zur NSA
zu gehen, dann kommste an alle Nummern.

Ich hab aber keine Lust, bei Putin im Wartesaal zu sitzen. Mach du das mal … :wink:

Gruß
Reinhard

Gruß, Andreas

Auswärts Hilfe gesucht
Hallo Reinhard,

ich hab mal in ActiveVB gepostet:
http://foren.activevb.de/forum/vba/thread-25305/beit…
Mal sehen, ob da was kommt.

Gruß, Andreas

Hallo Reinhard & Andreas,

ich hab mal in ActiveVB gepostet:
http://foren.activevb.de/forum/vba/thread-25305/beit…
Mal sehen, ob da was kommt.

Wie ich schon gesagt habe:
Das Verhalten ist nicht definiert!

Hier die Beschreibung von MS:
http://msdn.microsoft.com/de-de/library/5z06z1kb%28v…

Definiert ist nur, dass VB den Ausdruck für end nur einmal berechnet und dann mit diesem Wert vergleicht.
Aber, dies gilt nur für VB, andere BASIC können das anders handhaben!

FOR count = start TO end
 [...]
NEXT count

Ergibt also folgenden Pseudocode:

1. **start** berechnen und **count** zuweisen
2. **end** berechnen
3. wenn **count** \> **end** , dann GOTO 7.
4. [...]
5. **count** = **count** + 1
6. GOTO 3.
7. weiter gehts ....

Nun ist aber nicht festgeleg ob die Reihenfolge 1.-2. oder 2.-1. ist.
Nur das macht schon den Unterschied, ob die Schlaufe 5x oder 1x ausgeführt wird.

Euer Konstrukt sieht folgendermassen aus:

count = 5
FOR count = 1 TO count
 [...]
NEXT count

Pseudocode:

0. count = 5
1. count = 1
2. end = count
..... Die Schlaufe wird 1x mal durchlaufen

oder

0. count = 5
1. end = count
2. count = 1
..... Die Schlaufe wird 5x mal durchlaufen

Das Verhalten von BASIC ist für euren Fall einfach nicht definiert!

Der Unterschied in Abhängigkeit des Variablentyps, liegt wohl darin begründet, dass je nach Typ unterschiedlich darauf zugegriffen werden muss, vermutlich liegt der Unterschied sogar daran, dass bei Integer direkt über einen Maschinenbefehl zugegriffen wird und auf die anderen Typen über Unterprogramme (Zumindest bei VARIANT geht es nur über Unterprogramme).

MfG Peter(TOO)

Hallo Reinhard & Andreas,

Hallo Peter

Das Verhalten von BASIC ist für euren Fall einfach nicht
definiert
!

Der Unterschied in Abhängigkeit des Variablentyps, liegt wohl
darin begründet, dass je nach Typ unterschiedlich darauf
zugegriffen werden muss, vermutlich liegt der Unterschied
sogar daran, dass bei Integer direkt über einen
Maschinenbefehl zugegriffen wird und auf die anderen Typen
über Unterprogramme (Zumindest bei VARIANT geht es nur über
Unterprogramme).

So ähnlich hatte ich Wolfgang bei ActiveVB auch vetstanden.
Auch wenn mit noch nicht so klar ist, wieso man Variant mit Object gleichsetzen kann und was die Iterationsschnittstelle eines Objektes ist.

Gruß, Andreas

MfG Peter(TOO)

Hallo Andreas,

Auch wenn mit noch nicht so klar ist, wieso man Variant mit
Object gleichsetzen kann und was die Iterationsschnittstelle
eines Objektes ist.

Variant ist eigentlich gar kein Datentyp sondern ein Element, welches jeden Datentyp beherbergen kann.
Insofern entscheidet dann der Datentyp welche Operation z.B. bei einer Addition ausgeführt wird. Und für eigene Datentypen muss dann Variant auch die passenden Routinen mitbringen.

Iterationsschnittstelle
Diese legt fest wie die Werte durchgezählt werden.
Bei Ganzzahlen ist das noch einfach, auf die 0 folgt die 1, dann 2, 3, 4…

Bei Buchstaben ist es auch noch relativ einfach, hier entspricht die Abfolge z.B. dem ASCII-Code. Aber wenn deine Mühle EBCDIC als Zeichensatz verwendet bekommst du andere Resultate und die Rechnerei ist etwas komplizierter:
http://de.wikipedia.org/wiki/EBCDIC#EBCDIC_500

Aber nach welcher Regel zählst du Namen oder Farben durch?

Wenn man die Farben als Enumerations-Typ definiert, kann man bei dessen Definition dann die Farbreihenfolge festlegen, z.B. rot, gelb, grün.
Daraus ergibt sich dann, dass
gelb+1 = grün
Dazu braucht es aber eine Funktion, welche dies ausführt.
Dazu gehört auch
gelb-1
grün-2
rot+2

Dies ist dann die Iterationsschnittstelle für dieses Objekt.

MfG Peter(TOO)

2 Like