# L = N x C + 2R

```
Sub flat1(L As Double, C As Double)
'L = N x C + 2R
'L and C are the inputs
'Length and Centers

'N and R are the outputs
'N = Number of full spaces
'R = length of ends - Remainder

Dim N As Integer
Dim R As Double
Dim str As String
Dim i As Integer

If L / C < 1.25 Then
MsgBox " L / C < 1.25 "
Exit Sub
End If

N = Fix(L / C)
R = (L - N * C) / 2

If R < 0.25 * C Then
N = N - 1
R = (L - N * C) / 2
End If
'now N and R are derived

If hole_slot = "SLOT" Then
Call flat_slot(L, N, C, R)
End If

If hole_slot = "HOLE" Then
Call flat_hole(L, N, C, R)
End If

End Sub
```

# More Turtle Graphics

A basic class implementation for turtle graphics in autocad –

The basic idea of turtle graphics is that the pen has a location and a direction. The instruction to draw a line only needs distance. The ending point is the new current location. To translate distance at angle from a given point to coordinates the Sin and Cosine are used.

The public class variables are x1, y1 – the current location, the beginning of the line to be drawn, and x2, y2, the calculated end points. Heading is a private double. It is private so that the class can always keep the angle heading between 0 <= heading < 360 no matter how many cumulative turns. A boolean PEN variable allows a PENUP or PENDOWN state.

Turtle1.FD 6 draws a line 6 units (assuming PEN is DOWN). Turtle.Left 45 and Turtle.Right 45 turn heading to the left or right 45 degrees or any number. Input to the user is in degrees. The class module converts to radians in private.

some example code using the turtle class –

```Sub turtle_demo_A()

Dim turtle1 As CTurtle
Set turtle1 = New CTurtle

Debug.Print turtle1.x1
Debug.Print turtle1.y1
Debug.Print turtle1.pen
'x1 and y1 are zero
'pen is true
'these are class defaults

'class_initialize default is 90

'property Let heading (double)
'seems like an argument but you call LET with assignment
'property let heading sets and controls value between 0 <= pheading < 360

'just like A = A + 3
'right side of equation is GET and left side is LET

turtle1.left 90

turtle1.right 90

turtle1.fd 12
'line is 45 to left

End Sub
```

all this boils down to –

```
Sub turtle_demo_B()

Dim turtle1 As CTurtle
Set turtle1 = New CTurtle

turtle1.x1 = 2
turtle1.y1 = 3

turtle1.fd 12
End Sub
```

The Class Module code for the turtle to draw a line contains the trigonometry to calculate the point at dist and angle. It draws the line using the familiar AddLine method with EndPoints as an array of 3 doubles, xyz. This is a 2D implementation, Z is always zero for now but does not have to be.

```Public Sub fd(dist As Double)
'assumes x1 y1 and heading
x2 = x1 + dist * Cos(ang2rad(pheading))
y2 = y1 + dist * Sin(ang2rad(pheading))

If pen Then
Call drawline(x1, y1, x2, y2)
End If

'updates to new position
x1 = x2
y1 = y2
End Sub

Sub drawline(x1 As Double, y1 As Double, x2 As Double, y2 As Double)
'internal sub to draw line
Dim pt1(0 To 2) As Double
Dim pt2(0 To 2) As Double
pt1(0) = x1: pt1(1) = y1: pt1(2) = 0
pt2(0) = x2: pt2(1) = y2: pt2(2) = 0

Update
End Sub
```

Drawing the same line in code with no class implementation –

```Sub turtle_demo_C()

Dim pt1(0 To 2) As Double
Dim pt2(0 To 2) As Double

Dim x1 As Double, y1 As Double
Dim x2 As Double, y2 As Double

Dim ang As Double
Dim dist As Double

x1 = 2
y1 = 3
ang = 45
dist = 12

x2 = x1 + dist * Cos(ang2rad(ang))
y2 = y1 + dist * Sin(ang2rad(ang))

pt1(0) = x1: pt1(1) = y1: pt1(2) = 0
pt2(0) = x2: pt2(1) = y2: pt2(2) = 0

End Sub
```

