online 1
gast (50)

/ Forum / Tabellenkalkulation

TabellenkalkulationTabellenkalkulation

Fragevon wollachee vom 08.02.2019, 10:43 Options

Wie kann VBA erkennen, dass in Excel neue Steuerelemente hinzugefügt wurden?

Hallo zusammen,

wenn man in Excel ein z.B. Kombinationsfeld hat, welches mit seiner Eigenschaft "LinkedCell" auf eine normale Zelle verweist, bleibt dieser Eintrag erhalten, wenn man das Steuerelement mehrfach kopiert.
Ich hätte nun gerne, das der LinkedCell-Verweis ohne manuelles Zutun immer auf die Zelle verweist, auf der sich das jeweilige Steuerelement befindet.

Meine Idee ist wie folgt:
Excel-VBA muss beim Beenden des Entwurfsmodus oder gleich nach dem Einfügen des Steuerelements erkennen, dass ein oder mehrere neue Steuerelemente hinzu gekommen sind.
Jedenfalls muss irgendwie erreicht werden, dass spätestens nach dem Beenden des Enturfsmodus automatisch eine VBA-Prozedur aufgerufen wird.
Diese Prozedur prüft für alle in der Tabelle enthaltenen Steuerelemente, ob deren LinkedCell-Eigenschaft gesetzt ist und lenkt sie auf die "hinter" dem Steuerelement liegende Zelle um (irgendwie müsste also noch zu ermitteln sein, welche Zelle der Position des Steuerelements zugeordnet ist).

Mir ist bisher noch nicht bekannt, wie ich
1. automatisch eine Prozedur nach Beenden des Entwurfsmodus oder dem Erzeugen eines neuen Steuerelements anstoßen kann,
2. zu einem Steuerelement die zugrunde liegende Zelle des Tabellenblattes ermitteln kann.

Wenn jemand zu 1. oder 2. eine Tip hätte, würde mir das sehr weiterhelfen.

Vielen Dank,
Wollachee


Antwort schreiben

Antwort 1 von coros vom 08.02.2019, 12:44 Options

Hallo Wollachee,

zu 1:: Mir ist nicht bekannt, dass es da eine Möglichkeit gibt, abzufragen wann der Entwurfsmodus beendet wurde, geschweige dann ein Ereignis auszulösen.

Zu 2.: Habe ehrlich gesagt nicht ganz den Satz zu 2. verstanden. Eventuell kannst Du das ja etwas einfacher schreiben.

Zu Deiner einleitenden Frage:

Zitat:
Ich hätte nun gerne, das der LinkedCell-Verweis ohne manuelles Zutun immer auf die Zelle verweist, auf der sich das jeweilige Steuerelement befindet.


Ich würde das mit nachfolgendem Code realisieren. Das Makro setzt voraus, dass bereits eine ComboBox mit dem Namen "ComboBox1" im Blatt vorhanden ist. Das Makro macht nun nichts anderes, als dass es ComboBox1 kopiert und an der Stelle, an der eine Zelle markiert wurde, einfügt. Die LinkedCell-Eigenschaft wird dann automatisch mit der markierten Zelladresse überschrieben. Kopiere das Makro zum testen in ein StandardModul.

[b]Option Explicit

Sub ComboBox_einfügen()
Rem: COmbobox1 kopieren
ActiveSheet.Shapes("ComboBox1").Copy
Rem: Kopierte ComboBox in markierte Zelle einfügen
ActiveCell.PasteSpecial
Rem: LinkedCell-Eigenschaft mit Adresse der markierten Zelle überschreiben
Selection.LinkedCell = ActiveCell.Address
End Sub[/b]


Das reine erstellen einer ComboBox würde etwas komplizierter sein, da man die Postion der Objekte nicht an die aktive Zelle koppeln kann, sondern man müsste anhand der Werte Left, Top, Width und Height ermitteln und errechnen, wo die markierte Zelle sich befindet und welche Werte hier dann anzugeben wären. Das ist aber ein bisschen viel Aufwand für das einfügen einzelnen ComboBoxen.

Zum Prüfen ob eine neue ComboBox dazu gekommen ist, könnte man nachfolgendes Makro nehmen. Das speichert die alte Anzahl von ComboBoxen in Zelle A1 ab. Beim nächsten Ausführen wird die Zahl verglichen und einen entsprechende Bildschirmmeldung ausgegeben.

[b]Option Explicit

