Autocad VBA Parametrics – 2 – Polyline Method

The autocad lightweightpolyline is the method of choice for drawing parametric plane figures if it is an option. But assembling an array of 30 or so points can be tedious. Here is a sub i wrote several months ago, and to be honest, it is a complete mystery now. the only way i can work on it is to plot it out and start listing points. So i am going to generalize the method and come up with an easier standard procedure for drawing parametric polyline objects.


Sub orig_OS_skin(A As Double, B As Double)
    Dim objent As AcadLWPolyline
    Dim pt(1 To 36) As Double
    
    pt(1) = 0.21875: pt(2) = A + 0.5 - 1
    pt(3) = 0.21875: pt(4) = A + 0.5
    pt(5) = 0: pt(6) = A + 0.5
    pt(7) = 0: pt(8) = 0
    pt(9) = B + 0.5 - 1.25: pt(10) = 0
    pt(11) = B + 0.5 - 1.0625: pt(12) = 0.1875
    pt(13) = B + 0.5: pt(14) = 0.1875
    pt(15) = B + 0.5: pt(16) = 0.40625
    pt(17) = B + 0.5 - 0.875: pt(18) = 0.40625
    pt(19) = B + 0.5 - 0.875: pt(20) = 0.34375
    pt(21) = B + 0.5 - 0.0625: pt(22) = 0.34375
    pt(23) = B + 0.5 - 0.0625: pt(24) = 0.25
    pt(25) = B + 0.5 - 1.08839: pt(26) = 0.25
    pt(27) = B + 0.5 - 1.27589: pt(28) = 0.0625
    pt(29) = 0.0625: pt(30) = 0.0625
    pt(31) = 0.0625: pt(32) = A + 0.5 - 0.0625
    pt(33) = 0.15625: pt(34) = A + 0.5 - 0.0625
    pt(35) = 0.15625: pt(36) = A + 0.5 - 1
    Set objent = acadDoc.ModelSpace.AddLightWeightPolyline(pt)
    objent.Closed = True
    objent.Update
       
    Set objpersistent = objent
End Sub

the first task is to draw a single polyline object. You cannot automate an object if you cannot draw it. if you have drawn it 100 times you will do a better job automating it than if you have barely drawn it. Just like plotting a curve, place it as conveniently as possible at 0,0. Visualize it sitting on the xy axis. Keep your parametric variables as convenient as possible. Start listing points by moving in the direction of the positive X axis. sweep around the screen in a counterclockwise direction as a standard procedure. Locate the first point at 0,0 if possible. The second point should be to the right. Use excel to list just the X values. it is simpler to separate the listings of X and Y values and measure or calculate them separately. Work in the parametric calculations as you go. Make dimensions and measurements on the drawing as needed. After you have gone all around the object listing the X values, do the same thing for Y. This is the key step.

2016-09-18_1

The program listing above that dimensions an array (1 to 36) for 18 points then loads a value into each index location is the brute force normal straightforward approach. We can instead create a polyline wrapper program. The array function only requires the data to be separated by commas. the Polyline method will not use that array directly, but we can create a transfer method in the wrapper. the wrapper will also measure the length of the array. Create a new sub and paste the values just entered into the spreadsheet into the sub.

