Discussion:
Zeilen und Spalten mit VBA ausblenden
(zu alt für eine Antwort)
Thomas Mangold
2008-07-17 22:11:44 UTC
Permalink
Hallo,

ich lasse in einem komplexen Dokument mit folgendem Code alle Spalten
ausblenden, die kein X in der ersten Zeile stehen haben:

For Each cell In Range(Cells(1, 2), Cells(1, 256))
If UCase(cell.Value) = "X" Then
cell.EntireColumn.Hidden = False
Else: cell.EntireColumn.Hidden = True
End If
Next cell


Analog gehe ich mit den Zeilen vor, ich lasse alle Zeilen ausblenden,
deren Element in der ersten Spalte kein X hat:
.
cell.EntireRow.Hidden = False
.

Das funktioniert. Allerdings sehr langsam. Gibt es eine Möglichkeit,
dies zu beschleunigen.

Eine Idee wäre, die Spalten zu merken, die ausgeblendet werden sollen
und dann alle auf einmal ausblenden. Nur geht bei
ActiveSheet.Columns(Spalte).Hidden = False
darf Spalte nur einen zusammenhängenden Bereich umfassen.

Gruß
Thomas
Claus Busch
2008-07-17 23:45:58 UTC
Permalink
Hallo Thomas,
Post by Thomas Mangold
ich lasse in einem komplexen Dokument mit folgendem Code alle Spalten
For Each cell In Range(Cells(1, 2), Cells(1, 256))
If UCase(cell.Value) = "X" Then
cell.EntireColumn.Hidden = False
Else: cell.EntireColumn.Hidden = True
End If
Next cell
Analog gehe ich mit den Zeilen vor, ich lasse alle Zeilen ausblenden,
.
cell.EntireRow.Hidden = False
.
Das funktioniert. Allerdings sehr langsam. Gibt es eine Möglichkeit,
dies zu beschleunigen.
wenn du über sämtliche Spalten und Zeilen diese Überprüfung nach "X"
laufen läßt, ist das logischerweise langsam. Wenn deine Tabelle in Zeile
2 lückenlos ausgefüllt ist, dann lass dir doch die letzte belegte Spalte
geben und prüfe nur von Spalte 2 bis zur letzten. Analog könntest du das
auch mit den Zeilen machen, aber noch schneller wäre es, wenn du die
Spalte A nach x filtern würdest.
Ausblenden errechnet in Zeile 2 die letzte belegte Spalte und in Spalte
2 die letzte belegte Zeile (Das musst du noch deiner Tabelle
entsprechend anpassen). Ausblenden2 filtert Spalte A nach x:

Sub Ausblenden()

Dim LRow As Long
Dim LCol As Integer
Dim rngZelle As Range

Application.ScreenUpdating = False
With ActiveSheet
LRow = .Cells(Rows.Count, 2).End(xlUp).Row
LCol = .Cells(2, Columns.Count).End(xlToLeft).Column

For Each rngZelle In Range(Cells(1, 2), Cells(1, LCol))
If UCase(rngZelle.Value) <> "X" Then
rngZelle.EntireColumn.Hidden = True
End If
Next

For Each rngZelle In Range("A2:A" & LRow)
If UCase(rngZelle.Value) <> "X" Then
rngZelle.EntireRow.Hidden = True
End If
Next
End With
Application.ScreenUpdating = True

End Sub

Sub Ausblenden2()

Dim LCol As Integer
Dim rngZelle As Range

Application.ScreenUpdating = False
With ActiveSheet
LCol = .Cells(2, Columns.Count).End(xlToLeft).Column

For Each rngZelle In Range(Cells(1, 2), Cells(1, LCol))
If UCase(rngZelle.Value) <> "X" Then
rngZelle.EntireColumn.Hidden = True
End If
Next

.Range("$A$1").AutoFilter Field:=1, Criteria1:="=x"
End With
Application.ScreenUpdating = True

End Sub


Mit freundlichen Grüssen
Claus Busch
--
Win XP Prof SP2 / Vista Ultimate
Office 2003 SP2 / 2007 Ultimate
Thomas Mangold
2008-07-18 10:16:39 UTC
Permalink
Hallo Claus,
Post by Claus Busch
Post by Thomas Mangold
ich lasse in einem komplexen Dokument mit folgendem Code alle Spalten
For Each cell In Range(Cells(1, 2), Cells(1, 256))
If UCase(cell.Value) = "X" Then
cell.EntireColumn.Hidden = False
Else: cell.EntireColumn.Hidden = True
End If
Next cell
Analog gehe ich mit den Zeilen vor, ich lasse alle Zeilen ausblenden,
.
cell.EntireRow.Hidden = False
.
Das funktioniert. Allerdings sehr langsam. Gibt es eine Möglichkeit,
dies zu beschleunigen.
wenn du über sämtliche Spalten und Zeilen diese Überprüfung nach "X"
laufen läßt, ist das logischerweise langsam.
Ich habe den Code verkürzt, ich kenne die maximale Spalte und maximale
Zeile und lasse die Schleife auch nur bis dahin laufen. Das habe ich
nicht so elegant gelöst wie du.

