2016-06-22 6 views
0

Ich arbeite an einem sehr großen VBA-Projekt in Excel bei meiner Arbeit. Wir haben etwa 1500 Codezeilen für nur ein Feature und etwa ein Dutzend weitere Features. Aus diesem Grund habe ich versucht, alles zu durchbrechen, so dass ich Code für jedes Feature an verschiedenen Orten aufbewahren kann. OOP saugt VBA an ... Das Problem besteht darin, dass diese Steuerelemente Ereignisse auslösen müssen. Natürlich sind einige Ereignisse (wie das Ereignis TextBox_AfterUpdate) beim dynamischen Erstellen von Steuerelementen nicht verfügbar. Es ist ein wenig verschachtelt wegen allem, was vor sich geht, also werde ich es so gut wie möglich abbrechen:Wie kann ich effektiv Steuerelemente dynamisch in Excel VBA erstellen oder Wie verwende ich Application.OnTime()?

Ich habe ein Klassenmodul, das eine Registerkarte für ein mehrseitiges Steuerelement darstellt. Wenn ein Benutzer auf eine Registerkarte klickt, ruft die UserForm dieses Klassenmodul auf, und dort werden die Steuerelemente dynamisch erstellt. Auf diese Weise kann ich den Code in diesem Klassenmodul behalten. Ich habe ein Sub, das ich als das "AfterUpdate" -Subs bezeichnet habe und den Code, den ich brauchte, um dort zu laufen. Jetzt besteht das Problem darin, dass das Sub zur richtigen Zeit aufgerufen wird.

Also was ich getan habe, ist ein Timer der Art zu überprüfen und zu sehen, ob die "ActiveControl" genannten Textbox ist. Wenn dies nicht der Fall ist, können wir davon ausgehen, dass der Fokus weg ist und wir dieses Ereignis auslösen können. Hier ist der Code Ich verwende:

Eine gekürzte Version der Registerkarte Kreation ...

Private WithEvents cmbMarketplace As MSForms.ComboBox 

Public Sub LoadTab(ByVal oPageTab As Object) 
    If TabLoaded Then Exit Sub 

    Set PageTab = oPageTab 

    Dim tmp As Object 

    Set tmp = PageTab.Add("Forms.Label.1") 
    tmp.Top = 6: tmp.Left = 6: tmp.Width = 48 
    tmp.Caption = "Marketplace:" 

    Set cmbMarketplace = PageTab.Add("Forms.ComboBox.1", "cmbMarketplace") 

    ' LOAD OTHER CONTROLS ' 

    TabLoaded = True 
    Start_Timer 
End Sub 

Dann START_TIMER:

Public Sub Start_Timer() 
    TimerActive = True 
    Application.OnTime Now() + TimeValue("00:00:01"), "Timer" 
End Sub 

Und die Unter, die gezündet werden soll:

Public Sub Timer() 
    If TimerActive Then 
     ' DO SOME RANDOM THINGS ' 
     Application.OnTime Now() + TimeValue("00:00:01"), "Timer" 
    End If 
End Sub 

Scheint dies ein vernünftiger Ansatz zur Lösung des Problems, dem ich gegenüberstehe? Ich bin offen für Vorschläge ...

Das ist das erste Problem. Dies scheint eine Menge Arbeit zu sein, um dies zu erreichen. (Ich arbeite daran, Visual Studio zu bekommen, aber ich weiß nicht, ob das passieren wird)

Der obige Code funktioniert, aber die "Timer" Sub wird überhaupt nicht ausgelöst. Ich bekomme keine Fehler, wenn ich nur den Code ausführen. Alles ist geschaffen, alles funktioniert so, wie ich es hoffe. Wenn ich jedoch durch den Code gehe, erhalte ich eventuell folgenden Fehler:

Offensichtlich ist keiner dieser Vorschläge gültig. Makros sind aktiviert und das Untermodul befindet sich im selben Klassenmodul. Ich habe versucht, es öffentlich zu machen, dasselbe Problem. Versuchte "ClassModule1! Timer" ohne Erfolg. Ich bin am Ende meiner Weisheit und versuche das herauszufinden. Ich denke daran, dass die Leute ALLES in die Benutzerform schreiben oder einfach aufgeben.

Hat jemand irgendwelche Vorschläge, wie man große Codeabschnitte effektiv auflösen kann? Und hat jemand eine Ahnung, warum dieses Sub nicht laufen wird und scheinbar nicht gefunden werden kann?

Ich verstehe, dass dies eine verwirrende Situation ist, also wenn Sie mehr Informationen oder Codebeispiele benötigen oder wissen möchten, warum ich etwas so eingerichtet habe, wie ich es tue, lassen Sie es mich wissen.

Danke!

+1

Mögliches Duplikat von [Hinzufügen von Ereignissen zu Steuerelementen, die zur Laufzeit in Excel mit VBA erstellt werden] (http://Stackoverflow.com/q/3014421/4088852), [Erstellen von Ereignishandlern für mehrere dynamische Steuerelemente] (http://stackoverflow.com/q/25384623/4088852) und wahrscheinlich auch andere. – Comintern

Antwort

4

Obviously neither of those suggestions are valid. Macros ARE enabled and the sub is in the same darn class module.

Es ist das Problem: ein Makro nicht in einem Klassenmodul sein. Die Nachricht ist vollständig korrekt: VBA kann die Timer-Prozedur nicht sehen, da sie nicht zugänglich ist.

Klasse A-Modul ist ein Konzept für ein Objekt , VBA (oder eine OOP-Sprache was das betrifft) nicht irgendetwas mit einem Klassenmodul tun, ohne eine Instanz dieser Klasse - das heißt ein Objekt.

Ihr Timer-Rückruf muss ein Public Sub in einem Standardmodul, sein, so dass es direkt als Makro aufgerufen werden kann. Öffentliche Prozeduren einer Klassenmodule sind Methoden, nicht Makros.

Je nachdem, was ' DO SOME RANDOM THINGS ' tatsächlich bedeutet, kann dies eine Umstrukturierung erforderlich machen oder auch nicht.

1500-liner Spaghetti Code kann in jeder Sprache geschrieben werden BTW.

Verwandte Themen