Dial drawn by Access on an Access report Ms Access Gurus

Do you like this? Dial a donation, thank you!

Draw a Dial in Access

Draw Dials showing a needle pointing to your value on Access reports! VBA procedure that's easy to call from code behind a report. Access can draw complex objects using a few simple methods.

The code that does the drawing is all in one module that you can easily import into your projects. Although the drawing is complex, you can do a lot with Circle and Line methods.

DevCon
April 27 + 28 (Thursday + Friday), 2023

Do you want to participate in a presentation about drawing on Access reports? Come to Access DevCon, a huge annual Access conference open to the world, organized by Karl Donaubauer with help from Peter Doering and Philipp Stiefel. Here are the speakers: Access DevCon Agenda.

Join me, Access experts, and developers who love Access. I'm presenting Draw Gadgets on Access Reports and would be happy to see you. It's virtual, so you can join from anywhere! Register for DevCon

Show a Dial on an Access report

Draw a Dial with a needle ponting to value. Colors of dial range from Red to Orange to Yellow to Green, and the needle visually shows fraction or percentage value on your Access reports. VBA procedure that's easy to call from code behind reports.

Quick Jump

Goto Top  


Download

Download zipped BAS file you can import into your Access projects: mod_Draw_Dial_s4p.zip

Download zipped ACCDB file with a sample sample report, and module: DrawDial_s4p_ACCDB.zip

Remember to UNBLOCK files you download to remove the Mark of the Web. Here are steps to do that: https://msaccessgurus.com/MOTW_Unblock.htm

Goto Top  

Try it yourself

There are 2 sample reports and a table with numbers to use for data.

Goto Top  

VBA

Standard module

Specify the report object, the XY coordinates of the dial center, the radius, value (fraction or percentage), and optionally a color for the center, and ratio of center to the total size. Linear measurements are in twips (TWenty In a Point).

'*************** Code Start *****************************************************
' module: mod_Draw_Dial_s4p
'-------------------------------------------------------------------------------
' Purpose  : Draw a Dial on an Access report
' Author   : crystal (strive4peace)
' License  : below code
' Code List: msaccessgurus.com/code.htm
' This code: http://msaccessgurus.com/VBA/Code/DrawDial.htm
'-------------------------------------------------------------------------------
'           global variables
'-------------------------------------------------------------------------------
'comment if defined elsewhere
Public ganColorRedOrangeYellowGreen30(1 To 30) As Long 
Public Const TWIPperINCH As Long = 1440 
Public Const PI As Double = 3.14159 
Public Const gZero As Double = 0.0000001 

'-------------------------------------------------------------------------------
'           Draw_Dial_s4p
'-------------------------------------------------------------------------------
Sub Draw_Dial_s4p(oReport As Report _ 
   ,pXCenter As Single,pYCenter As Single _ 
   ,pRadius As Single _ 
   ,Optional psgValue As Variant = -1 _ 
   ,Optional pnColorCenter As Long = vbWhite _ 
   ,Optional psgRatio As Single = 0.6 _ 
   ) 
