Layers from excel to CAD via VBA

Layers from excel to CAD via VBA

Anonymous
Not applicable
2,987 Views
4 Replies
Message 1 of 5

Layers from excel to CAD via VBA

Anonymous
Not applicable

Hello,

 

I am still learning some basic coding to be able to control Layers via excel with simple code and have two questions to ask:

 

1. Everything seems fine except Lineweight column. Every time I export layer to the CAD lineweight comes as "Continuous". Either it has something I cannot understand behind it or I cannot find the right information what should be written in the excel Lineweight column;

 

2. As you can see in the code I have command only for one active row, it would be great to be able export multiple rows to CAD;

x = ActiveCell.Row

 

 

 

Code - excel.png

 

Sub C3D()
Dim ACAD
x = ActiveCell.Row

y = Cells(x, 2)

If Not (y = "" Or y = "Name") Then

Set ACAD = Nothing
On Error Resume Next
Set ACAD = GetObject(, "AutoCAD.Application")
ACAD.Visible = True
Set doc = ACAD.ActiveDocument

Dim linetypeName As String

On Error Resume Next ' trap any load errors
doc.Linetypes.Load Cells(x, 7), "acad.lin"

Set layerObj = doc.Layers.Add(Cells(x, 2))
layerObj.Freeze = Cells(x, 3)
layerObj.LayerOn = Cells(x, 4)
layerObj.Lock = Cells(x, 5)
layerObj.Color = Cells(x, 6)
layerObj.LineType = Cells(x, 7)
layerObj.LineWeight = Cells(x, 8)
layerObj.PlotStyleName = Cells(x, 10)
layerObj.Plottable = Cells(x, 11)
layerObj.ViewportDefault = Cells(x, 12)
layerObj.Description = Cells(x, 13)

Set ACAD = Nothing
End If

End Sub

 

Any suggestions or comments would be great.

 

0 Likes
2,988 Views
4 Replies
Replies (4)
Message 2 of 5

Anonymous
Not applicable

I'm not familiar with linetype or lineweight objects but I guess your main issue is that such things as "acLnWtByLwDefault" are autocad enumeration, i.e. they are actually "Long" type constants that you can directly use in your code but not set them via strings

in order to do that you have to build some functions to check the string value against enumeration strings like follows

 

Function GetLinweight(lineweigthStrng As String, lineweigthEnum As Long) As Boolean
    GetLinweight = True
    Select Case lineweigthStrng
        Case "acLnWtByLayer"
            lineweigthEnum = acLnWtByLayer
        Case "acLnWtByBlock"
            lineweigthEnum = acLnWtByBlock
        Case "acLnWtByLwDefault"
            lineweigthEnum = acLnWtByLwDefault
        Case "acLnWt000"
            lineweigthEnum = acLnWt000
            
        ' go on listing your other cases
        
        Case Else
            GetLinweight = False ' if no match then return False
    End Select
End Function

and use it in the fashion of the following

 

Dim lineweightEnum As Long
If GetLinweight(Cells(x, 8), lineweightEnum) Then layerObj.LineWeight = lineweightEnum 'set current layer line weight only if cell content matches any acad line weight enumeration

this should apply to color property too

 

while you my want to follow some pieces of advice:

- use the "function" coding pattern to break your code into bits that do specific jobs and have (hopefully) more manageable code

- use "On Error Resume Next" only to prevent error stopping your code in strict conjunction with subsequent code to handle them consciously

- use "Option Explicit" keyword at the very top of your module to force you to declare all variabls to both help you debug your code and have much

- always use full workbook and worksheet range qualification to ensure what excel object you are really acting on