Interessant scheint mir, neben dem Ausschalten der
Bildschirmaktualisierung das Filtern. Zumal die Tabelle erheblich mehr
Zeilen als Spalten besitzt.
Post by Claus Busch
.Range("$A$1").AutoFilter Field:=1, Criteria1:="=x"
Da habe ich nur noch das nächste Problem. Ich will nämlich alle Zeilen
ausblenden, außer denen, die ein x oder ein a haben oder leer sind oder
den Wert der Variablen Klasse besitzen. D.h. ich nicht nur zwei, sondern
4 Kriterien. Kann man das mit VBA lösen oder muss ich eine Hilfszeile
einbauen?

Thomas

Ich verwende Office 2000
Claus Busch
2008-07-18 10:37:49 UTC
Permalink
Hallo Thomas,
Post by Thomas Mangold
Interessant scheint mir, neben dem Ausschalten der
Bildschirmaktualisierung das Filtern. Zumal die Tabelle erheblich mehr
Zeilen als Spalten besitzt.
Post by Claus Busch
.Range("$A$1").AutoFilter Field:=1, Criteria1:="=x"
Da habe ich nur noch das nächste Problem. Ich will nämlich alle Zeilen
ausblenden, außer denen, die ein x oder ein a haben oder leer sind oder
den Wert der Variablen Klasse besitzen. D.h. ich nicht nur zwei, sondern
4 Kriterien. Kann man das mit VBA lösen oder muss ich eine Hilfszeile
einbauen?
du kannst beim Autofilter leider nur 2 Kriterien einsetzen. Aber du
könntest den Spezialfilter dazu verwenden. Dazu müssen deine Daten
allerdings Überschriften haben, weil der Spezialfilter das so verlangt
und du musst irgendwo den Kriterienbereich hinterlegen. Da du aber sehr
wahrscheinlich keine Überschriften einbauen kannst und für den
Kriterienbereich sowieso eine zusätzliche Spalte benötigen würdest,
könntest du das auch über eine Hilfsspalte lösen, in der du über eine
ODER-Funktion den Wert der Spalte A abfragst und dann nach diesem
Wahrheitswert filterst.


Mit freundlichen Grüssen
Claus Busch
--
Win XP Prof SP2 / Vista Ultimate
Office 2003 SP2 / 2007 Ultimate
Georg Pohl
2008-07-18 04:33:53 UTC
Permalink
Post by Thomas Mangold
Das funktioniert. Allerdings sehr langsam. Gibt es eine Möglichkeit,
dies zu beschleunigen.
Hallo Thomas,

Claus hat Dir einen Lösungsweg angezeigt. Allerdings wage ich zu
behaupten, dass die eigentliche Optimierung weniger in einem
veränderten Algorithmus liegt, sondern darin am Anfang der Routine die
Bildschirm-Aktualisierung aus- und am Ende wieder einzuschalten.

Setze einmal an den Anfang Deiner Routine ein
"Application.ScreenUpdating = False" und ans Ende
"Application.ScreenUpdating = True" - Du wirst Dich wundern, wie
schnell Deine Sub wird :-)
--
Gruß
Georg
Thomas Mangold
2008-07-18 09:45:34 UTC
Permalink
Hallo Georg,
Post by Claus Busch
Post by Thomas Mangold
Das funktioniert. Allerdings sehr langsam. Gibt es eine Möglichkeit,
dies zu beschleunigen.
Hallo Thomas,
Claus hat Dir einen Lösungsweg angezeigt. Allerdings wage ich zu
behaupten, dass die eigentliche Optimierung weniger in einem
veränderten Algorithmus liegt, sondern darin am Anfang der Routine die
Bildschirm-Aktualisierung aus- und am Ende wieder einzuschalten.
Setze einmal an den Anfang Deiner Routine ein
"Application.ScreenUpdating = False" und ans Ende
"Application.ScreenUpdating = True" - Du wirst Dich wundern, wie
schnell Deine Sub wird :-)
Das funktioniert erheblich schneller und ist viel angenehmer, weil der
Bildchsirm nicht so flackert.

Auf eine ähnliche Idee bin auch schon gekommen, ich habe die
automatische Berechnung ausgeschalten mit:
Application.Calculation = xlManual
Der Effekt war allerdings nicht merkbar.

Vielen Dank!

Thomas
Loading...