'220617 strive4peace, 230414
'draw a dial with 30 colors from Red to Orange to Yellow to Green
'dial starts in SW quadrant
   
   'PARAMETERS
   '  oReport is the Report object
   '  pXCenter is the center of dial in twips for the x-coordinate
   '  pYCenter is the center of dial in twips for the y-coordinate
   '  pRadius is the circle radius in twips
   'OPTIONAL PARAMETERS
   '  psgValue is a percent % or fraction --
   '     defined as variant so it can be null
   '  pnColorCenter is the long integer color number for the middle
   '  psgRatio = ratio of inside circle to circle

   If psgValue > 1 Then  'value can't be greater than 100%
      psgValue = 1 
   ElseIf IsNull(psgValue) Then 
      psgValue = -1  'don't show needle
   End If 

   Dim sgRadiusInside As Single _ 
      ,sgRadiusNeedle As Single _ 
      ,x1 As Single,y1 As Single _ 
      ,x2 As Single,y2 As Single _ 
      ,sgAngle As Single _ 
      ,sgAngle1 As Single _ 
      ,sgAngle2 As Single _ 
      ,sgStartAngle As Single _ 
      ,sgWedgeAngle As Single _ 
      ,sgTickAngle As Single _ 
      ,i As Integer _ 
      ,iQty As Integer _ 
      ,nColorNeedle As Long 

   Dim iGapDegree As Integer _ 
      ,sgGapAngle As Single 
      
   If ganColorRedOrangeYellowGreen30(1) = 0 Then 
      'set colors if not yet defined
      Call SetColors_RedOrangeYellowGreen30 
   End If 
   
   iQty = 30  'number of wedges - depends on number of colors
   
   sgTickAngle = 1 / 180 * PI  'spacing between wedges for tick marks
   iGapDegree = 60  'gap at bottom
   sgGapAngle = iGapDegree / 180 * PI 
   sgWedgeAngle = ((PI * 2) - sgGapAngle) / iQty 
   
   sgStartAngle = 1.5 * PI - sgGapAngle / 2  '270° - half gap

   nColorNeedle = RGB(0,0,255)  'blue 16711680

   With oReport 
      
      .ScaleMode = 1  'twips
      .DrawWidth = 1  'pixel

      .FillStyle = 0  'Opaque

      sgAngle2 = sgStartAngle 

      'draw colored wedges for the dial
      For i = 1 To 30 
         sgAngle1 = sgAngle2 - sgWedgeAngle 
         'do this so it can be negative
         If sgAngle1 = 0 Then 
            sgAngle1 = gZero 
         End If 
         'Circle angle: 0 to 2 pi
         ' starts at sgStartAngle and goes backward
         ' to be clockwise
         .FillColor = ganColorRedOrangeYellowGreen30(i) 
         oReport.Circle (pXCenter,pYCenter) _ 
               ,pRadius _ 
               ,ganColorRedOrangeYellowGreen30(i) _ 
               ,-(sgAngle1 + sgTickAngle) _ 
               ,-(sgAngle2 - sgTickAngle) 
               
         If sgAngle1 < 0.0001 Then 
            sgAngle2 = 2 * PI - gZero 
         Else 
            sgAngle2 = sgAngle1 
         End If 
      Next i 
         
      'draw center circle in the middle
      .FillColor = pnColorCenter 
      sgRadiusInside = psgRatio * pRadius 
      oReport.Circle (pXCenter,pYCenter) _ 
         ,sgRadiusInside _ 
         ,pnColorCenter 

      'draw needle
      If psgValue >= 0 Then 
         'round end
         sgRadiusNeedle = pRadius * 0.15 
         
         'find the angle for the value
         sgAngle = sgStartAngle - _ 
            (((2 * PI) - sgGapAngle) _ 
            * psgValue) 
   
         If sgAngle < 0 Then 
            sgAngle = sgAngle + (2 * PI) 
         End If 
         x1 = pXCenter + Cos(sgAngle) _ 
               * (sgRadiusInside - sgRadiusNeedle * 1.5) 
         y1 = pYCenter - Sin(sgAngle) _ 
               * (sgRadiusInside - sgRadiusNeedle * 1.5) 
         'draw circle
         .FillColor = nColorNeedle 
         sgRadiusInside = psgRatio * pRadius 
         oReport.Circle (x1,y1) _ 
            ,sgRadiusNeedle _ 
            ,nColorNeedle 
         
         'outside coordinate for needle
         x2 = pXCenter + Cos(sgAngle) _ 
               * pRadius 
         y2 = pYCenter - Sin(sgAngle) _ 
               * pRadius 
         
         'draw blue line for needle
         .DrawWidth = 10 
         oReport.Line (x1,y1)-(x2,y2),nColorNeedle 
      End If  'needle
      
   End With 
      
Proc_Exit: 
   On Error GoTo 0 
   Exit Sub 
  
Proc_Err: 
   MsgBox Err.Description,,_ 
        "ERROR " & Err.Number _ 
        &  "   Draw_Dial_s4p "

   Resume Proc_Exit 
   Resume 
   
