Diagrammpunkte 'ziehen' bei Excel >= 2007

Hallo VBA-Experten,

bei Excel 2003 konnte man in einem X-Y-Diagramm auf einen Datenpunkt klicken und ihn dann mit der Maus an andere Koordinaten ziehen. Die dazugehörigen Zellen in der Tabelle wurden automatisch mit geändert.
Seit Excel 2007 geht das ja leider nicht mehr:
http://www.pctipp.ch/forum/showthread.php?t=17634

Ich wollte jetzt mal versuchen, ob ich diese Funktionalität selber nachbauen kann (ich hab’s gesehen: Auf der verlinkten Seite wird ein Add-In erwähnt, was das wohl kann. Es hat mich aber gereizt, es mal selber zu versuchen).
Ein paar Vorversuche mit den MouseDown-, MouseMove- und MouseUp Events habe ich gemacht. Klappt auch schon teilweise.
Mit GetChartElement kann ich auch die Datenreihe und den Datenpunkt finden, auf den ich geklickt habe.
Und hier kommt meine eigentliche Frage:
Wie kann ich die zu diesem Punkt gehörenden Zellen für die X- und Y-Koordinate herausfinden? Dort muss der Makro ja die neuen Werte eintragen.
Meine erste Idee war, die „Formula“ der Datenreihe auseinander zu pflücken, also Stringanalyse. Das wäre bei einer einfachen Formel wie

=DATENREIHE(;Tabelle1!$A$1:blush:A$10;Tabelle1!$B$1:blush:B$10;1)

noch machbar. Aber bei Sachen wie

=DATENREIHE(;(Tabelle1!$D$1:blush:D$3;Tabelle1!$D$5:blush:D$7;Tabelle1!$D$9:blush:D$12);(Tabelle1!$E$1:blush:E$3;Tabelle1!$E$5:blush:E$7;Tabelle1!$E$9:blush:E$12);2)

geht es doch gewaltig an die Schmerzgrenze.
Nächste Idee war, nicht über „Formula“, sondern über „XValues“ und „Values“, also z.B.:

Sub punkteÄndern()
 Dim xWerte As Variant, yWerte As Variant

 With ActiveChart.SeriesCollection(1)
 xWerte = .XValues
 yWerte = .Values
 xWerte(5) = 23
 yWerte(5) = 50
 .XValues = xWerte
 .Values = yWerte
 End With
End Sub

Wenn ich das aber mit der ersten Datenreihe von oben mache, dann sieht die Formel hinterher so aus:

=DATENREIHE(;{1\2\3\4\23\6\7\8\9\10};{1\2\3\4\50\6\7\8\9\10};1)

Also alle Zellbezüge weg. Nicht im Sinne des Erfinders.
Dann habe ich in Excel4 Makrofunktionen gestöbert, ob es dort vielleicht eine Funktion gibt, die zu einem Datenpunkt die dazugehörigen Zellen ausspuckt. Nach einer halben Stunde wühlen in den alten Hilfe-Dateien nix entsprechendes gefunden.
Also, Experten vor: Wie komme ich an die Zellen, in denen die X- und Y-Werte für einen Datenpunkt stehen.

Danke und Gruß, Andreas

http://www.pctipp.ch/forum/showthread.php?t=17634
wird ein Add-In erwähnt, was das wohl kann. Es hat mich
aber gereizt, es mal selber zu versuchen).

Wie kann ich die zu diesem Punkt gehörenden Zellen für die X-
und Y-Koordinate herausfinden? Dort muss der Makro ja die
neuen Werte eintragen.

Zu dem „ziehen“ nützt dir das nix aber du kennst doch die Datenpunkt-
Nr mit GetChartElement?
Siehe bitte nachstehenden Code.
Achja, ein Tipp, das Diagramm sollte in einem Diagrammblatt
sein, das macht vieles einfacher mit dem referenzieren.

Und aus der Datenpunkt-Nr. die Datenzellen zu ermitteln ist doch
wohl einfach oder übersehe ich was?

Für eine Semi-Lösung könnte man jetzt in der Chart_MouseDown
Prozedur eine UF starten wo die Datenwerte angezeigt werden und
du kannst sie dort verändern, Nach OK wird das dann umgesetzt.

