Anzeige
Archiv - Navigation
1068to1072
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

VBA calculate/change event

VBA calculate/change event
09.04.2009 16:07:47
Frank
Guten Tag allerseits,
ich hoffe es ist jemand so nett, sich meiner anzunehmen und unterstützt mich bei der Lösung folgenden Problems:
Ich möchte ein Excel-Diagramm (2003) dynamisch über veränderbare Werte aus bestimmten Zellen skalieren. Es handelt sich um ein Diagramm mit jeweils primären und sekundären x- und y-Achsen. Die primäre x-Achse ist als "automatisch" definiert, die sekundäre x-Achse als Zeitachse. Der Zellbereich mit den dynamischen Werten für die Achsenskalierung (Minimum, darunter dann Maximum) sei A1:D2. In der Zeile 3 (A3:D3) stehen ebenfalls variable Werte für die Hauptintervalle der Achsen.
Ich habe nachgeforscht, wie das mit VBA zu lösen ist, und bin auf die Möglichkeit gestoßen, im worksheet Code als change event zu formulieren, gleichzeitig dabei eine "case"-Struktur zu verwenden, um damit die einzelnen Zellen A1:D3 anzusprechen, deren Werte dann MaximumScale, MinimumScale und MajorUnit im VBA-Code sind.
Problem: Die Werte A1:D3 generieren sich über Formeln. Hierzu habe ich gefunden, daß mit worksheet calculate eine Lösung erstellt werden kann.
Damit bin ich aber mit meinem Latein am Ende und drehe mich ständig im Kreis, weil ich zwar im nicht VBA-Bereich von Excel ganz gut zu sein glaube, in VBA aber eine wirkliche Flasche bin.
Kann mich jemand auf den rechten Weg bringen? Wäre wirklich toll.
Beste Grüße
Frank

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
Eines hast du noch vergessen: Wann oder...
09.04.2009 17:20:04
Luc:-?
...aus welchem Grund soll ein Wechsel der Skalierung erfolgen, Frank?
Danach richtet sich dann auch, ob eine Ereignisproz (und welche) verwendet wdn kann oder eine andere Lösung gefunden wdn muss. Select Case x setzt voraus, dass ein x abgefragt wdn kann, dessen Wert dann die Auswahl der unterschiedlichen Skalierungsdatensätze aus den zugehörigen Zellbereichen veranlasst. Wenn dieses x durch einen Zelleintrag zustande kommt, wird ein Worksheet_Change-Ereignis ausgelöst, worauf mit der gleichnamigen Prozedur reagiert wdn kann.
Gruß Luc :-?
Anzeige
AW: Eines hast du noch vergessen: Wann oder...
09.04.2009 17:28:01
Frank
Danke fürs Sichten meines Problems. Ich hoffe, daß ich richtig verstanden habe.
In den Zellen A1:D2 sind untereinanderstehend die Werte für Minimum und Maximum einer jeden Achse. Den jeweiligen Wert verändere ich, indem ich eine Laufleiste (könnte wahlweise auch ein Drehfeld/spin button sein) bediene, deren Bezugszelle Eingang in die Berechnungen in A1:D2 findet.
Klartext: ich bediene die Laufleiste, ein Wert in A1:D2 ändert sich, hieraus soll ein neues Minimum bzw. Maximum der betroffenen Achse im Diagramm sich verändern.
Wie komme ich weiter?
Tut mir leid, musste zwischendurch weg und...
09.04.2009 20:23:15
Luc:-?
...dem vermaledeiten Lappentopf hat's zu lange gedauert und hat sich derweil verabschiedet. Nun darf ich die fast fertige Antwort noch mal schreiben, Frank... :-(
Also, was du schreibst, deutet darauf hin, dass die Skalierungsextrema stets neu ermittelt wdn. Da würde sich schon ..._Change anbieten, wobei die Cases entfallen können, da stets alle benötigten Angaben im Bereich A1:D2 vorliegen und keine Auswahl daraus getroffen wdn muss.
Falls noch andere (das gleiche Ereignis auslösende) Vorgänge auf dem Blatt ablaufen können, empfehle ich, den relevanten Bereich mit vbFkt Intersect gg das "Ziel" der Veränderung (automatisch erzeugter Proz-Parameter Target) zu prüfen:
If Not Intersect(Target, Range("A1:D2") Is Nothing Then
Anschließend können gleich die Zuweisungen der Zellwerte an die betreffenden Achseneigenschaften folgen. Abschließendes End If nicht vergessen!
Allerdings wird diese Prozedur bei jeder Zell(wert)änderung aufgerufen und für jede der betroffenen 8 Zellen idR auch durchgeführt. (Mal testen - Haltepkt setzen oder Mitzählen pgmieren → Ausgabe mit MsgBox!) Sollte nicht weiter stören; wenn doch, Prüfbereich auf die stets letzte geänderte Zelle einschränken (Voraussetzung: immer Änderung aller 8 Zellen).
..._Calculate scheint ungünstiger zu sein, da hier Target nicht z.V. steht und so die Aktion bei jeder Berechnung durchgeführt wird.
Tipp: Falls die Ereignisproz noch für andere Zwecke benötigt wird (nur eine pro Blatt auf dem jeweiligen Blatt und dito auf dem "Mappenblatt" möglich - also insgesamt 2), sollte sie quasi als Verteiler aufgebaut wdn, d.h. Abfragen der relevanten Aktionsmerkmale und Aufruf zuzuordnender separater Public Subprozz in Normalmodul mit Call prozname(param1, ..., param~). Würde ich auch dann immer machen, wenn die auszuführenden Pgmteile recht lang sind...
Frohe Ostern!
Luc :-?
Anzeige
AW: Dateibeispiel
10.04.2009 12:54:46
Frank
Danke, ich versuche gerade, Deine Tipps zu durchdringen und habe mal eine Beispieldatei angefügt.
https://www.herber.de/bbs/user/61133.xls
Ich werde versuchen, ein wenig Code zu produzieren, der mir sinnvoll erscheint und hoffe, dass ich zu einem Ergebnis komme.
Aber eine Sache: Bist Du Dir sicher, dass das alles mit worksheet_change funktionieren kann? Die Werte für die Achsenskalierung ermitteln sich über Formeln und nicht direkte Eingabe in die Zelle A1:D3. Soweit ich an anderer Stelle gelesen habe, ist das eine Limitierung bei der Verwendung von "change". Aus diesem Grund habe ich überhaupt nach der Sinnhaftigkeit von "calculate" gefragt.
Frohe Ostern auch Dir.
Frank
P.S. Hört sich ein bißchen nach halbem Küchenbrand an. Ich hoffe, der Schaden hält sich in Grenzen.
Anzeige
AW: Dateibeispiel
10.04.2009 21:03:50
Frank
Mit diesem Code kann man über manuelle Eingabe in die Zellen A1:D3 erreichen, was ich zuvor beschrieben habe. Wie aber vermutet, funktioniert es nicht mehr, wenn in diesen Zellen Funktionen mit Bezügen auf andere Zellen stehen, aus denen sich die jeweiligen Werte dann erst errechnen.
Es scheint also irgendeine Art von Anpassung nötig zu sein (vielleicht doch irgendwie mit worksheet_calculate?). Luc....und vielleicht auch noch andere: könnt Ihr mir helfen?
Hier der Code für "manuelle Eingabe" zur Skalierung (auch wenn das für Fortgeschrittene witzig klingen mag, ich bin hierüber ein bißchen stolz :-) ):

Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("A1:D3")) Is Nothing Then Exit Sub
With ActiveSheet.ChartObjects("Diagramm 1").Chart
If Range("A1")  "" Then .Axes(xlCategory).MinimumScale = Range("A1")
If Range("A2")  "" Then .Axes(xlCategory).MaximumScale = Range("A2")
If Range("A3")  "" Then .Axes(xlCategory).MajorUnit = Range("A3")
If Range("C1")  "" Then .Axes(xlValue).MinimumScale = Range("C1")
If Range("C2")  "" Then .Axes(xlValue).MaximumScale = Range("C2")
If Range("C3")  "" Then .Axes(xlValue).MajorUnit = Range("C3")
If Range("B1")  "" Then .Axes(xlCategory, xlSecondary).MinimumScale = Range("B1")
If Range("B2")  "" Then .Axes(xlCategory, xlSecondary).MaximumScale = Range("B2")
If Range("B3")  "" Then .Axes(xlCategory, xlSecondary).MajorUnit = Range("B3")
If Range("D1")  "" Then .Axes(xlValue, xlSecondary).MinimumScale = Range("D1")
If Range("D2")  "" Then .Axes(xlValue, xlSecondary).MaximumScale = Range("D2")
If Range("D3")  "" Then .Axes(xlValue, xlSecondary).MajorUnit = Range("D3")
End With
End Sub