Instead of doing the calculations, Autocad provides the Utility PolarPoint to do the trig. Polarpoint returns an array. Autodesk help uses a Variant to capture it, but a dynamic array works fine (see pt2).

```Sub turtle_demo_D()

Dim pt1(0 To 2) As Double
Dim pt2() As Double

Dim x1 As Double, y1 As Double

Dim ang As Double
Dim dist As Double

x1 = 0
y1 = 0
ang = 45
dist = 12

'these are commented out
'x2 = x1 + dist * Cos(ang2rad(ang))
'y2 = y1 + dist * Sin(ang2rad(ang))

pt1(0) = x1: pt1(1) = y1: pt1(2) = 0

End Sub
```

We can further simplify this process with a function to populate point arrays. Every Point can be declared as a dynamic array.

```Function Pt(x As Double, y As Double, z As Double) As Double()
Dim pnt(0 To 2) As Double
pnt(0) = x: pnt(1) = y: pnt(2) = z
Pt = pnt
End Function

Sub turtle_demo_E()

Dim pt1() As Double
Dim pt2() As Double

Dim ang As Double
Dim dist As Double

ang = 45
dist = 12

pt1 = Pt(2, 3, 0)

End Sub
```

we can streamline a little bit more with a dedicated Line sub-routine. now lets compare the turtle and more conventional autocad methods. Each will draw a line and turn before drawing the next. Using dynamic arrays, what was pt2 can become pt1 with a simple assignment. That is not possible with the conventional static array where points are declared as – Dim PT1 (0 to 2) as Double.

```Sub turtle_demo_F()

Dim turtle1 As CTurtle
Set turtle1 = New CTurtle

turtle1.x1 = 1
turtle1.y1 = 2

turtle1.fd 12
turtle1.left 30
turtle1.fd 12

Dim pt1() As Double
Dim pt2() As Double

Dim ang As Double
Dim dist As Double

ang = 45
dist = 12

pt1 = Pt(1, 2, 0)
line1 pt1, pt2

pt1 = pt2
pt2 = acadDoc.Utility.PolarPoint(pt1, ang2rad(ang + 30), dist)
line1 pt1, pt2

End Sub
```

Turtle graphics has geometry implications, start here, go forward, turn and repeat. Turtle graphics is local with a simple interface and limited command set. Coordinate graphics is a global grid, but its interface can also be simplified. The two approaches might be able to work together.

A random star generator –

```Sub turtle_demo_6()
init_turtle
Dim dblsize As Double
Dim inc As Integer

For inc = 1 To 480

dblsize = rnddbl(0, 360)

dblsize = rnddbl(0, 1024)
turtle1.x1 = dblsize

dblsize = rnddbl(512, 1024)
turtle1.y1 = dblsize

dblsize = rnddbl(2, 17)
star_5 dblsize

Next inc

End Sub

Sub star_5(dblsize As Double)

For i = 1 To 5
turtle1.fd dblsize
turtle1.right 144
Next i

End Sub

Function rnddbl(upr As Double, lwr As Double) As Double
' Randomize
' better results without Randomize

rnddbl = CDbl((upr - lwr + 1) * Rnd + lwr)
End Function

```

any comment in the code causes wordpress to substitute the html equivalent, even the code tag vb with quotations gets corrupted. use wordpress code tag and it moves by itself above an empty line. I really struggle sometimes with wordpress and its code behavior. The only way i even get it to work is to load the old editor. There is an easier way to edit posts, they helpfully remind me. I tried that a few times.

# Excel VBA – > Autocad Basics

To begin writing your Autocad VBA code in excel – start excel. Most of the time you have to add the developer tab to the ribbon. That is done with the File tab, Options, Customize Ribbon. Add the Developer tab. Start the Visual Basic editor. When you save an excel file with visual basic code, save it with XLSM file extension. In the visual basic editor, important first step, you must add a reference for excel to see autocad programming objects. This is under Tools, References. Look for Autocad Type Library. Move it up in the list as high as it will go.

now you need a standard module to connect to autocad. insert a module, add two public variables at the top.