Du willst aber eine Ziehen-Lösung. M.E. wirste dann mit API
die Maus überwachen müßen. Ich mutmaße da gibts schon Chancen
durch API was zu basteln was die Startposition der maus ermittelt
und dann die Endposition nach Move.

Aber das muß man wieder umrechnen auf die Diagrammkoordinaten.
Um dann daraus wieder die Zellwerte zu errechnen die man braucht für den neuen „gezogenen“ Datenpunkt.

Oha, du hast dir keine Aufgabe ausgesucht *glaub*

Meine erste Idee war, die „Formula“ der Datenreihe auseinander
zu pflücken, also Stringanalyse. Das wäre bei einer einfachen

Ich verstehe nicht ganz was Datenreihe mit Ziehen zu tun hat?

Gruß
Reinhard

Private Sub Chart\_MouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
 Dim lngPoint As Long
 Dim L As Long
 Dim ID As Long
 Dim myChart As Chart
 Set myChart = Me
 If Button = 1 Then 'Linksclick
 myChart.GetChartElement x, y, ID, L, lngPoint
 If ID = xlSeries Then 'Schauen was selectiert ist
 MsgBox "Datenpunkt " & lngPoint
 End If
 End If
End Sub

Hallo Reinhard,

http://www.pctipp.ch/forum/showthread.php?t=17634
wird ein Add-In erwähnt, was das wohl kann. Es hat mich
aber gereizt, es mal selber zu versuchen).

Wie kann ich die zu diesem Punkt gehörenden Zellen für die X-
und Y-Koordinate herausfinden? Dort muss der Makro ja die
neuen Werte eintragen.

Zu dem „ziehen“ nützt dir das nix aber du kennst doch die
Datenpunkt-
Nr mit GetChartElement?
Siehe bitte nachstehenden Code.

Ja, natürlich kenne ich die Datenpunktnummer. Mein Code sieht ähnlich aus, wie der da unten. Aber das hilft mir ja nicht weiter. Ich möchte ja die Zellen haben, die zu diesem Datenpunkt gehören. Denn da will ich letzlich die neuen Koordainaten eintragen.

Achja, ein Tipp, das Diagramm sollte in einem Diagrammblatt
sein, das macht vieles einfacher mit dem referenzieren.

Weiß ich. Mach ich sowieso immer.

Und aus der Datenpunkt-Nr. die Datenzellen zu ermitteln ist
doch
wohl einfach oder übersehe ich was?

ich glaub’, da übersiehst du was. Kannst du mir mal zeigen, wie das „einfach“ geht?
Meine Versuche hatte ich ja bereits beschrieben.

Für eine Semi-Lösung könnte man jetzt in der Chart_MouseDown
Prozedur eine UF starten wo die Datenwerte angezeigt werden
und
du kannst sie dort verändern, Nach OK wird das dann umgesetzt.

Du willst aber eine Ziehen-Lösung. M.E. wirste dann mit API
die Maus überwachen müßen. Ich mutmaße da gibts schon Chancen
durch API was zu basteln was die Startposition der maus
ermittelt
und dann die Endposition nach Move.

Ich kann ja auch ohne API in Excel mit dem MouseMove Ereignis die aktuelle Position (in Pixeln) ermitteln.

Aber das muß man wieder umrechnen auf die Diagrammkoordinaten.

Die Umrechnerei ist etwas tricky, aber das habe ich mittlerweile gelöst

Um dann daraus wieder die Zellwerte zu errechnen die man
braucht für den neuen „gezogenen“ Datenpunkt.

Oha, du hast dir keine Aufgabe ausgesucht *glaub*

Meine erste Idee war, die „Formula“ der Datenreihe auseinander
zu pflücken, also Stringanalyse. Das wäre bei einer einfachen

Ich verstehe nicht ganz was Datenreihe mit Ziehen zu tun hat?