End Sub 

'-------------------------------------------------------------------------------
'           SetColors_RedOrangeYellowGreen30
'-------------------------------------------------------------------------------
Public Sub SetColors_RedOrangeYellowGreen30() 
   ganColorRedOrangeYellowGreen30(1) = 2763685    'RGB: 165, 43, 42
   ganColorRedOrangeYellowGreen30(2) = 2105532    'RGB: 188, 32, 32
   ganColorRedOrangeYellowGreen30(3) = 1382098    'RGB: 210, 22, 21
   ganColorRedOrangeYellowGreen30(4) = 658408    'RGB: 232, 11, 10
   ganColorRedOrangeYellowGreen30(5) = 255    'RGB: 255, 0, 0
   ganColorRedOrangeYellowGreen30(6) = 10751    'RGB: 255, 41, 0
   ganColorRedOrangeYellowGreen30(7) = 21247    'RGB: 255, 82, 0
   ganColorRedOrangeYellowGreen30(8) = 31999    'RGB: 255, 124, 0
   ganColorRedOrangeYellowGreen30(9) = 42495    'RGB: 255, 165, 0
   ganColorRedOrangeYellowGreen30(10) = 42495    'RGB: 255, 176, 0
   ganColorRedOrangeYellowGreen30(11) = 48383    'RGB: 255, 188, 0
   ganColorRedOrangeYellowGreen30(12) = 54015    'RGB: 255, 210, 0
   ganColorRedOrangeYellowGreen30(13) = 59647    'RGB: 255, 232, 0
   ganColorRedOrangeYellowGreen30(14) = 65535    'RGB: 255, 244, 0
   ganColorRedOrangeYellowGreen30(15) = 65535    'RGB: 255, 255, 0
   ganColorRedOrangeYellowGreen30(16) = 1375480    'RGB: 248, 252, 20
   ganColorRedOrangeYellowGreen30(17) = 2685680    'RGB: 240, 250, 40
   ganColorRedOrangeYellowGreen30(18) = 4061417    'RGB: 233, 248, 61
   ganColorRedOrangeYellowGreen30(19) = 5371362    'RGB: 226, 246, 71
   ganColorRedOrangeYellowGreen30(20) = 5371362    'RGB: 226, 245, 81
   ganColorRedOrangeYellowGreen30(21) = 4841658    'RGB: 186, 224, 73
   ganColorRedOrangeYellowGreen30(22) = 4312210    'RGB: 146, 204, 65
   ganColorRedOrangeYellowGreen30(23) = 3782761    'RGB: 105, 184, 57
   ganColorRedOrangeYellowGreen30(24) = 3253057    'RGB: 65, 163, 49
   ganColorRedOrangeYellowGreen30(25) = 3253057    'RGB: 65, 150, 45
   ganColorRedOrangeYellowGreen30(26) = 2722362    'RGB: 58, 138, 41
   ganColorRedOrangeYellowGreen30(27) = 2191923    'RGB: 51, 114, 33
   ganColorRedOrangeYellowGreen30(28) = 1661484    'RGB: 44, 102, 28
   ganColorRedOrangeYellowGreen30(29) = 1130789    'RGB: 37, 84, 21
   ganColorRedOrangeYellowGreen30(30) = 1130789    'RGB: 37, 65, 17
End Sub 
'*************** Code End *******************************************************

Call from code behind report r_DIAL_Numberz

Uses a table with numbers (Numberz) to get values for this example

'*************** Code Start *****************************************************
' code behind report: r_DIAL_Numberz
' Report Draw Reference:
'  http://msaccessgurus.com/VBA/ReportDraw_Reference.htm
'-------------------------------------------------------------------------------
' Purpose  : draw colored dials
' Author   : crystal (strive4peace)
' Code List: www.msaccessgurus.com/code.htm
' This code: https://msaccessgurus.com/VBA/Draw_Dial.htm
'-------------------------------------------------------------------------------
' LICENSE
'   You may freely use and share this code, but not sell it.
'   Keep attribution. Use at your own risk.
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'           Detail_Format
'-------------------------------------------------------------------------------
Private Sub Detail_Format(Cancel As Integer _ 
      ,FormatCount As Integer) 