Sub Anzahl_ComboBoxen()
Rem: Variablen deklarieren
Dim Bezeichnungsfeld As OLEObject, Zähler As Integer
Rem: Schleife zum Ansprechen aller OleObjekte, die in dem
Rem: Tabelenblatt vorhanden sind
For Each Bezeichnungsfeld In ActiveSheet.OLEObjects
Rem: Wenn der Objektname von links an gesehen in einer Länge von
Rem: 5 Buchstaben das Wort "Label" ergibt, dann...
If Left(Bezeichnungsfeld.Name, 8) = "ComboBox" Then
Rem: Zähler hochzählen
Zähler = Zähler + 1
Rem: Abfrage Ende
End If
Rem: nächsten Schleifendurchlauf starten
Next
Rem: Wenn Zähler und Vergleichswert aus Zelle A1 gleich, dann...
If Zähler = Range("A1") Then
Rem: ...diese Bildschirmmeldung bringen,...
MsgBox "Keine ComboBox dazu gekommen", vbInformation, "Hinweis..."
Rem: ...ansonsten...
Else
Rem: ...diese Bildschirmmeldung bringen
MsgBox "Es ist eine neue ComboBox dazu gekommen", vbInformation, "Hinweis..."
End If
Rem: Wert aus Variable "Zähler" in Zelle A1 schreiben
Range("A1") = Zähler
End Sub
[/b]


Ich hoffe, Du kommst klar. Bei Fragen melde Dich wieder.

Solltest Du nicht wissen, wie Du den Code in Deine Datei bekommst, dann schau mal auf meiner HP in der Rubrik Anleitungen und dort dann in der Anleitungsnummer 3 nach. Dort stelle ich dazu eine bebilderte Anleitung zur Verfügung, die Dir sicherlich helfen wird.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du ein
Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 2 von wollachee vom 08.02.2019, 13:19 Options

@Oliver,

vielen Dank für Deine ausführliche Hilfstellung. Ich habe mir inzwischen bereits selbst was ausgedacht, was meine Problemstellung zufriedenstellend löst.

Du hast sicher Recht, es gibt vermutlich keine Möglichkeit, direkt das Beenden des Entwurfsmodus im VBA-Code abzufragen. Ich beschränkt mich deshalb jetzt auf ein so unkompliziertes Verfahren wie Klick in eine andere Zelle.

Es ist - zumindest im Moment - auch noch nicht nötig, den Typ des Steuerelements abzufragen. Alles, was eine LinkedCell-Eigenschaft bietet, wird bearbeitet. Eventuelle Exceptions anderer Steuerelemente werden abgefangen.

Für jedes zu behandelnde Steuerelement frage ich die Koordinaten der TopLeftCell-Eigenschaft ab und berechne daraus den neuen Eintrag für die LinkedCell-Eigenschaft.

Anschließend setze ich noch das nicht benötigte Attribut "AltHTML" auf "*", um zu markieren, dass dieses Steuerelement bereits bearbeitet wurde.

Nach dem Beenden des Entwurfsmodus muss man nur noch einmal irgendwohin klicken und die Neuberechnung ist gelaufen.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    ' Redefine Errorhandling
    On Error GoTo NO_LINKEDCELL_PROP
    
     For Each n In ActiveWorkbook.ActiveSheet.OLEObjects
        If n.LinkedCell <> "" And n.AltHTML = "" Then 
            n.LinkedCell = Chr(64 + n.TopLeftCell.Column) & Trim(Str(n.TopLeftCell.Row))
            n.AltHTML = "*" recalculated element
        End If
NO_LINKEDCELL_PROP:
    Next
    
    'Restore Errorhandling
    On Error GoTo 0
End Sub


Trotzdem nochmal vielen Dank. Ich wußte doch, dass es hier Leute gibt, die sich damit auskennen.

Gruß, Wollachee

Ähnliche Themen

Steuerelemente per VBA markieren
bergfreund  05.06.2007 - 61 Hits - 1 Antwort

Aktive Filter in Excel erkennen (VBA)
Mein_Pseudonym  06.07.2007 - 121 Hits - 2 Antworten

Vba Userform
VBkid  27.09.2007 - 32 Hits -

Schnellreferenz Excel VBA
Joshuan  23.05.2008 - 219 Hits - 3 Antworten

VBA-Excel
mentosbasi  28.05.2008 - 350 Hits - 3 Antworten

Hinweis

Diese Frage ist schon etwas älter, Sie können daher nicht mehr auf sie antworten. Sollte Ihre Frage noch nicht gelöst sein, stellen Sie einfach eine neue Frage im Forum..

Neue Einträge

Version: supportware 1.9.150 / 10.06.2022, Startzeit:Mon Jan 26 01:23:17 2026