Mit Ziehen direkt nichts. Aber, wenn ich das Ziehen mit MouseMove überwache, habe ich immer die aktuelle Cursorposition in Pixeln. Dann umrechnen auf Benutzerkorodinaten und eintragen in die Zellen. Um eben diese Zellen zu finden, muss ich die „Formula“ der Datenreihe zerpflücken.

Gruß
Reinhard

Gruß, Andreas

Private Sub Chart_MouseDown(ByVal Button As Long, ByVal Shift
As Long, ByVal x As Long, ByVal y As Long)
Dim lngPoint As Long
Dim L As Long
Dim ID As Long
Dim myChart As Chart
Set myChart = Me
If Button = 1 Then 'Linksclick
myChart.GetChartElement x, y, ID, L, lngPoint
If ID = xlSeries Then 'Schauen was selectiert ist
MsgBox "Datenpunkt " & lngPoint
End If
End If
End Sub

Ich möchte ja die Zellen haben, die zu diesem
Datenpunkt gehören. Denn da will ich letzlich die neuen
Koordainaten eintragen.

Hallo Andreas,

merk dir bitte den Namen Nepumuk, es lohnt sich sehr.

Gruß
Reinhard

Ich möchte ja die Zellen haben, die zu diesem
Datenpunkt gehören. Denn da will ich letzlich die neuen
Koordainaten eintragen.

Hallo Andreas,

merk dir bitte den Namen Nepumuk, es lohnt sich sehr.

Gruß
Reinhard

hallo Reinhard,

OK, ich werd’ mir Nepomuk mal merken. Aber bei meinem momentanen Problem bringt er mich auch nicht weiter: In deinem Link liest er auch nur die Daten zu dem Punkt aus (das habe ich ja auch schon gemacht). Ich weiß aber trotzdem nicht, aus welchen Zellen die stammen.

Gruß, Andreas

Ich möchte ja die Zellen haben, die zu diesem
Datenpunkt gehören. Denn da will ich letzlich die neuen
Koordainaten eintragen.

Link liest er auch nur die Daten zu dem Punkt aus (das habe
ich ja auch schon gemacht). Ich weiß aber trotzdem nicht, aus
welchen Zellen die stammen.

Hallo Andreas,

das ist kein Problem.
Aus der Information ReihenNr, Punkt-Nr kriegt man auch
neben den Werten für x und y auch ihre Zelladressen, ihr Blatt heraus.

Ich wollt erst nicht, denn obwohl schon lange Zeit her, weiß ich
daß Vba-Zugriff problematisch ist und ich gescheitert bin.
Plan von mir war, das was Excel nicht (so einfach) bietet per
Vba zu tun.
Fünfte Y-Achse, Skalierungen nach Wunsch usw.

Mein Lösungsansatz war, dann zeichne ich so Dinger einfach.
Dann habe ich mich wie du wohl jetzt in Vba bei Diagrammen
durch wie üblich googeln schlau gemacht.

Und siehe da, ICH hatte es geschafft bei einem bestehenden
Diagramm diese Dinge tun zu können. Habe ich mich gefreut.
Aber, sobald man im Diagramm die Legende ein/ausblendete,
anders positionierte war mein ganzer schöner Code reif für die Tonne.

Dieses Dilemma meinte ich als ich dir das schrieb:

„Aber das muß man wieder umrechnen auf die Diagrammkoordinaten.
Um dann daraus wieder die Zellwerte zu errechnen die man braucht für
den neuen „gezogenen“ Datenpunkt.
Oha, du hast dir keine Aufgabe ausgesucht *glaub*“

Gut, war früher, vorbei vergessen. Villeicht schaffen wir es zusammen.

Also, anbei ist Code aus meiner Baustellenmappe.
Nix dolles, da stehen in Blatt1 in A1:A5 die entsprechenden
Zahlen, 1,2,3,…
In B1:B5 Zufallszahlen.
Im Diagrammblatt halt das Diagramm, Punkt, Linie, XY, k.A.
wervechsel ich immer *gg*

Und, es ist Ausprobiercode, aber steht m.E: alles drin was ich sage
/sagte was möglich ist.

Damit schaffte ich es schon, auf einen Datenpunkt bzw.
dessen Datenlinienbereich zu klicken dann Mousedown und
nach MouseUP wurde dann für diesen datenpunkt in seinen
Zellen beim Y-Wert etwas eingetragen, im Code die 55.

