For-Each in Range und Array

Informationen und Beispiele zu den hier genannten Dialog-Elementen:
MsgBox
Bild

Betrifft: For-Each in Range und Array
von: Daniel
Geschrieben am: 15.07.2015 18:30:46

Hallo
mal ne Frage zur For-Each-IN-Schleife.
Wenn ich diesen Schleifentyp auf eine Range anwende, dann kann ich nicht nur den Wert lesen, sonderen auch
- den Zellwert verändert zurückschreiben
- mit .Offset() auf Nachbarzellen zugreifen
- mit .Row und .Column Zeilen- und Spaltenindex abfragen.
geht sowas auch, wenn die Schleife über ein einfaches Array läuft?
oder muss man, wenn man mehr will als nur den Wert auslesen, die Schleife über die Indexnummern erstellen?
Gruß Daniel

Bild

Betrifft: AW: For-Each in Range und Array
von: Gerd L
Geschrieben am: 15.07.2015 20:51:31
Hallo Daniel,
machst du ... oder muss man ...
Gruß Gerd

Bild

Betrifft: Wundere mich, dass Gerd auf so eine unklare ...
von: Luc:-?
Geschrieben am: 16.07.2015 02:47:46
…Frage überhaupt etwas geantwortet hat, Daniel;
1. Was ist für dich der Unterschied zwischen „einer Range“ und einem „einfachen Array“?
2. Was bedeutet in diesem Zusammenhang „…muss man, wenn man mehr will als nur den Wert auslesen, die Schleife über die Indexnummern erstellen“? Oben hast du beschrieben, was mit der Range-Laufvariablen einer For Each-Schleife möglich ist und unten fragst du dann das…!???
Gruß, Luc :-?

Besser informiert mit …

Bild

Betrifft: AW: Wundere mich, dass Gerd auf so eine unklare ...
von: Daniel
Geschrieben am: 16.07.2015 08:38:29
Ok, dann hier mal mit Beispiel, damit ihr versteht was ich meine:
im ersten Fall ändert sich der Array-Wert mit, wenn ich Laufvariable einen neuen Wert zuweise:

Set XXX = Range("a1:a2")
For Each x In XXX
    x.Value = 1
Next
Debug.Print XXX(1, 1)

im zweiten Fall funktioniert das nicht, ich weise zwar der Laufvariable einen Wert zu, aber der dazugehörige Array-Wert ändert sich nicht mit, sondern bleibt auf seinem alten Wert:
Set XXX = Range("a1:a2")
XXX = Range("B1:B2").Value
For Each x In XXX
    x = 2
Next
Debug.Print XXX(1, 1)

daher meine Frage, ob es auch für den zweiten Fall eine Möglichkeit gibt, das Array selbst über die Laufvariable zu ändern, so wie es im ersten Fall funktioniert?
Gruß Daniel

Bild

Betrifft: Du hast zwar d.Deklaration nicht mit angegeben,...
von: Luc:-?
Geschrieben am: 16.07.2015 14:02:52
…Daniel,
aber sicher ist x im 1.Fall As Range und im 2. As Variant deklariert (es ist ohnehin nur Objekt oder Variant möglich!). Ist XXX Variant, enthält es im 1.Fall einen Bereich, im 2. ein Datenfeld. Daten­felder haben aber keinen direkten Bezug zu ihrem evtl Herkunfts­Bereich mehr! Das wäre bei allen SchleifenTypen so und damit hätte der auch nur indirekt mit diesem Problem zu tun.
Wenn du in diesem Fall den Zell­Inhalt automatisch ändern willst, benötigst du 1. einen im Prozedur­Kopf ByRef (Standard) und As Range deklarierten Bereichs­Parameter und 2. muss dessen Bezug auch erhalten bleiben, damit du den neuen Wert dem jeweiligen Feld direkt zuordnen kannst. Das Ändern des durch die Lauf­Variable repräsentierten Elements des Variant-Arrays nutzt gar nichts, da nicht mal das Original-Element geändert wird. Das müsstest du mit seinen Positions­Indizes ansprechen, wobei die bei diesem Schlei­fentyp separat hoch­gezählt wdn müssten, wobei einiges zu beachten ist (ZellBereiche wdn zeilen-, Daten­felder spaltenweise durch­laufen!).
Ein Ändern eines Zellwerts in einer Variant-For Each-Schleife stellt den Sinn der Variant-Bildung infrage. Deshalb sollte hier das einzelne Element des Variants geändert wdn, was nur über die Indizes, nicht per Lauf­Variabler fktt. Nach Schleifen­Durchlauf kann dann das Ergebnis in Gänze in den ursprüngl Zell­Bereich zurück­ge­schrie­ben wdn. Das wäre das übliche Vorgehen in diesem Fall.
Luc :-?