- use "Specialcells" excel range property to loop through specific cells only (e.g.: "only "text" cells, like in this case)

 

like follows 

 

Option Explicit

Sub C3D()
    Dim ACAD As AcadApplication
    Dim doc As AcadDocument
    
    If Not GetDoc(ACAD, doc) Then
        MsgBox "Autocad session or activedocument not available" & vbCrLf & vbCrLf & "the program ends"
        Exit Sub
    End If
    
    Dim cell As Range
    Dim layerObj As AcadLayer
    Dim linetypeName As String
    Dim layerData As Variant
    Dim colorEnum As Long, lineweightEnum As Long
    With Workbooks("MyWorkbookName").Worksheets("myWorksheetName") ' change "MyWorkbookName" or "myWorksheetName" to your actual workbook and worksheet names
        For Each cell In .Range("B2", .Cells(.Rows.Count, "B").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues) ' loop through column "B" not empty cells with text content only
            layerData = Application.Transpose(Application.Transpose(cell.Resize(1, 12).Value))
            With doc.Layers.Add(layerData(1))
                .LayerOn = layerData(2)
                .Freeze = layerData(3)
                .Lock = layerData(4)
                If GetColor(CStr(layerData(5)), colorEnum) Then .Color = colorEnum 'set current layer color only if cell content matches any acad color enumeration
                If HasLineTypeBeenLoaded(doc, CStr(layerData(6))) Then .LineType = layerData(6) 'set current layer line type only if cell content matches any acad.lin existing line type
                If GetLinweight(CStr(layerData(7)), lineweightEnum) Then .LineWeight = lineweightEnum 'set current layer line weight only if cell content matches any acad line weight enumeration
                .PlotStyleName = layerData(9)
                .Plottable = layerData(10)
                .ViewportDefault = layerData(11)
                .Description = layerData(12)
            End With
        Next
    End With
    Set doc = Nothing
    Set ACAD = Nothing
End Sub

Function GetColor(colorStrng As String, colorEnum As Long) As Boolean
    GetColor = True
    Select Case UCase(colorStrng)
        Case "WHITE"
            colorEnum = acWhite
        Case "BLUE"
            colorEnum = acBlue
        Case "RED"
            colorEnum = acRed
        Case "GREEN"
            colorEnum = acGreen
            
        ' go on listing your other cases
        
        Case Else
            GetColor = False ' if no match then return False
    End Select
End Function

Function GetLinweight(lineweigthStrng As String, lineweigthEnum As Long) As Boolean
    GetLinweight = True
    Select Case lineweigthStrng
        Case "acLnWtByLayer"
            lineweigthEnum = acLnWtByLayer
        Case "acLnWtByBlock"
            lineweigthEnum = acLnWtByBlock
        Case "acLnWtByLwDefault"
            lineweigthEnum = acLnWtByLwDefault
        Case "acLnWt000"
            lineweigthEnum = acLnWt000
            
        ' go on listing your other cases
        
        Case Else
            GetLinweight = False ' if no match then return False
    End Select
End Function

Function HasLineTypeBeenLoaded(doc As AcadDocument, linetypeName As String)
    Dim myLineType As AcadLineType
    
    Err.Clear
    On Error Resume Next ' trap any load errors
    Set myLineType = doc.Linetypes.Item(linetypeName) ' check for linetype already in document linetypes collection
    Err.Clear
    If myLineType Is Nothing Then doc.Linetypes.Load linetypeName, "acad.lin" 'if not already there then try adding it
    HasLineTypeBeenLoaded = Err = 0
End Function

Function GetDoc(ACAD As AcadApplication, doc As AcadDocument) As Boolean
    Set ACAD = Nothing
    On Error Resume Next
    Set ACAD = GetObject(, "AutoCAD.Application")
    If Not ACAD Is Nothing Then
        Set doc = ACAD.ActiveDocument
        If Not doc Is Nothing Then
            ACAD.Visible = True
            GetDoc = True
        Else
            Set ACAD = Nothing
        End If
    End If
End Function

 

Message 3 of 5

sieclaprzemyslaw
Contributor
Contributor

Hello,

 

If you go to help page of lineweight property, you will see the list of values:

acLnWtByLayer
acLnWtByBlock
acLnWtByLwDefault
acLnWt000
acLnWt005
acLnWt009,

(...)

 

And as we can see on your picture you are using different values (you need to choose one from the list).

 

Good luck!

0 Likes
Message 4 of 5

Anonymous
Not applicable

Function HasLineTypeBeenLoaded(doc As AcadDocument, linetypeName As String)

Here it comes compile arror line type not defined

0 Likes
Message 5 of 5

Anonymous
Not applicable

which line is highlighted when you get the error?

0 Likes