'draw dials
   
   'CALLS
   '  Draw_Dial_s4p
   
   Dim xCenter As Single _ 
      ,yCenter  As Single _ 
      ,sgRadius As Single _ 
      ,sControlname As String _ 
      ,iValue As Integer 
 
   xCenter = 1 * TWIPperINCH 
   yCenter = 1 * TWIPperINCH 
   sgRadius = 0.75 * TWIPperINCH 
   
   With Me 
      
      '----------- Draw_Dial_s4p for fraction
            
      Call Draw_Dial_s4p(Me,xCenter,yCenter,sgRadius _ 
         ,Me.Fractn.Value) 

   End With  'me
   
End Sub 
'*************** Code End *******************************************************

Call from code behind report r_DIAL_Numberz_BackColor_Ratio

Send optional parameters for BackColor and ratio of inner circle

'*************** Code Start *****************************************************
' code behind report: r_Circle_DIAL
' Report Draw Reference:
'  http://msaccessgurus.com/VBA/ReportDraw_Reference.htm
'-------------------------------------------------------------------------------
' Purpose  : draw colored dials
' Author   : crystal (strive4peace)
' Code List: www.msaccessgurus.com/code.htm
'-------------------------------------------------------------------------------
' LICENSE
'   You may freely use and share this code, but not sell it.
'   Keep attribution. Use at your own risk.
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'           Detail_Format
'-------------------------------------------------------------------------------
Private Sub Detail_Format(Cancel As Integer _ 
      ,FormatCount As Integer) 
'draw dials
   
   'CALLS
   '  Draw_Dial_s4p
   
   Dim xCenter As Single _ 
      ,yCenter  As Single _ 
      ,sgRadius As Single _ 
      ,sgRatio As Single _ 
      ,sControlname As String _ 
      ,iValue As Integer _ 
      ,nColorMiddle As Long 
 
   xCenter = 1 * TWIPperINCH 
   yCenter = 1 * TWIPperINCH 
   sgRadius = 0.75 * TWIPperINCH 
   sgRatio = 0.3 
   
   With Me 
      'set middle color to same as background
      nColorMiddle = .Detail.BackColor  'assume no Alternate BackColor
      
      '----------- Draw_Dial_s4p for fraction
            
      Call Draw_Dial_s4p(Me,xCenter,yCenter,sgRadius _ 
         ,.Fractn.Value,nColorMiddle,sgRatio) 

   End With  'me
   
End Sub 
'*************** Code End *******************************************************
Code was generated with colors using the free Color Code add-in for Access

Goto Top  

Reference

Drawing Reference on MsAccessGurus

Report Draw Reference for VBA syntax and help for drawing on Access reports.

Circle method

Line method

DrawWidth property

FillColor property

FillStyle property

ScaleMode property

Goto Top  

Backstory

Using graphics to indicate values makes differences easier to see ... a picture is worth a thousand words

Report Draw Reference and VBA Syntax VBA drawing code with links to more pages with code to draw on your Access reports. If you can imagine it, Access can do it!

If you find this page useful, help this site grow. Donations are much appreciated, large and small. Access is only limited by your imagination.

Share with others

Here's the link for this page in case you want to copy it and share it with someone:

https://msaccessgurus.com/VBA/Draw_Dial.htm

or in old browsers:
http://www.msaccessgurus.com/VBA/Draw_Dial.htm

Get Tutoring with Access and drawing

Let's connect and team-develop your application together. I teach you how to do it yourself. My goal is to empower you.

While we build something great together, I'll pull in code and features from my vast libraries as needed, cutting out lots of development time. And you'll get links to great resources.

Do you want your reports to be more creative and visual? I'd love to help you. Email me at training@msAccessGurus.com

~ crystal

the simplest way is best, but usually the hardest to see

Goto Top