it-swarm.com.de

OnClick in Excel VBA

Gibt es eine Möglichkeit, in Excel mit einem Klick auf eine Zelle in VBA zu klicken? Ich beziehe mich nicht auf das Worksheet_SelectionChange-Ereignis, da dieses nicht mehrmals ausgelöst wird, wenn die Zelle mehrmals angeklickt wird. BeforeDoubleClick löst mein Problem auch nicht, da ich nicht verlangen möchte, dass der Benutzer das erforderliche Doppelklick ausführt.

Meine derzeitige Lösung funktioniert zwar mit dem SelectionChange-Ereignis, scheint jedoch die Verwendung globaler Variablen und anderer suboptimaler Codierungspraktiken zu erfordern. Es scheint auch fehleranfällig zu sein.

20
haslo

Natürlich gibt es keine perfekte Antwort. Wenn Sie jedoch den Benutzer zulassen möchten 

  1. bestimmte Zellen auswählen 
  2. erlaube ihnen, diese Zellen zu ändern, und
  3. fangen Sie jeden Klick ab, selbst wiederholte Klicks in derselben Zelle,

dann scheint es am einfachsten zu sein, den Fokus von der ausgewählten Zelle zu entfernen, so dass ein Klick auf diese Option ein Select-Ereignis auslöst.

Eine Möglichkeit besteht darin, den Fokus wie oben vorgeschlagen zu verschieben, dies verhindert jedoch das Bearbeiten der Zellen. Eine weitere Option besteht darin, die Auswahl um eine Zelle (links/rechts/auf/ab) zu erweitern, da dies die Bearbeitung der ursprünglichen Zelle ermöglicht, jedoch ein Select-Ereignis auslöst, wenn diese Zelle erneut selbst angeklickt wird. 

Wenn Sie nur die Auswahl einer einzelnen Zellenspalte überfüllen möchten, können Sie eine ausgeblendete Spalte rechts einfügen, die Auswahl erweitern, um die ausgeblendete Zelle rechts einzufügen, wenn der Benutzer auf die Schaltfläche klickt. Dadurch erhalten Sie eine bearbeitbare Zelle Jedes Mal, wenn darauf geklickt wird. Der Code lautet wie folgt 

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  'prevent Select event triggering again when we extend the selection below
  Application.EnableEvents = False
  Target.Resize(1, 2).Select
  Application.EnableEvents = True
End Sub
20
dbb

Um wiederholte Klicks auf dieselbe Zelle einzufangen, müssen Sie den Fokus auf eine andere Zelle verschieben, sodass Sie bei jedem Klicken die Auswahl verschieben. 

Der folgende Code wählt die obere linke Zelle aus, die auf dem Bildschirm angezeigt wird, wenn Sie auf eine Zelle klicken. Offensichtlich hat es den Fehler, dass es keinen Klick auf die obere linke Zelle einfängt. Dies kann jedoch verwaltet werden (z. B. durch Auswahl der oberen rechten Zelle, wenn die aktive Zelle oben links ist).

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  'put your code here to process the selection, then..
  ActiveWindow.VisibleRange.Cells(1, 1).Select
End Sub
7
dbb

SelectionChange ist das in das Excel-Objektmodell dafür integrierte Ereignis. Es sollte genau so sein, wie Sie es wünschen, und es wird ausgelöst, wenn der Benutzer irgendwo klickt. 

Ich bin nicht sicher, ob ich Ihre Einwände gegen globale Variablen hier verstehe. Sie würden nur 1 benötigen, wenn Sie das Application.SelectionChange-Ereignis verwenden. Sie würden jedoch keine benötigen, wenn Sie den Workbook-Klassencode (um das Ereignis Workbook.SelectionChange abzufangen) oder den Worksheet-Klassencode (um das Ereignis Worksheet.SelectionChange abfangen) verwenden. (Es sei denn, Ihr Problem ist das Problem der "globalen Variablenzurücksetzung" in VBA, für das es nur eine Lösung gibt: Fehlerbehandlung überall. Erlauben Sie keine unbehandelten Fehler, sondern protokollieren Sie sie und/oder melden Sie einen Fehler als Meldung an Box an den Benutzer.)