Sub new_poly_draw(A As Double, B As Double)
Dim pt As Variant
pt = array(

Paste here

Call draw_array(pt)
End Sub
Sub new_poly_draw(A As Double, B As Double)
Dim pt As Variant
pt = array(

0   0
B-1.25  0
B-1.0625    0.1875
B 0.1875
B 0.40625
B-.875  0.40625
B-.875  0.34375
B-.0625 0.34375
B-.0625 0.25
B-1.0884    0.25
B-1.2759    0.0625
0.0625  0.0625
0.0625  A-.0625
0.15625 A-.0625
0.15625 A-1
0.21875 A-1
0.21875 A
0   A

Call draw_array(pt)
End Sub

now put commas between values and put your line continuations wherever you want.

Sub new_poly_draw(A As Double, B As Double)
Dim pt As Variant
        
pt = Array(0, 0, B - 1.25, 0, B - 1.0625, 0.1875, _
B, 0.1875, B, 0.40625, B - 0.875, 0.40625, B - 0.875, 0.34375, _
B - 0.0625, 0.34375, B - 0.0625, 0.25, B - 1.0884, 0.25, B - 1.2759, 0.0625, _
0.0625, 0.0625, 0.0625, A - 0.0625, 0.15625, A - 0.0625, 0.15625, A - 1, _
0.21875, A - 1, 0.21875, A, 0, A)
 
 Call draw_array(pt)
End Sub

and you are done, because you have this wrapper to run it

Sub draw_array(pt As Variant)
     Dim pt2() As Double
     Dim objent As AcadLWPolyline
     Dim i As Integer
     Dim lower As Integer, upper As Integer
     lower = LBound(pt)
     upper = UBound(pt)
     
     ReDim pt2(lower To upper)
     For i = lower To upper
     pt2(i) = pt(i)
     Next i
    
     Set objent = acadDoc.ModelSpace.AddLightWeightPolyline(pt2)
         objent.Closed = True
         objent.Update

Set objpersistent = objent

End Sub

objpersistent is a public variable that allows you to move this piece into position in the calling program.

Autocad VBA Parametrics – 1 – Wrapper functions

Sometimes it takes a long time to make something simple. Creating wrapper subroutines makes large parametric programs cleaner and easier to read, allowing them to get larger and more useful. If you straightforwardly code each routine containing all the details it uses, you soon reach a point where the program is too complex looking to modify. Wrapper routines delegate the details of the drawing and make the flow of the calling programs easier to follow.

The ADDLINE method in Autocad VBA requires an array of 3 doubles for each endpoint of the line.

Dim lineobj as AcadLine
Dim pt1(0 To 2) As Double
Dim pt2(0 To 2) As Double
pt1(0) = 2: pt1(1) = 3: pt1(2) = 0
pt2(0) = 40: pt2(1) = 50: pt2(2) = 0
Set lineobj = acadDoc.ModelSpace.AddLine(pt1, pt2)

By contrast the same thing can be done in autolisp with one line of code.

(command “line” (list 2 3) (list 4 5) “”)

Autocad VBA does not allow any shortcuts. Every line drawn has to use a dimensioned named assigned array of 3 doubles.

An Autocad VBA parametric drawing program would quickly require too many points to be practical. Wrapper functions are the solution. I am using the term in an informal way to indicate wrapping a VBA Autocad method to make it easier to use. Here is a simple line wrapper and how it is called.

call line(2, 3, 40, 50)

 Sub line(x1 As Double, y1 As Double, x2 As Double, y2 As Double)
Dim lineobj As AcadLine
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
Set lineobj = acadDoc.ModelSpace.AddLine(pt1, pt2)
End Sub

Every Autocad VBA object is a candidate for one or more wrappers. The point command in autocad is not used very often in design (its very useful in the graphing calculator), but it could be easily simplified.
Call draw_point(1,3,0)

Sub draw_point(x1 As Double, y1 As Double, z1 As Double)
Dim pointobj As AcadPoint
Dim pt1(0 To 2) As Double
pt1(0) = x1: pt1(1) = y1: pt1(2) = z1
Set pointobj = acadDoc.ModelSpace.AddPoint(pt1)
End Sub

An array of 3 doubles is Autocad VBA’s normal way of specifying a point location used by dozens of different objects. We can make a wrapper to aid making this array. When passing arrays as arguments to a subroutine they are always passed by reference – any changes made to the array in the called program are reflected in the calling program. Unfortunately we cannot get the wrapper to dimension the array for us, but we can simplify the values assignment a little. It does help when a lot of points are being set up.

Dim pt2(0 to 2) as Double
Call initpt(pt2, 2, 4, 0)

Sub initpt(ByRef ptn() As Double, val1 As Double, val2 As Double, val3 As Double)
ptn(0) = val1: ptn(1) = val2: ptn(2) = val3
End Sub

The ADDLIGHTWEIGHTPOLYLINE method requires a single array of doubles, one value for each x and y. A line with two points would require an array with 4 values.

Dim plineobj As AcadLWPolyline
Dim pt(1 To 4) As Double
pt(1) = 2: pt(2) = 3: pt(3) = 40: pt(4) = 50
Set plineobj = acadDoc.ModelSpace.AddLightWeightPolyline(pt)

The LightWeightPolyline method can be wrapped in a box routine. Box is drawn from lower left counterclockwise. The last segment is made with the closed property. In this case a layer is specified. It could be left out of the routine or made optional.
Call mbox(0, 0, L, W, “Hidden”)

Sub mbox(x1 As Double, y1 As Double, x2 As Double, y2 As Double, strlayer As String)
    Dim objent As AcadLWPolyline
    Dim pt(1 To 8) As Double
    pt(1) = x1: pt(2) = y1
    pt(3) = x2: pt(4) = y1
    pt(5) = x2: pt(6) = y2
    pt(7) = x1: pt(8) = y2
    Set objent = acadDoc.ModelSpace.AddLightWeightPolyline(pt)
    objent.Closed = True
    objent.layer = strlayer
End Sub

Rectangular boxes show up a lot in any design. Any plane figure with a known number of vertexes could be hard coded as above. If you have a parametric application that often uses a notched rectangle you would use a polyline wrapper expecting 6 points. Here is how the hardcoded 6 point polyline sub is coded. You can see the 12 inputs are starting to get tedious. This 6 pointed figure has 12 inputs and the 4 pointed figure above has 4 inputs because this figure does not have to have rectangular angles, it simply draws 6 points. the box above is assumed to be square with the coordinate system.

Sub test_p6()
Call connect_acad
Dim L As Double, W As Double, A As Double, B As Double
L = 72
W = 24
A = 12
B = 18
Call p6_box(0, 0, L - B, 0, L - B, A, L, A, L, W, 0, W)
End Sub

Sub p6_box(p1 As Double, p2 As Double, p3 As Double, p4 As Double, p5 As Double, p6 As Double, _
p7 As Double, p8 As Double, p9 As Double, p10 As Double, p11 As Double, p12 As Double)

    Dim objent As AcadLWPolyline
    Dim pt(1 To 12) As Double
    pt(1) = p1: pt(2) = p2
    pt(3) = p3: pt(4) = p4
    pt(5) = p5: pt(6) = p6
    pt(7) = p7: pt(8) = p8
    pt(9) = p9: pt(10) = p10
    pt(11) = p11: pt(12) = p12
    Set objent = acadDoc.ModelSpace.AddLightWeightPolyline(pt)
    objent.Closed = True
End Sub

The straightforward method to draw complex polyline figures would initially be coded all in one sub. The array would be dimensioned then loaded with values and immediately be given to the AddPoly method. This is a closed figure with 16 points.

 Dim objent As AcadLWPolyline
    Dim pt(1 To 32) As Double
    pt(1) = 1: pt(2) = 0.21875
    pt(3) = 0: pt(4) = 0.21875
    pt(5) = 0: pt(6) = 0
    pt(7) = W - 1.25: pt(8) = 0
    pt(9) = W - 1.0625: pt(10) = 0.1875
    pt(11) = W: pt(12) = 0.1875
    pt(13) = W: pt(14) = 0.40625
    pt(15) = W - 0.875: pt(16) = 0.40625
    pt(17) = W - 0.875: pt(18) = 0.34375
    pt(19) = W - 0.0625: pt(20) = 0.34375
    pt(21) = W - 0.0625: pt(22) = 0.25
    pt(23) = W - 1.08839: pt(24) = 0.25
    pt(25) = W - 1.27589: pt(26) = 0.0625
    pt(27) = 0.0625: pt(28) = 0.0625
    pt(29) = 0.0625: pt(30) = 0.15625
    pt(31) = 1: pt(32) = 0.15625
    Set objent = acadDoc.ModelSpace.AddLightWeightPolyline(pt)
    objent.Closed = True

A general method can be devised using a generic wrapper that tests the length of the array passed. However the poly method only accepts an array of doubles, and there is no way to conveniently construct an array of doubles except by declaring the index numbers of each value as above. The array function is easier to construct, but it only works with a variant declared. That is what we will use to construct the point list, then convert it in the wrapper, which can accept an array of any size.

Sub test_draw_array()
    Call connect_acad
    Dim W As Double
    W = 24
    Dim pt As Variant
    pt = Array(1, 0.21875, 0, 0.21875, _
                0, 0, W - 1.25, 0, _
                W - 1.0625, 0.1875, W, 0.1875, _
                W, 0.40625, W - 0.875, 0.40625, _
                W - 0.875, 0.34375, W - 0.0625, 0.34375, _
                W - 0.0625, 0.25, W - 1.08839, 0.25, _
                W - 1.27589, 0.0625, 0.0625, 0.0625, _
                0.0625, 0.15625, 1, 0.15625)
    Call draw_array(pt)
End Sub

Sub draw_array(pt As Variant)
     Dim pt2() As Double
     Dim objent As AcadLWPolyline
     Dim i As Integer
     Dim lower As Integer, upper As Integer
     lower = LBound(pt)
     upper = UBound(pt)
     
     ReDim pt2(lower To upper)
     For i = lower To upper
     pt2(i) = pt(i)
     Next i
    
     Set objent = acadDoc.ModelSpace.AddLightWeightPolyline(pt2)
         objent.Closed = True
         objent.Update
End Sub

Autocad Graphing Calculator

Autocad has Euclidean roots. Its a classic geometry tool. And it has VBA. It is not necessary to download and install the VBA module to have full access to VBA through Excel.

this blog online 1 year with 100 pages, approx, More to come.

i apologize for the old posts with messed up links and code mangling. wordpress changed their editor last year and between them and me changing the theme, we messed up a few pages that were ok when first published. i just noticed some new broken links.

2016-09-05_1

Lissajous curves gone wrong. I unchecked the convert to Radians button in the Parametric form before graphing, so that Sin(360) is interpreted by VBA not as Sin(2 pi) but Sin(360) or in radians Sin(57 * 2 pi) approx, but more importantly the step increment between points instead of being 1 degree is 1 radian or 57 degrees.

2016-09-05_2

the Cochleoid

the Cochleoid is a polar spiral that spirals in on itself, because Sin A varies between -1 and 1, but A gets ever larger.

2016-08-29_1

at point 8 A is 210, not 30, but because the Sin is negative, R is negative. The graph passes thru 0,0 every time the sin is zero.

2016-08-29_2

running the graph from negative 1080 (-6 pi) to -1 (to avoid divide by zero error) draws the mirror image graph from the inside out.

2016-08-29_3

2016-08-29_4

wolfram reference
http://mathworld.wolfram.com/Cochleoid.html

Acad TableStyle full method

2016-08-28_1

Acad Tablestyle can be programmed efficiently without duplicating code using a global variable for the Tablestyle object. While it is tempting to re-create the Autocad Tablestyle dialog in a VBA form, it would be difficult to improve on it and it would be a lot of work. The following program is a more or less full implementation of the tablestyle creation in code. Doubtless there could be some improvement of the variable listings, making them easier to create a list of standard tablestyles. This will do for a template in how tablestyles are made. an input form could interface with this style easily.


Option Explicit

Public TS As AcadTableStyle

'tablestyle creation all in code, no form input
'based on the autocad tablestyle dialog
'sub calls are closely related to the tabs General, Text and Borders
'each sub is called 3 times with rowtype, just like the dialog
'purpose would be to create a favorite std style with all variables in code
'but form input would go thru this format also
'to create a 2nd style copy this header sub and modify values

Sub make_table_style_std()
    Call connect_acad
    Call set_text_style 'for now so we have textstyle selection
    Dim col As AcadAcCmColor
    Set col = AcadApplication.GetInterfaceObject("AutoCAD.AcCmColor.20")
    Dim rowtypes As Long
    Dim tablestylename As String
    
     'set up vars for general tab
    Dim blncolor As Boolean
    Dim alignment As Integer
    Dim marginhoriz As Double, marginvert As Double
    Dim blnmerge As Boolean
    
     'set up vars for text tab
    Dim textstyle As String
    Dim textheight As Double
    
     'set up vars for borders tab
    Dim lineweight As Integer
    
    tablestylename = "Tb_Style1"
'first call that creates or sets the tablestyle
Call table_style_std(tablestylename)

'***************************
 'set up vars for general tab
        
    Call col.SetRGB(0, 0, 0)
    blncolor = False
    alignment = 5 'centered
    marginhoriz = 0.06
    marginvert = 0.06
    blnmerge = False

'call ts_general 3 times once for each row type, chg vars as needed
Call ts_General(acTitleRow, blncolor, col, alignment, marginhoriz, marginvert)

Call ts_General(acHeaderRow, blncolor, col, alignment, marginhoriz, marginvert)
alignment = 6 'right

Call ts_General(acDataRow, blncolor, col, alignment, marginhoriz, marginvert)

Call ts_merge

 '************************
 'set up vars for text tab
    textstyle = "Tahoma"
    textheight = 0.1875
    Call col.SetRGB(0, 0, 0)
     
'call ts_text 3 times once for each row type, chg vars as needed
Call ts_Text(acTitleRow, textstyle, textheight, col)
    textheight = 0.125

Call ts_Text(acHeaderRow, textstyle, textheight, col)
    textheight = 0.09375

Call ts_Text(acDataRow, textstyle, textheight, col)

 '**************************
 'set up vars for borders tab
    lineweight = 40
    Call col.SetRGB(0, 0, 255)
    
 'call ts_border 3 times once for each row type, chg vars as needed
Call ts_Borders(acTitleRow, lineweight, col)

Call ts_Borders(acHeaderRow, lineweight, col)
    lineweight = 30

Call ts_Borders(acDataRow, lineweight, col)
End Sub

'***********

Sub table_style_std(stylname As String)
'main entry called first
    Dim dictionaries As AcadDictionaries
    Dim dictObj As AcadDictionary
    Set dictionaries = acadDoc.Database.dictionaries
    Set dictObj = dictionaries.Item("acad_tablestyle")

    Set TS = dictObj.AddObject(stylname, "AcDbTableStyle")
    TS.Name = stylname
    TS.Description = TS.Name & " TableStyle"
    
   acadDoc.SetVariable ("ctablestyle"), stylname
End Sub

Sub ts_General(rowtypes As Long, blncolor As Boolean, fillcolor As AcadAcCmColor, alignment As Integer, _
               marginhoriz As Double, marginvert As Double)
'skipping format option and type
'merge is handled in its own sub

'seems to be a problem with autodesk help reference
'setbackgroundcolornone true is the only valid input
'that option sets backgroundcolor to none as desired
'which is contrary to activex help

If blncolor Then
TS.SetBackgroundColor rowtypes, fillcolor
Else
TS.SetBackgroundColorNone rowtypes, True
End If

TS.SetAlignment rowtypes, alignment
TS.HorzCellMargin = marginhoriz
TS.VertCellMargin = marginvert

End Sub


Sub ts_merge()
'the enablemergeall statement is functional in styles
'titlesuppressed and headersuppressed are not functional in tablestyle
'although they are documented and do not cause an error - they dont do anything
'whether a created table has a title and header is dictated by table method
    TS.EnableMergeAll "Title", True
    TS.EnableMergeAll "Header", False
    TS.EnableMergeAll "Data", False
'the activex help on enablemergeall seems to indicate 2 integer arguments and a boolean
'whilst the program code example is per above, one string row description and boolean
'which is why i put it in its own sub for clarity
End Sub


Sub ts_Text(rowtypes As Long, textstyle As String, textheight As Double, col As AcadAcCmColor)
 'acDatarow=1 acHeaderrow=4 acTitlerow=2
 TS.SetTextStyle rowtypes, textstyle
 TS.SetTextHeight rowtypes, textheight
 TS.SetColor rowtypes, col
 
'get functtions are similar
 Debug.Print TS.GetTextStyle(rowtypes)
 Debug.Print TS.GetTextHeight(rowtypes)
 Set col = TS.GetColor(rowtypes)
 Debug.Print col.ColorIndex
 Debug.Print col.ColorMethod
 Debug.Print col.ColorName
End Sub


Sub ts_Borders(rowtypes As Long, lineweight As Integer, col As AcadAcCmColor)
   'to set all rowtypes at once use 7 (1+2+4)
   '63 sets all gridlinetypes eg outside inside etc 1, 2, 4, 8, 16, 32
   'somehow you can set the grid linetype eg dashed but i dont see a method
   
   TS.SetGridColor 63, rowtypes, col
   TS.SetGridLineWeight 63, rowtypes, lineweight
   TS.SetGridVisibility 63, rowtypes, True
End Sub

Autocad VBA Font Tables

Tablestyles can be added and programmed without duplicating code by using a global variable for the AcadTableStyle object. This is a flexible method for getting a handle on them.

but first – make font tables in autocad – run a loop from 0 to 255 to advance the Chr(#), change the textstyle of the table style to instantly change the table.

Sub test_array_to_acadtable3()

'0 to 255 ascii table
'font style is set in the table style
'send the array to the maketable routine

Call connect_acad
Dim rows As Integer, i As Integer
Dim columns As Integer, j As Integer

rows = 16
columns = 16

Dim ar_mult() As String
ReDim ar_mult(1 To rows, 1 To columns)

For i = 1 To rows
For j = 1 To columns
ar_mult(i, j) = Chr((i - 1) * 16 + (j - 1))
Next j
Next i

Call makethetable3(ar_mult)
End Sub

2016-08-07_3

2016-08-07_2

2016-08-07_4

2016-08-07_1

2016-08-07_5

2016-08-07_6

VBA Arrays and Autocad Tables

Here is the basic routine for making an autocad table from an array in its simplest form from a one-based array, and a generalized form that creates a table from any two-dimensional array.


Sub test_array_to_acadtable1()
'test to make a one-based two dimensional array of numbers
'and send the array to the maketable routines

Call connect_acad
Dim rows As Integer, i As Integer
Dim columns As Integer, j As Integer
'change these to anything you like
rows = 14
columns = 16

Dim ar_mult() As Integer
ReDim ar_mult(1 To rows, 1 To columns)

For i = 1 To rows
For j = 1 To columns
ar_mult(i, j) = i * j
Next j
Next i

'makes two identical tables
Call makethetable2(ar_mult)
Call makethetable3(ar_mult)
End Sub


Sub test_array_to_acadtable2()
'test to make a random-based two dimensional array of numbers
'and send the array to the maketable routine
'that has been generalized to accept an array of any base

Call connect_acad
Dim rows As Integer, i As Integer
Dim columns As Integer, j As Integer
'change these to anything you like
rows = 14
columns = 16

Dim ar_mult() As Integer
ReDim ar_mult(3 To rows + 2, 3 To columns + 2)

For i = 3 To rows + 2
For j = 3 To columns + 2
ar_mult(i, j) = (i - 2) * (j - 2)
Next j
Next i

Call makethetable3(ar_mult)
End Sub


Sub makethetable3(ar As Variant)
'table is two-dimensional and any-base
    Dim tbl As AcadTable
    Dim i As Integer, j As Integer
    Dim rowcount As Integer, colcount As Integer
    Dim rowLbound As Integer, colLbound As Integer
    Dim rowUbound As Integer, colUbound As Integer
    
    Dim drowh As Double, dcolw As Double
    Dim pt0(0 To 2) As Double
    
    rowLbound = LBound(ar, 1)
    colLbound = LBound(ar, 2)
    rowUbound = UBound(ar, 1)
    colUbound = UBound(ar, 2)
    rowcount = rowUbound - rowLbound + 1
    colcount = colUbound - colLbound + 1
        
        drowh = 0.125
        dcolw = 0.625
    Set tbl = acadDoc.ModelSpace.AddTable(pt0, rowcount, colcount, drowh, dcolw)
        tbl.UnmergeCells 0, 0, 0, 0
        tbl.TitleSuppressed = True
        tbl.HeaderSuppressed = True

    For i = rowLbound To rowUbound
        For j = colLbound To colUbound
        tbl.SetText i - colLbound, j - rowLbound, ar(i, j)
        Next j
    Next i
End Sub


Sub makethetable2(ar As Variant)
'the simpler routine
'assume table is two-dimensional and one-base
'no attempt to set up a tablestyle
'which makes the unmerge method necessary
 
    Dim tbl As AcadTable
    Dim i As Integer, j As Integer
    Dim rowcount As Integer, colcount As Integer
    Dim drowh As Double, dcolw As Double
    Dim pt0(0 To 2) As Double
    
    rowcount = UBound(ar, 1)
    colcount = UBound(ar, 2)
    drowh = 0.125
    dcolw = 0.625
    'create the table sized for the array
   Set tbl = acadDoc.ModelSpace.AddTable(pt0, rowcount, colcount, drowh, dcolw)
    tbl.UnmergeCells 0, 0, 0, 0
    tbl.TitleSuppressed = True
    tbl.HeaderSuppressed = True

    For i = 1 To rowcount
     For j = 1 To colcount
     tbl.SetText i - 1, j - 1, ar(i, j)
     Next j
    Next i

End Sub

any selection of data on a spreadsheet can be saved to an array with a single line of code, and the array fed to the makethetable routine. of course the formatting is terrible but we have tools for that.


Sub make_table_from_selection()
Dim ar_tbl As Variant
ar_tbl = Selection.Value
 'a selection assigned to a variant
 'creates a one-based two-dimension array
 'the first dim is the row, the second is the column
  
'MsgBox LBound(ar_tbl, 1)  returns 1
'MsgBox LBound(ar_tbl, 2)  returns 1

Call connect_acad
Call makethetable3(ar_tbl)

End Sub