Excel-VBA: Die Selection-Eigenschaft und ihre Tücken
Zusammenfassung
Die Selection-Eigenschaft des Application-Objektes besitzt nicht einen echten Bug
aber eine spezielle Eigenheit. Wenn man beispielsweise mit Kommentaren oder
Zeichnungsobjekten arbeitet, sollte man diese Eigenheit unbedingt kennen und
berücksichtigen.
Vorgehen
Wie der Name schon sagt, wird Select ganz allgemein dazu verwendet, um irgendwelche
Objekte wie zum Beispiel Zellen oder Kommentare eines (spezifizierten) Bereiches zu
selektieren. Mit folgender Anweisung markieren Sie beispielsweise die Zellen des Bereiches
A1 bis C3:
Range("A1:C3").Select
Das ist soweit verständlich.
Auch diese Anweisung funktioniert tadellos:
ActiveCell.SpecialCells(xlCellTypeComments).Select
Da ActiveCell vom Typ Range ist und für einen Bereich
steht, der genau eine Zelle umfasst, wird SpecialCells bzw. Select auf das gesamte
Arbeitsblatt angewendet.
Vergleichen wir das einmal mit der Selection-Eigenschaft des Application-Objektes. Selection gibt ein Objekt zurück und wird in VBA-Programmen in der Regel dazu verwendet, um den aktuell selektierten Bereich als Range-Objekt zu erhalten.
Legen Sie ein leeres Arbeitsblatt an, schreiben in die
Zelle A1 den Text "Ohne Kommentar", in Zelle C6 "Mit Kommentar" und
fügen dieser Zelle C6 einen Kommentar mit beliebigem Text hinzu. Wichtig ist, dass die
Excel-Option für Kommentar-Ansicht auf "Kommentare und Indikatoren" eingestellt
ist. Der hinzugefügte Kommentar ist somit immer sichtbar. Selektieren Sie die Zelle A1,
öffnen den VBA-Editor und geben im Direktfenster folgende Anweisung ein:
ActiveCell.SpecialCells(xlCellTypeComments).Select
Kein Problem. Alle Kommentar-Zellen (in unserem Fall
C6) werden selektiert. Selektieren Sie jetzt in Excel wieder die Zelle A1 und geben dann
im Direktfenster diese Anweisung ein:
Selection.SpecialCells(xlCellTypeComments).Select
Ebenfalls kein Problem. Es wird ebenfalls C6 markiert.
Nun selektieren Sie wieder die Zelle A1 und dann den
Kommentar von Zelle C6, aber nicht die Zelle selbst sondern nur das Kommentar-Objekt (in
der Regel ein Rechteck). Jetzt wird folgende Anweisung eingegeben:
ActiveCell.SpecialCells(xlCellTypeComments).Select
Als Ergebnis wird wie erwartet die Zelle C6 markiert.
Nochmal zurück zu Excel, die Zelle A1 selektieren und dann wieder das Kommentar-Objekt.
Im Direktfenster wird diese Anweisung ausgeführt:
Selection.SpecialCells(xlCellTypeComments).Select
Was passiert? Der Laufzeitfehler Nr. 438 "Objekt
unterstützt diese Eigenschaft oder Methode nicht" erscheint!
OK. Sie werden jetzt vielleicht denken, dass die
Fehlermeldung ja logisch ist, da nicht eine Zelle sondern das Kommentar-Objekt aktiviert
ist. Ist wirklich keine Zelle aktiv? Geben Sie als Test dies ein:
?ActiveCell.Value
Sie erhalten "Ohne Kommentar" zurück, was
beweist, dass eine aktive Zelle existiert.
Welches ist die Ursache der
Fehlermeldung?
Erfahrene Excel-Programmierer werden den Grund der Fehlermeldung schnell erkennen.
Die Ursache liegt in der Definition der Selection-Eigenschaft. Selection gibt nämlich
schlicht ein allgemeines Objekt zurück und nicht ein Range-Objekt. Die Deklaration im
Objektmodell lautet "Property Selection As Object" im Gegensatz zu
beispielsweise der Cells-Eigenschaft "Property Cells As Range". In unserem
Problemfall war das referenzierte Objekt ein Kommentar und nicht ein Bereich. Weil
Kommentare über keine SpecialCells-Funktion verfügen, wurde der Fehler "Objekt
unterstützt diese Eigenschaft oder Methode nicht" ausgelöst.
Was muss bei der
Programmierung beachtet werden?
Die Verwendung von Selection als Behälter bzw. Platzhalter für den aktuellen
Bereich ist einfach und weit verbreitet. In gewissen Situationen besteht jedoch die
Gefahr, dass Selection nicht das erwartete Objekt enthält beziehungsweise den erwarteten
Objekttyp aufweist. Wie am Beispiel eines Kommentares zu erkennen ist, ist die Verwendung
von ActiveCell gegenüber Selection viel sicherer.
Dieser Code würde bei markiertem Kommentar-Objekt nicht korrekt funktionieren, da Selection in
dieser Situation den Objekttyp "TextBox" besitzt und daher die
Comment-Eigenschaft nicht kennt:
If Not Selection.Comment Is Nothing Then
MsgBox Selection.Comment.Text
Else
MsgBox "Zelle ohne Kommentar"
End If
Die Variante mit ActiveCell dagegen würde auch in diesem
Fall korrekt ausgeführt:
If Not ActiveCell.Comment Is Nothing Then
MsgBox ActiveCell.Comment.Text
Else
MsgBox "Zelle
ohne Kommentar"
End If
Gelegentlich wird von VBA-Programmierern auch die "On
Error Resume Next"-Anweisung eingesetzt, um bei Zellen ohne Kommentar den
Laufzeitfehler 91 "Objektvariable oder With-Blockvariable nicht festgelegt"
azufangen. Es wird dabei - vorbildlich - mittels der Codezeile "If Err Then" auf
sämtliche Laufzeitfehler getestet, ein Hinweismeldungsdialog eingeblendet und
schliesslich mit "On Error GoTo 0" der Error Handling wieder deaktiviert:
On Error Resume Next
MsgBox Selection.Comment.Text
If Err Then
MsgBox "Zelle ohne Kommentar"
End If
On Error GoTo 0
Was meinen Sie: Funktioniert der obige Beispielcode korrekt?
Die Antwort ist Nein. Auch wenn die aktive Zelle einen Kommentar besitzt, wird die Meldung "Zelle ohne Kommentar" angezeigt, weil sowohl Laufzeitfehler 438 "Objekt unterstützt diese Eigenschaft oder Methode nicht" wie auch Laufzeitfehler 91 (den man eigentlich abfangen wollte) identisch behandelt werden. Würde man im obigen Beispiel 'Selection' durch 'ActiveCell' ersetzen, würde der Code korrekt funktionieren, da der Laufzeitfehler Nr. 438 bei ActiveCell gar nicht auftreten kann.
Mit der TypeName-Funktion kann übrigens der Objekttyp des
Selection-Objektes ermittelt werden:
?TypeName(Selection) '-> zeigt "Range" bei Zellen bzw.
"TextBox" bei Kommentaren
The eXpLorer
Zuletzt aktualisiert am
20.07.2003 / 20:30 Uhr
© Copyright 2002-2003 by Philipp von Wartburg, CH-8917
Oberlunkhofen
Alle Rechte vorbehalten