Bild

Betrifft: AW: Du hast zwar d.Deklaration nicht mit angegeben,...
von: Daniel
Geschrieben am: 16.07.2015 14:30:37
Hi Luc
mir gehts hier rein um Datenfelder.
heitß wenn, ich sowas habe wie:
XXX = Array(1, 2, 3, 4)
und ich will jeden Arraywert verdoppeln, dann geht das nur über den Index:

for i = Lbound(xxx) to Ubound(xxx)
    xxx(i) = xxx(i) * 2
Next
und nicht mit einer for Each in Schleife?
Gruß Daniel

Bild

Betrifft: Ja, du benötigst auf jeden Fall einen Index, ...
von: Luc:-?
Geschrieben am: 16.07.2015 16:04:14
…Daniel,
denn das Datenfeld wird standardmäßig ByVal aufgerufen, da (klassische) VBA-Arrays keine Objekte sind wie in vielen anderen PgmierSprachen. Damit können ihre Elemente nicht per Änderung des Werts einer ein Element nur abbildenden LaufVariable einer For Each-Schleife geändert wdn. Du kannst die wert­geänderte Lauf­Variable aber wieder an das zugehörige Datenfeld­Element rück­über­weisen, nur benötigst du dann einen mitlfd Index, den du selber richtig bilden musst.
Luc :-?

Bild

Betrifft: probiers doch einfach aus. owT
von: Rudi Maintaire
Geschrieben am: 16.07.2015 11:24:03


Bild

Betrifft: AW: probiers doch einfach aus. owT
von: Daniel
Geschrieben am: 16.07.2015 14:03:31
hab ich, geht nicht.
daher die Frage, obs noch weitere, mir unbekannte Methoden gibt, mit denen es funktioniert.
Gruß Daniel

Bild

Betrifft: geht nicht: so ist es
von: Rudi Maintaire
Geschrieben am: 16.07.2015 15:19:16
Hallo,
es geht nicht per For each, sondern nur über den Index.
Gruß
Rudi

Bild

Betrifft: AW: For-Each in Range und Array
von: Michael
Geschrieben am: 16.07.2015 14:42:39
Hi zusammen,
es scheint so zu sein, daß das g nicht "direkt" mit einem Array verbunden ist.
Das nachfolgende Beispiel habe ich von http://www.online-excel.de/excel/singsel_vba.php?f=94
und leicht geändert:

Public Sub DurchArray2()
    Dim MeinFeld, g, i
    MeinFeld = Array(1, 2, 3)
    For Each g In MeinFeld
        Debug.Print "FE1: " & g
        g = 5
    Next g
    For Each g In MeinFeld
        Debug.Print "FE2: " & g
    Next g
    For i = LBound(MeinFeld) To UBound(MeinFeld)
        Debug.Print "For To 1: " & MeinFeld(i)
        MeinFeld(i) = 5
    Next
    For Each g In MeinFeld
        Debug.Print "FE3: " & g
    Next g
End Sub
... und damit Rudis Vorschlag aufgegriffen.
Schöne Grüße,
Michael
P.S.: Hilfreich ist auch die "offizielle" Hilfe: https://msdn.microsoft.com/de-de/library/5ebk1751.aspx
Im Tipp steht sinngemäß: For Each ist dann sinnvoll, wenn Anfangs- und Endwert der Liste nicht bekannt sind - bei einem Array *weiß* man das aber, also bitte: For x= ....