Möglicherweise müssen Sie auch die Ereignisse Worksheet.Activate () und Worksheet.Deactivate () (oder die Entsprechung in der Workbook-Klasse) und/oder die Ereignisse Workbook.Activate und Workbook.Deactivate () abfangen, damit Sie wissen, wann der Benutzer verfügt geschaltete Arbeitsblätter und/oder Arbeitsmappen. Die Fensteraktivierungs- und -aktivierungsereignisse sollten diesen Ansatz abschließen. Sie könnten alle die gleiche Prozedur aufrufen, jedoch alle dasselbe: Der Benutzer hat den "Fokus" geändert, wenn Sie möchten.

Wenn Sie VBA nicht mögen, können Sie dasselbe mit VB.NET oder C # tun.

[Bearbeiten: Dbb macht einen sehr guten Punkt, wenn das SelectionChange-Ereignis keinen Klick annimmt, wenn der Benutzer in die aktuell ausgewählte Zelle klickt. Wenn Sie das aufgreifen müssen, müssen Sie Unterklassen verwenden.]

1
Mike Rosenblum

Ich glaube nicht Sie können jedoch ein Shape-Objekt (oder ein Wordart- oder ähnliches Element) erstellen. Klicken Sie auf das Ereignis event und platzieren Sie das Objekt an der Position der angegebenen Zelle.

0
TcKs

Das hat für mich funktioniert .....

Private Sub Worksheet_Change(ByVal Target As Range)

    If Mid(Target.Address, 3, 1) = "$" And Mid(Target.Address, 2, 1) < "E" Then
       ' The logic in the if condition will filter for a specific cell or block of cells
       Application.ScreenUpdating = False
       'MsgBox "You just changed " & Target.Address

       'all conditions are true .... DO THE FUNCTION NEEDED 
       Application.ScreenUpdating = True
    End If
    ' if clicked cell is not in the range then do nothing (if condttion is not run)  
End Sub

HINWEIS: Diese Funktion berechnet eine Pivot-Tabelle neu, wenn ein Benutzer ein Element in einem Datenbereich von A4 bis D500 hinzugefügt hat. Es gab geschützte und ungeschützte Abschnitte im Arbeitsblatt. Die eigentliche Prüfung für den Klick ist, ob die Spalte weniger als "E" ist. Die Logik kann so komplex werden, wie Sie eine beliebige Anzahl von Bereichen einschließen oder ausschließen möchten

block1  = row > 3 and row < 5 and column column >"b" and < "d" 
block2  = row > 7 and row < 12 and column column >"b" and < "d" 
block3  = row > 10 and row < 15 and column column >"e" and < "g"

If block1 or block2 or block 3 then
  do function .....
end if  
0
Joe

Ich hatte ein ähnliches Problem und behebte das Problem, indem ich das Makro "onTime" ausführte und einige globale Variablen verwendete, um nur ausgeführt zu werden, wenn der Benutzer aufgehört hat zu klicken.

Public macroIsOnQueue As Boolean
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    macroIsOnQueue = False
    Application.OnTime (Now() + TimeValue("00:00:02")), "addBordersOnRow"
    macroIsOnQueue = True
End sub
Sub addBordersOnRow()
    If macroIsOnQueue Then        
       macroIsOnQueue = False
       ' add code here
    End if
End sub

Immer wenn der Benutzer die Auswahl innerhalb von 2 Sekunden ändert, wird auf diese Weise die Variable macroIsOnQueue auf false gesetzt, die letzte Auswahl wird jedoch geändert, macroIsOnQueue wird auf true gesetzt und das Makro wird ausgeführt.

Hoffe das hilft, Viel Spaß mit VBA !!

0
Dumitru Daniel