Skip to main content
2 of 7
added 51 characters in body
Naresh
  • 305
  • 1
  • 13

Excel Chart - Crosshair cursor lines with VBA

Submitting for expert review. Refer YouTube video

Paste this code in excel VBE Chart(Sheet) object.

Code works fine. I was wondering if we can avoid deletion and addition of lines with every mouse move. I tried adding lines on chart activate event and then allign those lines using module level variables. But the too procedures cannot work together as by the time chart activate is triggered mouse move already takes place.

Option Explicit

Private xPoint As Variant, yPoint As Variant, XMax As Variant, YMax As Variant, DispScale As Variant
Private shp As Shape, ChartPaperSize, PgWidPXL, PgHgtPXL, ChtAreaWid, ChtAreaHgt, ActWinZoom
Private shpHL As Variant, shpVL As Variant

'--------------------------------------------------------------------------------
Private Sub Chart_MouseMove(ByVal Button As Long, ByVal Shift As Long, ByVal A As Long, ByVal B As Long)
'Dim xPoint As Variant, yPoint As Variant, XMax As Variant, YMax As Variant, DispScale As Variant
'Dim shp As Shape, ChartPaperSize, PgWidPXL, PgHgtPXL, ChtAreaWid, ChtAreaHgt, ActWinZoom
'This macro is suitable for following 4 paper sizes only
'--------------------------------------------------------------------------------
ChartPaperSize = ActiveChart.PageSetup.PaperSize
Select Case ChartPaperSize
' I couldnt find better way to convert paper size number to inches and therafter to pixels
' I dont know why multiplying by 0.9745 or 0.9725 keeps the x, y coordinates more close to the diplayed cursor position
    Case 5 '"xlPaperLegal"
       If ActiveChart.PageSetup.Orientation = xlLandscape Then
       PgWidPXL = 14 * 220 * 0.9745 '220 PPI
       PgHgtPXL = 8.5 * 220 * 0.9725
       Else
       PgWidPXL = 8.5 * 220 * 0.9745
       PgHgtPXL = 14 * 220 * 0.9725
       End If
    Case 1 '"xlPaperLetter"
       If ActiveChart.PageSetup.Orientation = xlLandscape Then
       PgWidPXL = 11 * 220 * 0.9745
       PgHgtPXL = 8.5 * 220 * 0.9725
       Else
       PgWidPXL = 8.5 * 220 * 0.9745
       PgHgtPXL = 11 * 220 * 0.9725
       End If
    Case 9 '"xlPaperA4"
       If ActiveChart.PageSetup.Orientation = xlLandscape Then
       PgWidPXL = 11.69 * 220 * 0.9745
       PgHgtPXL = 8.27 * 220 * 0.9725
       Else
       PgWidPXL = 8.27 * 220 * 0.9745
       PgHgtPXL = 11.69 * 220 * 0.9725
       End If
    Case 8 ' "xlPaperA3"
       If ActiveChart.PageSetup.Orientation = xlLandscape Then
       PgWidPXL = 16.54 * 220 * 0.9745
       PgHgtPXL = 11.69 * 220 * 0.9725
       Else
       PgWidPXL = 11.69 * 220 * 0.9745
       PgHgtPXL = 16.54 * 220 * 0.9725
       End If
    'Case Else
End Select

'Windows display recommended scale of 125% in my computer settings
XMax = PgWidPXL * (100 / 125) ' for A4 2503 for legal 2999 '2395 'Max mousepointer width on 100% chart sheet zoom
YMax = PgHgtPXL * (100 / 125) ' for A4 1764 for legal 1814 '1450 'Max mousepointer height on 100% chart sheet zoom

ChtAreaWid = ChartArea.Width
ChtAreaHgt = ChartArea.Height

DispScale = Round(1161 / ActiveWindow.Width, 2)
' 1161 is ActiveWindow.Width at Windows display recommended scale of 125% on my computer

ActWinZoom = ActiveWindow.Zoom
xPoint = (A * (ChtAreaWid * DispScale) / XMax) / (ActWinZoom / 100)
yPoint = (B * (ChtAreaHgt * DispScale) / YMax) / (ActWinZoom / 100)
'--------------------------------------------------------------------------------
'Delete lines
For Each shp In ActiveChart.Shapes
If shp.Type = msoLine Then
shp.Delete
End If
Next

'Add new lines
With ActiveChart.Shapes.AddLine(1, yPoint, ChartArea.Width, yPoint).Line  'horizontal line
.ForeColor.RGB = RGB(150, 150, 150)
.Weight = 5
End With
With ActiveChart.Shapes.AddLine(xPoint, 1, xPoint, ChartArea.Height).Line  'vertical line
.ForeColor.RGB = RGB(150, 150, 150)
.Weight = 5
End With
'--------------------------------------------------------------------------------
'Above deletion and addition of new lines could be avoided if two lines are already present
'Say, we manually insert line shapes named "Straight Connector 1" and "Straight Connector 2" then

'With ActiveChart.Shapes("Straight Connector 1") 'horizontal line
'.Left = 1
'.Top = yPoint
'.Width = ChartArea.Width
'.Height = yPoint
'End With
'With ActiveChart.Shapes("Straight Connector 2") 'vertical line
'.Left = xPoint
'.Top = 1
'.Width = xPoint
'.Height = ChartArea.Height
'End With
'--------------------------------------------------------------------------------

End Sub
Naresh
  • 305
  • 1
  • 13