Anzeige
Nee, war bloß ärgerlich! Gemeint war ja...
12.04.2009 04:53:00
Luc:-?
...auch mein Lappentopf, Frank!
Da er das öfter macht, hat er sich diese wenig schmeichelhafte Bezeichnung redlich verdient. Meine Frau kam bloß gerade vom Einkauf und brauchte einen Träger...
Zum Problem:
Unter xl12 fkt dein Code. Ich würde nur das ActiveSheet gg Me austauschen - das Ganze fkt ja ohnehin nur auf einem Blatt, das in seinem Dokumentklassenmodul diese Proz enthält, und das heißt hier kurz Me. Da aber stets alle 4 Achsen angesprochen wdn, müssen aber auch schon alle 4 Achsen im Diagramm vorhanden sein. Fehlt eine, kommt es zum Fehler. Wenn du auch Diagramme mit weniger Achsen hier mit einbinden willst, musst du das Abfangen, d.h., entweder dürfen die entsprechenden Zuweisungen dann nicht abgearbeitet wdn oder du fängst diesen Fehler ab - am besten nicht einfach mit On Error Resume Next am PgmAnfang, sondern mit On Error GoTo zeile[nmarke]. Dort fragst du dann die Err.Number ab und kehrst ggf mit Resume Next zum Folgebefehl zurück.
Ob das auch mit früheren xlVersionen fkt, sehe ich mir später an. Dass es an den Fmll in den relevanten Zellen liegt, glaube ich nicht, die wdn ja nicht an das Diagramm übergeben, sondern nur ihr Ergebnis. Das ist ja gerade ein großer Vorteil der Diagramm-Generierung per VBA - das Diagramm bekommt stets alle Daten so wie es sie benötigt - als Zahlen!
Liefert eine der Skalierungszellenformeln mal ein Leer, bleibt hier übrigens der zuletzt eingestellte Wert erhalten, solange bis diese Zelle mal nicht mehr "leer" ist...
Österlicher Gruß, Luc :-?
PS: Stolz kannst du ruhig ein bißchen sein, denn es wäre so ja okay... Ich habe mit Zufallszahlen getestet, da ist das so genau richtig, weil die sich ja ständig ändern. Ansonsten könntest du natürlich auch mit Select Case Target.Address(0, 0) bei jedem Auslösen der Proz auch nur den gerade geänderten Wert übernehmen, also das Target. Wäre möglicherweise eine kaum messbare Winzigkeit schneller, denn auch die andere Version wird ja jetzt 12x aufgerufen bis alle Skalierungswerte ins Diagramm eingetragen sind. Trotzdem halte ich ..._Calculate für ungünstiger.
Anzeige

303 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige