|
VBA to draw shapes and write text on Access reports. Line, Circle, and Print methods can draw lines, rectangles, circles, elipses, arcs, points, and write text. Properties you should know to position, size, color, style, and scale. Functions for trigonometry and color.
Set the Default View for a report with drawings to Print Preview. VBA code to do drawings on Access reports runs in Print Preview, Print, and probably when using DoCmd.OutputTo or DoCmd.SendObject . It doesn't work in Report View or Layout View.
Objects are placed on top of each other, in the order they were drawn. If you want writing in a filled box, draw the box first, change desired property values, and then print the text. If you want text with a shadow, print the shadow text first, then offset CurrentX and CurrentY, change the ForeColor, and print the main text on top.
The canvas for drawing is the section that code is called from, or Report_Page to draw and write anywhere. If code is for a section, drawing is limited to that section only. ScaleLeft, ScaleTop, ScaleWidth, and ScaleHeight change depending on where the canvas is and how big it is. Therefore, if you call generic code to draw a shape or print text, realize that the coordinate system boundaries depend on where it can draw. This is analogous to using the same expression to calculate a subtotal in different group sections as well as the grand total in a report footer section.
Only the Report_Page event can address the whole page ... unless you do what some of the Help examples do and make the detail section really big! The size of a section is its size in design view. If a report is just for drawing, I like to use the Page event, which is the last drawing event to execute. Objects are placed on top of whatever else is there. Filled shapes can have transparent interiors.
To make a multiple page report with no real data that can drive page breaks:
Some events like Format and Print can happen multiple times. Page happens last.
In the following syntax examples, oReport represents a report object. Even if code applies to just a section, the main report object is still used to reference methods and properties.
By default, the unit of measure for positioning coordinates is twips (TWenty In a Point).
1 inch = 72 points 1 point = 20 twips 1 inch = 1440 twips
There are 566.9291338583 twips in a centimeter, or approximately 576 ... not such an easy number! You can change the scale to something else like centimeters if you can't get used to twips. Unit of measure is set by the ScaleMode property.
A "cartesian plane" is a flat surface with two dimensions. Points on the plane are referenced by their distance from two axes that are perpendicular to each other and intersect at (0,0), which is called the "origin".
The "x-axis" is horizontal.
The "y-axis" is vertical.
On a plane, a "cartesian coordinate", or XY coordinate, or simply coordinate, is an ordered pair of two numbers that specify the location of a particular point. A coordinate is often written as (x,y), where "x" is the positive or negative distance from the x-axis, and "y" is the positive or negative distance from the y-axis.
Use these methods in a section Format or Print event, or a report Page event (even though Help says different depending on which page you're reading). Help also mixes up results from drawing methods with controls -- a line drawn using Line isn't an object you can set properties for like a Line control is. Help needs help ~ and once I've figured out how to update it, I plan to!
Draw a line or rectangle.
A rectangle (box) has B or BF specified.
Sometimes the compiler will throw an error on the Line method, so you might just need to close things and come back. In my opinion, this is because the syntax is so odd. No intellisense for this method, and it also doesn't seem to work using a With reference.
DrawWidth determines width of line. DrawMode and DrawStyle affect how it is drawn. After drawing, CurrentX and CurrentY are set to the (x2, y2) end point.
If the color parameter isn't specified, ForeColor is used.
BF means the Box Fill color is the same as the specified color.
If B is used alone, the default interior is Transparent (1) (default) unless FillStyle is Opaque (0), or a pattern. The interior box color is FillColor, which means the inside color can be different than the line color.
When done, CurrentX and CurrentY are set to x2, y2.
No error occurs for drawing outside the viewable drawing area; that part of the drawing simply doesn't show.
Help: Report.Line method
oReport.Line (Step (x1, y1) - Step (x2, y2), Color, BF)
Draw circle, ellipse, or arc.
An ellipse has an Aspect <> 1.0. It isn't technically a "circle" since the distance to the circumference isn't equidistant from one center. (Likewise, a rectangle isn't a Line).
An arc has StartAngle and EndAngle specified, so it can be part of a circle.
DrawWidth determines width of line. DrawMode and DrawStyle affect how it is drawn. CurrentX and CurrentY are set to the (x,y) center point when done.
The circle will be filled using the FillColor if FillStyle isn't set to Transparent (1), which is the default.
Arcs are drawn in a counterclockwise (positive) direction. To specify that a radius line be drawn from the center to the StartAngle and/or EndAngle (such as pie slices), use a negative number to specify the respective angle. Angle, however will always be positive (the absolute value).
Therefore, a Negative sign is simply an indicator to draw the radius. If an angle really is 0 (zero), but you need it to be negative so a radius line will be drawn, specify a very small negative value such as -0.00000001 (or even smaller — I found that, even though the data type is single with no more than 9 sigfigs, a smaller negative number is less discernable if the drawing is big, and it still works).
When done, CurrentX and CurrentY are set to x, y for the center.
No error occurs for drawing outside the viewable drawing area; that part of the drawing simply doesn't show.
Help: Report.Circle method
oReport.Circle (Step (x,y), Radius, Color, StartAngle, EndAngle, Aspect)
*NOTE: In reality, for the Circle method, angles can't really be negative, since a negative sign is only an indicator to draw the radius line. Unlike Sin, Cos, and other trignometric functions than can resolve values greater than 2π (as well as true negative values), Circle cannot, and 2π radians is a limit. If you specify something it can't draw, it simply doesn't draw it. If you reference an area outside its canvas, it won't appear to draw anything. However, because you can reference the area outside the visible canvas, you can get some interesting effects and show partial shapes on the edges.
Draw a Point.
Size determined by DrawWidth (single pixel if =1). Style specified by DrawMode and DrawStyle. Similar to Circle in the sense that you get a circle, but point can't have a different outline and fill color, and instead of radius, DrawWidth determines size. CurrentX and CurrentY are set to the center of the point (x,y) when done.
Help: Report.PSet method
oReport.PSet (Flags, x, y, Color)
Print text.
Font is specified by FontName and FontSize. Color is ForeColor. Style is set by FontBold, FontItalic, and FontUnderline. Start position is CurrentX and CurrentY. Set these properties before Print.
Use the TextWidth and TextHeight methods to determine how big any string of text will be when printed with the current property settings. This is helpful to ensure that desired text will fit in the space you want it to go, and to center text, or right-align text.
When Print is done, a line break is appended if there is no ending semi-colon. In that case, CurrentX remains the same, and CurrentY is increased by TextHeight. If a semi-colon is specified at the end, CurrentX is set to point immediately after the last character printed and CurrentY remains the same. If a comma is specified at the end, CurrentX is the next point and CurrentY is increased by TextHeight.
If there is too much text for the area, it's truncated.
Help: Report.Print method
oReport.Print stringToPrint ; or ,
Define the coordinate system.
The coordinate system is reset to twips if the Scale method has no arguments
Help: Report.Scale method
oReport.Scale (Flags, x1, y1, x2, y2)
alternate (old?) syntax:
oReport.Scale (x1, y1)-(x2, y2)
Get the width of a string.
Single precision number returned in units specified by the ScaleMode property, and considering coordinate system defined by the Scale method
Font is specified by FontName and FontSize.
If there are carriage returns in the string, the horizontal width of the longest line is returned.
Possible uses include calculating where to set CurrentX to center text, changing FontSize to fit space, figuring out where to break lines to wrap text, and calculating where to draw a rectangle or circle around the text.
Help: Report.TextWidth method
oReport.TextWidth (stringExpression)
Get the height of a string.
Single precision number returned in units specified by the ScaleMode property, and considering coordinate system defined by the Scale method
Font is specified by FontName and FontSize.
If there are carriage returns in the string, the vertical cumulative height of the lines, including the leading space above and below each line, is returned.
Possible uses include calculating where to set CurrentY to vertically center text, changing FontSize to fit space, figuring out where to break lines to wrap text, and calculating where to draw a rectangle or circle around the text.
Help: Report.TextHeight method
oReport.TextHeight (stringExpression)
These are read/write properties even though explanations focus on setting values, not reading them. To store a property value in a variable:
myVariableName = oReport.PropertyName
Set the next horizontal starting position for drawing or printing. Single.
By default, the left edge is 0, and measurements are in TWIPs (TWenty In a Point). Values increase as you move to the right.
Usually used in conjunction with CurrentY for an XY coordinate. Use TextWidth if you need to calculate where to position for Print.
Set ScaleMode to change the unit of measure (default is twips).
Method | Before method (to position) | After method |
---|---|---|
Circle | The center (x,y) can be relative to current position using the Step keyword, or absolute. | Still the center of the object. |
PSet (Point) | The center (x,y) can be relative to current position using Flags, or absolute. | Still the center of the object. |
Line | Start point (x1, y1) can be relative to current value using the Step keyword, or absolute. | The end point of the line, (x2, y2) coordinate. |
The start print position. | The next print position. |
Help: Report.CurrentX property
oReport.CurrentX = SingleValue
Set the next vertical starting position for drawing. Single.
By default, the top edge is 0. Values increase as you move down.
Usually used with CurrentX for an XY coordinate.
Use TextHeight if you need to calculate where to position for Print.
Default unit of measure is twips. Set ScaleMode to change the unit of measure for coordinates.
See CurrentX for more information.
Help: Report.CurrentY property
oReport.CurrentY = SingleValue
Specify the unit of measurement for coordinates on a page. Integer
Applies to Circle, Line, Pset (Point), and Print methods, as well as CurrentX, CurrentY, and the Scale properties.
When creating a custom coordinate system, set ScaleTop, ScaleLeft, ScaleWidth, and/or ScaleHeight. Alternately, set coordinates for the the upper-left corner and bottom-right corner with the Scale method.
Help: Report.ScaleMode property
oReport.ScaleMode = IntegerValue
Setting | Description |
---|---|
0 | Custom coordinate system. Custom values used by one or more of the ScaleHeight, ScaleWidth, ScaleLeft, and ScaleTop properties |
1 | (Default) Twips |
2 | Points |
3 | Pixels |
4 | Characters (horizontal = 120 twips per unit; vertical = 240 twips per unit). |
5 | Inches |
6 | Millimeters |
7 | Centimeters |
Get the x-coordinate of the left edge of the drawing area
in units specified by ScaleMode. Single.
or
Set the desired value for the left horizontal edge
to make a custom coordinate system.
By default, the horizontal left position is 0.
When creating a custom coordinate system, set ScaleTop, ScaleLeft, ScaleWidth, and/or ScaleHeight. Alternately, set coordinates for the the upper-left corner and bottom-right corner with the Scale method.
Setting any scale property automatically sets ScaleMode to 0 (zero) to signify a custom coordinate system. Values of CurrentX and CurrentY are then automatically adjusted to be in the same actual place, but consider the new coordinate system.
Help: Report.ScaleLeft property
oReport.ScaleLeft = SingleValue
To set the origin to the middle of the page horizontally: oReport.ScaleLeft = - oReport.ScaleWidth /2
Get the y-coordinate of the top of the drawing area
in units specified by ScaleMode. Single.
or
Set the desired value for the top vertical position
to make a custom coordinate system.
By default, the top vertical position is 0.
When creating a custom coordinate system, set ScaleTop, ScaleLeft, ScaleWidth, and/or ScaleHeight. Alternately, set coordinates for the the upper-left corner and bottom-right corner with the Scale method.
Setting any scale property automatically sets ScaleMode to 0 (zero) to signify a custom coordinate system. Values of CurrentX and CurrentY are then automatically adjusted to be in the same actual place, but consider the new coordinate system.
Help: Report.ScaleTop property
oReport.ScaleTop = SingleValue
Get the horizontal distance from the left edge to the right edge of the drawing area
in units specified by ScaleMode,
which by default is twips. Single.
or
Set the desired value for how many units there are along the x-axis
to make a custom coordinate system.
Creating a custom coordinate system can make it easier to reference points on the page or section. For instance if you set ScaleWidth to 100, each horizontal unit will be 1/100th of the width.
For a custom coordinate system, set ScaleTop, ScaleLeft, ScaleWidth, and/or ScaleHeight. Alternately, set coordinates for the the upper-left corner and bottom-right corner with the Scale method.
Setting any scale property automatically sets ScaleMode to 0 (zero) to signify a custom coordinate system. Values of CurrentX and CurrentY are then adjusted to be in the same actual place, but consider the new coordinate system.
Help: Report.ScaleWidth property
oReport.ScaleWidth = SingleNumber
Get the vertical distance from the top
to bottom edges of the drawing area
in units specified by ScaleMode,
which is twips by default. Single.
or
Set the desired value for how many units there are along the y-axis
to make a custom coordinate system.
A custom coordinate system can make it easier to reference points. For instance if you set ScaleHeight to 100, each vertical unit will be 1/100th of the height. For a custom coordinate system, set ScaleWidth, ScaleHeight, ScaleLeft , and/or ScaleTop . Alternately, set coordinates for the the upper-left corner and bottom-right corner with the Scale method.
Setting any scale property automatically sets ScaleMode to 0 (zero) to signify a custom coordinate system. Values of CurrentX and CurrentY are then adjusted to be in the same actual place, but consider the new coordinate system.
Help: Report.ScaleHeight property
oReport.ScaleHeight = SingleNumber
Set the color for lines and text. Long.
Set ForeColor before Print to specify text color. ForeColor will be used for Line, Circle, and PSet (Point) if a color isn't specified.
After a shape is drawn specifying a color such as Line, the ForeColor property changes -- so be aware of this.
Help: Report.ForeColor property
Help not clear since it also talks about ForeColor of a control, which has nothing to do with drawing objects. Sometime I plan to update this page!
oReport.ForeColor = LongValue
Set interior color for filled shapes. Long.
Used to specify the inside color for closed shapes drawn with Line and Circle
Help: Report.FillColor property
oReport.FillColor = LongValue
Specify if the inside color for a shape is transparent, opaque, or filled with a pattern. Integer.
Default is Transparent.
Applies to boxes drawn with Line and closed shapes drawn with Circle.
Help: Report.FillStyle property
Help mixes up FillStyle for drawing objects with BackStyle for controls (which aren't relevent for drawing). There isn't a Line object to have a SpecialEffect either.
oReport.FillStyle = IntegerValue
Setting | Description |
---|---|
0 | Opaque |
1 | (Default) Transparent |
2 | Horizontal Line |
3 | Vertical Line |
4 | Upward Diagonal |
5 | Downward Diagonal |
6 | Cross |
7 | Diagonal Cross |
Specify how the pen color interacts with existing background. Integer.
Pen color is what is used for drawing Line, Circle, and PSet (point).
The colors you see on the screen may be different than what your printer is capable of.
Help: Report.DrawMode property
oReport.DrawMode = IntegerValue
Setting | Raster | Description |
---|---|---|
1 | Black pen color. | |
2 | NotMergePen | The inverse of setting 15, MergePen |
3 | MaskNotPen | The combination of the colors common to the background color and the inverse of the pen |
4 | NotCopyPen | The inverse of setting 13, CopyPen, specified by ForeColor |
5 | MaskPenNot | The combination of the colors common to both the pen and the inverse of the display |
6 | Invert | The inverse of the display color |
7 | XorPen | The combination of the colors in the pen and in the display color, but not in both |
8 | NotMaskPen | The inverse of setting 9 |
9 | MaskPen | The combination of the colors common to both the pen and the display |
10 | NotXorPen | The inverse of setting 7, XorPen |
11 | Nop | No operation; the output remains unchanged. In effect, this setting turns drawing off |
12 | MergeNotPen | The combination of the display color and the inverse of the pen color |
13 | CopyPen | (Default) The color specified by the ForeColor property |
14 | MergePenNot | The combination of the pen color and the inverse of the display color |
15 | MergePen | The combination of the pen color and the display color |
16 | White pen color. |
Width of line or size of point in pixels. Integer.
Applies to outside line for the Line and Circle methods, and size of point for the PSet method.
Default is 1 pixel. With this setting, DrawStyle and DrawMode work as expected. If DrawWidth > 3, DrawMode options get a solid line and DrawStyle isn't changed.
Help: Report.DrawWidth property
oReport.DrawWidth = IntegerValue
Set line style such as solid, dash, or dot. Control interior transparency. Integer.
Applies to Line and Circle methods.
If DrawWidth is > 3, DrawStyle will be a solid line ... but not always!
Help: Report.DrawStyle property
oReport.DrawStyle = IntegerValue
Setting | Description |
---|---|
0 | (Default) Solid line, transparent interior |
1 | Dash, transparent interior |
2 | Dot, transparent interior |
3 | Dash-dot, transparent interior |
4 | Dash-dot-dot, transparent interior |
5 | Invisible line, transparent interior |
6 | Invisible line, solid interior |
Specify the name of the font that text will use when printed. String.
Help: Report.FontName property
oReport.FontName = StringFontName
Set the point size for text that will be printed. Integer.
There are 72 points in an inch.
Help: Report.FontSize property
oReport.FontSize = IntegerValue
Set text to be bold or not. Boolean.
Help: Report.FontBold property
oReport.FontBold = BooleanValue
Set text to be italic or not. Boolean.
Help: Report.FontItalic property
oReport.FontItalic = BooleanValue
Set text to be underlined or not. Boolean.
Help: Report.FontUnderline property ?
oReport.FontUnderline = BooleanValue
Control if Top and Left for report sections will change. True (default) if Access should move down the page to print the next record, and across to print the next column. False to render at the same location as the previous record. Boolean.
This isn't a drawing property but is included to have a way to keep multiple records in the same drawing area.
If MoveLayout isn't true, Access won't change the print position for the next record. VBA can move controls wherever you want them in the drawing area for each record.
Duane Hookom sets MoveLayout to false on some of his calendar reports. In a Detail (or Group) event, the Top, Left, Width, Height, Color and more might be changed for controls in that section. Here are Duane's Hook'D on Access samples: http://www.access.hookom.net/Samples.htm
Help: Report.MoveLayout property
oReport.MoveLayout = BooleanValue
Return the RGB color value, which is also called the color number. Long.
Red, Green, and Blue are integers between 0 and 255 where 0 is none (black) and 255 is all (white).
Help: RGB function
RGB (Red, Green, Blue)
Return Long Integer representing the RGB color code given a specified color number from 0 to 15. Maybe QBColor is named for Quick Basic Color.
Help: QBColor function
QBColor (ColorNumber)
ColorNumber | Color |
---|---|
0 | Black |
1 | Blue |
2 | Green |
3 | Cyan |
4 | Red |
5 | Magenta |
6 | Yellow |
7 | White |
8 | Gray |
9 | Light Blue |
10 | Light Green |
11 | Light Cyan |
12 | Light Red |
13 | Light Magenta |
14 | Light Yellow |
15 | Bright White |
Return sine of an angle (radians) as a number between -1 and 1. Double.
Sine relates to Y-coordinate on a unit circle.
To convert degrees to radians, multiply degrees by π/180. π means Pi, which you can define as a constant
Const PI = 3.14159
watch Unit Circle video (37:06)
Help: Sin function
Sin (AngleRadians)
Return cosine of an angle (radians) as a number between -1 and 1. Double.
Cosine relates to X-coordinate on a unit circle.
To convert degrees to radians, multiply degrees by π/180. π means Pi, which you can define as a constant
Const PI = 3.14159
watch Unit Circle video (37:06)
Help: Cos function
Cos (AngleRadians)
Return the angle in radians whose tangent is a given number. Double.
Tangent is opposite (Y) / adjacent (X), or sine(angle)/cosine(angle). This is useful to get the angle of an X,Y coordinate.
To convert radians to degrees, multiply by 180/π where π is Pi, which you can define as a constant
Const PI = 3.14159
Help: Atn function
Atn (ValueDouble)
Short video about this web page, which continues to be updated as I draw and learn more.
YouTube: Report Draw Reference for Access (5:03) May 2023
Presentation for Access Pacific
YouTube: Drawing Shapes in an Access Report - Elements and Atoms (1:20:28) June 2022
ACCDB has information about the elements on the periodic chart for Chemistry. It's been updated from the presentation demo to add electron configuration and number of neutrons for each element (thanks, Paul). As per Adrian's request, there is a report that shows one atom per page. DrawAtom is a public procedure that can be called from any report.
There is also a form to edit the elements. There are reports to draw the Periodic Table of Elements, atoms, ... example reports showing circles, ellipses,and arcs ... and an Archimedean Spiral that prompts for the radius rate of change.
Latest ACCDB = 220615 (yymmdd)
File name | Description and Link |
---|---|
ReportDraw_Chemistry_s4p.zip | Zip file containing Access accdb file with
sample reports showing various things you can do
to draw reports in Access.
download ACCDB |
PeriodicTableElements.png | Image of the periodic table report
Periodic Table |
NutritionalElementsPeriodicTable.png | Image of the periodic table only showing nutritional elements
Nutritional Elements in the Periodic Table |
r_Circle_ELEMENT_ATOM.pdf | Report showing information about each element
and a drawing of its atom.
Element Atom Report |
r_Circle_ELEMENT_ATOM_OnePerPage.pdf | Report showing information about each element
and a drawing of its atom where each element is on one page.
Element Atom Report, one page per element |
f_ELEMENTS.png | form to edit the elements
Form to edit the Elements |
My first big plunge into drawing anything fancy with Access was using it to animate illustrations for a video tutorial (instead of a far more pratical tool) to teach trigonometry: Unit Circle video tutorial
Using those drawing concepts, I created the CalendarMaker report in Access. It uses the uses Report .Line and .Print methods to do all the drawing and writing, can scale one or many to a page, print holidays and whatever content you want on each day, in your language specified by Windows, starting whatever day of the week you want.
CalendarMaker video tutorial (49:05)
I also made a ticking analog clock using a form. YouTube video: Clock with Moving Hands + Sounds in Microsoft Access
Even after doing so much drawing with Access, I was still confused by some of the Help. Therefore, I decided to try everything (still testing some of the concepts) and rewrite it to be more clear. If you like this reference, or my chemistry database download, donate to help with costs and balance the time it takes to share, thank you.
here's the link for this page in case you want to copy it:
https://msaccessgurus.com/VBA/ReportDraw_Reference.htm
I love hearing about what you're doing with Access.
Let's connect and team-develop your application together. I teach you how to do it yourself. As needed, while we build something great together, I'll pull in code and features from my vast libraries, cutting out lots of development time.
Do you want your reports to be more creative and visual?
I'd love to help you.
Email me at training@msAccessGurus
I look forward to hearing from you ~ Donations are appreciated if you have funds to spare.
~ crystal
the simplest way is best, but usually the hardest to see