RangeZelle in RangeSpalte

19/12/2009 - 19:54 von Eberhard Funke | Report spam
Hallo,

es sollen alle Zellen einer Spalte durchlaufen werden, aber das Testmakro
zeigt das Problem auf:

Sub Strange()
Dim rngZ As Range
For Each rngZ In ActiveSheet.Columns(1)
'For Each rngZ In Range("Test")
Debug.Print rngZ.Address
Exit Sub 'hier abbruch, da Problem durch Debug.Print angezeigt wird
Next
End Sub

Direktfenster: $A:$A (und nicht, wie erwartet, $A$1)

Dagegen mit Name der Spalte 1 = Test und der auskommentierten Zeile statt
For Each rngZ In ActiveSheet.Columns(1)

Direktfenster: $A$1

Wieso funktioniert das nicht mit dem Rangeobjekt ActiveSheet.Columns(1)?


Mit freundlichen Grüssen Eberhard
XP home XL 2000
 

Lesen sie die antworten

#1 Andreas Killer
20/12/2009 - 08:59 | Warnen spam
Eberhard Funke schrieb:

es sollen alle Zellen einer Spalte durchlaufen werden, aber das Testmakro
zeigt das Problem auf:


Naja, ja und nein. :-)

Wieso funktioniert das nicht mit dem Rangeobjekt ActiveSheet.Columns(1)?


Das Problem dabei ist das es keinen Datentyp "Columns" gibt, sondern
alles ein Range ist.

Mit Columns(1) bekommst Du genau genommen kein "Zell"-Objekt, sondern
ein "Spalten"-Objekt zurück.

For Each rngZ In Columns("A:B")
Debug.Print rngZ.Address
Next

gibt "$A:$A" und "$B:$B" aus. Das gleiche geht für Zeilen auch:

For Each rngZ In Rows("1:2")
Debug.Print rngZ.Address
Next

Nun hast Du mehrere Möglichkeiten, das zurückgegebene "Column"-Objekt
in ein "Zell"-Objekt "umzuwandeln":

For Each rngZ In Columns(1).Cells

wàre das was dem Code am nàchsten kommt, es geht aber auch

For Each rngZ In Range("A:A")

Beides ist jedoch nicht klug, weil Du dadurch die komplette Spalte,
also auch Zellen außerhalb des benutzten Bereichs durchlàufst.

Um eine höhere Performance zu erreichen kann man die letzte Zeile
ermitteln und mit FOR alle Zeilen abzuklappern (kennst Du ja).

Man kann aber auch nur den benutzten Bereich durchlaufen und vorher
eine Schnittmenge bilden:

Sub Optimal()
Dim rngZ As Range, Spalte As Range
With ActiveSheet
Set Spalte = Intersect(.Columns(1), .UsedRange)
End With
If Spalte Is Nothing Then Exit Sub
For Each rngZ In Spalte
Debug.Print rngZ.Address
Next
End Sub

So kann man sehr einfach die gesamte "Höhe" eines Datensatzes
durchlaufen, ohne zu wissen wie groß er eigentlich ist und wo er beginnt.

Hat aber einen kleinen Nachteil: Der Zugriff auf UsedRange setzt die
letzte Zelle (die man mit Strg-Ende anspringt) auf das benutzte Ende
zurück, das ist nicht immer von allen Usern gern gesehen.

Andreas.

Ähnliche fragen