Was da, neben vielem anderen, noch fehlt ist die Umrechnung :frowning:
Ich will ja nicht fest 55 eintragen sondern den Wert der dem
Endpunkt meiner „Ziehung“ entspricht.

Gruß
Reinhard

Option Explicit

Public ReiheNr As Long, PunktNr As Long, JetztGehtDiePartyAb As Boolean
Public YWert

Private Sub Chart\_MouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
Dim lngPoint As Long, L As Long, ID As Long, S, Quelle
If Button = 1 Then 'Linksclick
 With Me
 .GetChartElement x, y, ID, ReiheNr, PunktNr
' .Deselect
 If ID = xlSeries Then 'Schauen was selectiert ist
 JetztGehtDiePartyAb = True

 End If
 End With
End If
End Sub

Private Sub Chart\_MouseUp(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
Dim kurzReiheNr As Long, kurzPunktNr As Long, ID As Long, S
If JetztGehtDiePartyAb = False Then Exit Sub
 JetztGehtDiePartyAb = False
 With Me
 .GetChartElement x, y, ID, kurzReiheNr, kurzPunktNr
' If kurzReiheNr ReiheNr Then
' MsgBox "fluuuuch"
' Exit Sub
' End If
 With .SeriesCollection(ReiheNr)
 'MsgBox Range(Split(.Formula, ",")(2))(PunktNr).Value
 S = .Values '(PunktNr)
 'MsgBox S(2)
' Range(Split(.Formula, ",")(2))(PunktNr).Value = 55
' Range(Split(.Formula, ",")(2))(PunktNr).Value = \_
' .Values(PunktNr)
 MsgBox Range(Split(.Formula, ",")(2))(PunktNr).Address
 MsgBox S(PunktNr)

 Range(Split(.Formula, ",")(2))(PunktNr).Value = \_
 S(PunktNr)

 End With
 End With
End Sub

'Private Sub Chart\_MouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
'Dim lngPoint As Long, L As Long, ID As Long, S, Quelle
'If Button = 1 Then 'Linksclick
' With Me
' .GetChartElement x, y, ID, L, lngPoint
' .Deselect
' If ID = xlSeries Then 'Schauen was selectiert ist
' With .SeriesCollection(L)
' Quelle = Split(.Formula, ",")
' MsgBox .Formula
' MsgBox .Name
' MsgBox Quelle(1)
' MsgBox Quelle(2)
' MsgBox "Datenpunkt " & lngPoint
' MsgBox "Reihennummer: " & L & vbLf & \_
' "Reihenname: " & .Name & vbLf & \_
' "Reihenname: " & .Name & vbLf
'
' End With
'
'
' End If
' End With
'End If
'End Sub

Hallo Andreas,

Hi Reinhard,

das ist kein Problem.
Aus der Information ReihenNr, Punkt-Nr kriegt man auch
neben den Werten für x und y auch ihre Zelladressen, ihr Blatt
heraus.

Ja, dank dem Thread eins weiter oben bin ich da auch schon fast dran (näheres später).

Aber, sobald man im Diagramm die Legende ein/ausblendete,
anders positionierte war mein ganzer schöner Code reif für die
Tonne.

Ich weiß, wie knifflig das ist. Schon herauszukriegen, wo die Grenzen des Plotbereichs liegen, ist eine Sau Arbeit. Vielleicht hab ich eine Methode, mit der das halbwegs gut funktioniert. Ich mach am Wochenende mal eine Bespielmappe fertig und lade sie hoch. Dann kannst du sie mal zerpflücken.

Dieses Dilemma meinte ich als ich dir das schrieb:

"Aber das muß man wieder umrechnen auf die
Diagrammkoordinaten.

Das ist noch das kleinste Problem. Wenn man die Chartarea-Grenzen in Pixeln, die Mausklickposition in Pixeln und die Chartarea-Grenzen in User-Koordinaten (MinimumScale, MaximumScale) hat, ist es eigentlich nurnoch ein etwas abgewandelter Dreisatz.

Gut, war früher, vorbei vergessen. Villeicht schaffen wir es
zusammen.

Wäre schön. Bei uns in der Firma wird gerade von Excel 2003 auf 2007 umgestellt und die Kollegen fluchen kräftig, weil sie keine Punkte mehr „ziehen“ können. Wenn ich da was anbieten könnte, wäre die Freude groß.

Also, anbei ist Code aus meiner Baustellenmappe.
Nix dolles, da stehen in Blatt1 in A1:A5 die entsprechenden
Zahlen, 1,2,3,…
In B1:B5 Zufallszahlen.
Im Diagrammblatt halt das Diagramm, Punkt, Linie, XY, k.A.
wervechsel ich immer *gg*

Und, es ist Ausprobiercode, aber steht m.E: alles drin was ich
sage
/sagte was möglich ist.

Damit schaffte ich es schon, auf einen Datenpunkt bzw.
dessen Datenlinienbereich zu klicken dann Mousedown und
nach MouseUP wurde dann für diesen datenpunkt in seinen
Zellen beim Y-Wert etwas eingetragen, im Code die 55.

Was da, neben vielem anderen, noch fehlt ist die Umrechnung

-(

Ich will ja nicht fest 55 eintragen sondern den Wert der dem
Endpunkt meiner „Ziehung“ entspricht.

Gruß
Reinhard

Option Explicit

Public ReiheNr As Long, PunktNr As Long, JetztGehtDiePartyAb
As Boolean
Public YWert

Private Sub Chart_MouseDown(ByVal Button As Long, ByVal Shift
As Long, ByVal x As Long, ByVal y As Long)
Dim lngPoint As Long, L As Long, ID As Long, S, Quelle
If Button = 1 Then 'Linksclick
With Me
.GetChartElement x, y, ID, ReiheNr, PunktNr
’ .Deselect
If ID = xlSeries Then 'Schauen was selectiert ist
JetztGehtDiePartyAb = True

End If
End With
End If
End Sub

Private Sub Chart_MouseUp(ByVal Button As Long, ByVal Shift As
Long, ByVal x As Long, ByVal y As Long)
Dim kurzReiheNr As Long, kurzPunktNr As Long, ID As Long, S
If JetztGehtDiePartyAb = False Then Exit Sub
JetztGehtDiePartyAb = False
With Me
.GetChartElement x, y, ID, kurzReiheNr, kurzPunktNr
’ If kurzReiheNr ReiheNr Then
’ MsgBox „fluuuuch“
’ Exit Sub
’ End If
With .SeriesCollection(ReiheNr)
'MsgBox Range(Split(.Formula, „,“)(2))(PunktNr).Value
S = .Values '(PunktNr)
'MsgBox S(2)
’ Range(Split(.Formula, „,“)(2))(PunktNr).Value = 55
’ Range(Split(.Formula, „,“)(2))(PunktNr).Value = _
’ .Values(PunktNr)
MsgBox Range(Split(.Formula, „,“)(2))(PunktNr).Address
MsgBox S(PunktNr)

Range(Split(.Formula, „,“)(2))(PunktNr).Value = _
S(PunktNr)

End With
End With
End Sub

'Private Sub Chart_MouseDown(ByVal Button As Long, ByVal Shift
As Long, ByVal x As Long, ByVal y As Long)
'Dim lngPoint As Long, L As Long, ID As Long, S, Quelle
'If Button = 1 Then 'Linksclick
’ With Me
’ .GetChartElement x, y, ID, L, lngPoint
’ .Deselect
’ If ID = xlSeries Then 'Schauen was selectiert ist
’ With .SeriesCollection(L)
’ Quelle = Split(.Formula, „,“)
’ MsgBox .Formula
’ MsgBox .Name
’ MsgBox Quelle(1)
’ MsgBox Quelle(2)
’ MsgBox "Datenpunkt " & lngPoint
’ MsgBox "Reihennummer: " & L & vbLf & _
’ "Reihenname: " & .Name & vbLf & _
’ "Reihenname: " & .Name & vbLf

’ End With


’ End If
’ End With
'End If
'End Sub

Anmerkung zu dem

Range(Split(.Formula, ",")(2))(PunktNr).Address

Das funtioniert m.E. nur wenn die Formula sehr einfach ist, und ohne Namen, also z.B.

=DATENREIHE(;Tabelle1!$A$1:blush:A$10;Tabelle1!$B$1:blush:B$10;1)

Wenn sowas kommt,

=DATENREIHE("Das ist der Name, den die Reihe hat";(Tabelle1!$D$1:blush:D$3;Tabelle1!$D$5:blush:D$6;Tabelle1!$D$8:blush:D$10);(Tabelle1!$E$1:blush:E$3;Tabelle1!$E$5:blush:E$6;Tabelle1!$E$8:blush:E$10);2)

dann gibt’s arge Probleme.

Ich melde mich, wenn ich die Demomappe fertig hab.

Gruß und danke,
Andreas

Grüezi Andreas

Bei uns in der Firma wird gerade von Excel 2003
auf 2007 umgestellt und die Kollegen fluchen kräftig, weil sie
keine Punkte mehr „ziehen“ können. Wenn ich da was anbieten
könnte, wäre die Freude groß.

Hmmm, wie in dem zum oben genannten Link zum AddIn geschildert wird, braucht es für jeden Diagramm-Typen eine eigene Oberfläche uns Auswertung.

Daher würde ich echt mal das Diagramm selber testen (lassen) und den Feedback abwarten, bevor Du dir die ganze Mühe machst…

Mit freundlichen Grüssen

Thomas Ramel

  • MVP für MS-Excel -

Hallo Andreas,

Aber, sobald man im Diagramm die Legende ein/ausblendete,
anders positionierte war mein ganzer schöner Code reif für die
Tonne.

Ich weiß, wie knifflig das ist. Schon herauszukriegen, wo die
Grenzen des Plotbereichs liegen, ist eine Sau Arbeit.
Vielleicht hab ich eine Methode, mit der das halbwegs gut
funktioniert.

würd ich sehr gern sehen, daran bin ich damals gescheitert.

Ich mach am Wochenende mal eine Bespielmappe
fertig und lade sie hoch. Dann kannst du sie mal zerpflücken.

Okay.

Anmerkung zu dem
Range(Split(.Formula, „,“)(2))(PunktNr).Address

Das funtioniert m.E. nur wenn die Formula sehr einfach ist,
und ohne Namen, also z.B.
=DATENREIHE(;Tabelle1!$A$1:blush:A$10;Tabelle1!$B$1:blush:B$10;1)
Wenn sowas kommt,
=DATENREIHE(„Das ist der Name, den die Reihe
hat“;(Tabelle1!$D$1:blush:D$3;Tabelle1!$D$5:blush:D$6;Tabelle1!$D$8:blush:D$10
);(Tabelle1!$E$1:blush:E$3;Tabelle1!$E$5:blush:E$6;Tabelle1!$E$8:blush:E$10);2
dann gibt’s arge Probleme.

Gemach gemach, ich wäre hochzufrieden wir würden Code basteln
können der in einem einfachen Punkte Diagramm auf das „Ziehen“
reagiert und das perfekt.
Das dann zu erweitern auf Datenreihen wie du sie zeigst oder
irgendwelche Bubble-Diagramme ist dann die nächste Herausforderung.

Ich melde mich, wenn ich die Demomappe fertig hab.

Kein Stress. Carpe diem :smile:

Gruß
Reinhard

Hallo Thomas,

in unserer Abteilung geht es vornehmlich (oder eigentlich ausschließlich) um XY-Diagramme.
Außerdem gibt es bei uns das unselige Konstrukt, dass die IT-Abteilung zwar so gut wie alles von Außen (also auch z.B. dieses Add-In) verbietet; wenn man aber Support für VBA haben will, sind sie ratlos. Also bin ich/ist unsere Abteilung da auf mich/sich allein gestellt. Deswegen mach ich mir die Mühe. Und nebenbei ist es (ehrlich gesprochen) für mich eine Programmier-Herausforderung, bei der ich viel dazu lernen kann.

Gruß nach Helvetia,

Andreas