Bild

Betrifft: AW: Vielen Dank an alle, die sich...
von: Daniel
Geschrieben am: 16.07.2015 16:37:02
... mit dem Problem befasst und geantwortet haben.
werde wohl damit leben müssen, dass es nur über den Index geht.
Gruß Daniel

Bild

Betrifft: Vor 10 Jahren gab's dazu hier schon mal eine ...
von: Luc:-?
Geschrieben am: 16.07.2015 23:57:24
…Frage von MichaV, Daniel,
an die ich mich Jahre später erinnert und dafür eine Abhilfe geschaffen hatte, die das separate Hoch­zählen eines Index in einer For Each-Schleife ggf überflüssig macht. Allerdings setzt das die Anlage einer speziellen Fkt und ihre Anwendung im Kopf der Schleife voraus, was die Abarbeitungs­geschwindigkeit ggf etwas verzögern könnte, da zuerst diese Fkt abgearbeitet wird, die das Datenfeld um eine vorangestellte lfdNr ergänzt. Diese kann dann in der Schleife als Index benutzt wdn. Gleichzeitig wird aber aus einem (bzw mehreren) normalen Vektoren (auch Einzel­Spalten oder -Zeilen eines Bereichs) ein vertikaler Vektor erzeugt, dessen Elemente aus Datenfeldern (über die Spalten/Zeilen der jeweiligen Zeile/Spalte) bestehen. Dazu findet man Ausführungen von mir im hiesigen Archiv und im alten OL-Xl(VBA)Forum. Solche UDFs habe ich Pair, VPairs oder Paar bzw Paare genannt, wenn es um maximal 2 Vektoren geht, bei mehr als 2 Couple. Ein AnwendungsBsp dafür (UDF SubSet) wird demnächst im OX/CP-Forum (Online-Excel/CodeProjekt) zu finden sein.*
* Hier im Archiv schwer, das Richtige zu finden; habe die einzige Stelle mit BspCode selbst nicht mehr gefunden → viele Irrwege!
Luc :-?

Bild

Betrifft: Aus meiner Absicht kann nun nichts mehr wdn, ...
von: Luc:-?
Geschrieben am: 18.07.2015 22:57:54
…siehe hier! Damit muss auf eine neue passende Gelegenheit oder eine WebSite gewartet wdn, die diese UDF zeigt… :-[
Luc :-?

Bild

Betrifft: AW: It 's better,,,
von: Gerd L
Geschrieben am: 16.07.2015 21:10:42
Hallo zus.
...weather in the Bahamas :-)

Sub Indexbildung()
Dim A, Z
ReDim B(0)
A = Array(1, 2, 3): MsgBox Join(A, "; ")
For Each Z In A
    If Len(B(0)) Then ReDim Preserve B(UBound(B) + 1)
    B(UBound(B)) = 2 * Z
Next
A = B: MsgBox Join(A, "; ")
End Sub
Gruß Gerd

Bild

Betrifft: Das ist zwar nicht ganz dasselbe, ...
von: Luc:-?
Geschrieben am: 17.07.2015 00:00:46
…Gerd,
aber eine echte (beste) Alternative. ;-)
Gruß, Luc :-?

Bild

Betrifft: AW: It 's better,,, not really
von: Daniel
Geschrieben am: 17.07.2015 08:26:34
auch hier verwendest du zum Ändern eines einzelnen Wert eines Datenfeldes den Weg über die Indexnummer, dh keine neue Erkenntnis.
Gruß Daniel

Bild

Betrifft: Ohne geht's ja auch nicht! owT
von: Luc:-?
Geschrieben am: 17.07.2015 12:03:52
:-?

 Bild

Beiträge aus den Excel-Beispielen zum Thema "Bereich durchsuchen, mehrere Vorkommen"