```Public acadApp As AcadApplication Public acadDoc As AcadDocument```

start your sub procedure by typing
and hit return

generally you will want to start autocad yourself the way you always do. if autocad is running the vba code to obtain a reference to it is

`Set acadApp = GetObject(, "AutoCAD.Application")`

notice we use our global variable. type this in to your sub procedure. I find this works fine but most online help shows it with a version dependent string like this.

`Set acadApp = GetObject(, "AutoCAD.Application.22")`
22 is the version that autocad is using to designate version 2018

to demystify this, what is GetObject, why is there a comma, where does this come from, open up the Object Browser. you can double click the word GetObject, right click, and pick Definition. if you dont find it that way, search the VBA library, top box, for GetObject –

The Object Browser shows its parent, VBA.Interaction and it shows the parameter list PathName comma Class. Right click on GetObject in the Object Browser and click Help to open MS online help.

If Autocad is not running, GetObject will return an error. The code to start autocad in VBA is CreateObject or New AcadApplication. They both work for me, just as the version independent and dependent string both seem to work equally well.

We need to handle the error, then deal with either autocad running or not. Autodesk has the logic and a file to do it here.

edit february 2020 – autodesk vba help links are broken here and in google search, try this.

https://help.autodesk.com/view/OARX/2019/ENU/?guid=GUID-73EC319D-9D7D-43FF-91B7-78CF36284028

if that is broke, the page is labeled
About Converting the VBA Code to VB (VBA/ActiveX)

this file is also in the Autodesk AutoCAD 2018: ActiveX Developer’s Guide, or whatever year you have, which is file acad_aag.chm somewhere in your autocad installation. find that and also acadauto.chm and copy them where you want them.

First we have to add the essential statement
otherwise we will not see any autocad.

Autodesk has the commands and logic but not the best form. We have to make some improvements. The code to start autocad needs to be in its own sub procedure with the code to reference the active drawing. We want to call connect_acad once and we want to obtain a global variable for the active drawing.

When autocad opens, it probably opens to a blank drawing, or maybe its already open to a drawing, but we have to get that drawing into a VBA object. Generally I want it to be a blank drawing because I am going to use it. The connect_acad sub procedure will not run until we want it to, so it just gets the activedocument which is a property of AcadApplication. Those are our two global variables, the application and the active drawing, and active drawing is the main one we use.

Put connect_acad in your module as a stand-alone. Anytime you want to write a program in excel vba to draw or interact with autocad, the first thing in the program is

at that point you have a global variable AcadDoc that you use for all of autocad’s vba objects.

here is the full acad_connect

```Option Explicit

On Error Resume Next

'both statements above behave without any discernible difference

If Err Then
Debug.Print "ERROR " & Err.Number
Debug.Print Err.Description

Err.Clear

'both statements above behave without any discernible difference

'essential statement

If Err Then
MsgBox Err.Description
Exit Sub
End If
End If

Debug.Print "Now running " + acadApp.Name + " version " + acadApp.Version

If acadDoc Is Nothing Then
End If

If acadDoc.ActiveSpace = 0 Then
End If

End Sub
```

in bricscad, try these (i dont have bricscad loaded currently but these worked a couple releases back)

`Set acadApp = GetObject(, "BricscadApp.AcadApplication")`

``` ```

```Set acadApp = New AcadApplication ```

using autodesk’s example to draw a single line would be modified like this. I made no other changes except adding Connect_Acad and changing Thisdrawing to AcadDoc.

`Sub testline()`

``` Call Connect_Acad Dim lineObj As AcadLine Dim startPoint(0 To 2) As Double Dim endPoint(0 To 2) As Double startPoint(0) = 1 startPoint(1) = 1 startPoint(2) = 0 endPoint(0) = 5 endPoint(1) = 5 endPoint(2) = 0 Set lineObj = acadDoc.ModelSpace.AddLine(startPoint, endPoint) ZoomAll ```

`End Sub`

Using this method, any code on autodesk help website that uses Thisdrawing.object can be run from excel by adding connect_acad at the top and replacing the word Thisdrawing with AcadDoc.