The eXpLorer


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

Zum Seitenanfang


The eXpLorer

Zuletzt aktualisiert am 20.07.2003 / 20:30 Uhr
© Copyright 2002-2003 by Philipp von Wartburg, CH-8917 Oberlunkhofen
Alle Rechte vorbehalten