分享

【源代码】一键导出CAD块属性到表格

 VBA说 2021-07-17

▎具体需求

使用CAD的人都知道图块,因为图块可以重复插入、做成图库,减少重复操作,被广泛使用。

当图块中有一些文字属性需要经常修改的时候,我们就可以在图块中添加属性文字,并定义成属性块。比如一些图框块,将零散的图元做成块,可以实现批量插入并修改的效果。

有插入就有导出,当我们需要获取属性块中的各个属性内容的时候,挨个获取属性块的信息特别的繁琐,需要打开块属性,手动复制粘贴。

这个时候我们就想到利用程序实现批量读取属性块的内容。

▎思路分析

大概流程:

用户选择一批图元→点击程序按钮,后台循环获取图元的属性。→输出所有属性到excel中。

有几个小细节需要考虑周全。

①获取的块属性个数不一定相同,需要获取所有块属性标题。

②因为块的位置不同,需要根据块的坐标进行排列最终的属性。

程序界面

▎效果及源代码

  • 效果:

代码是在Excel中的,通过excel链接CAD,并且读取属性。

Public Block_Info '存储块属性的坐标及具体数据
Private Sub CommandButton1_Click()
'//导出单个属性
    '//开始对属性按坐标排序
    Dim Result()
    bol = IIf(Me.OptionButton1.Value = True21)
    Block_Info = ArraySortTwo(Block_Info, bol, SortDESC) '按坐标降序排列的属性数组
    col = Getcol(Block_Info, Me.ComboBox1.Value)
    For i = 1 To UBound(Block_Info)
        k = k + 1
        ReDim Preserve Result(1 To 11 To k)
        Result(1, k) = Block_Info(i, col)
    Next
    ActiveCell.Resize(UBound(Result, 2)) = WorksheetFunction.Transpose(Result)
    MsgBox "导出完成!"
    Unload Me
End Sub

Private Sub CommandButton2_Click()
'//导出所有块属性
    '//开始对属性按坐标排序
    Dim Result()
    bol = IIf(Me.OptionButton1.Value = True21)
    Block_Info = ArraySortTwo(Block_Info, bol, SortDESC) '按坐标降序排列的属性数组
    'ActiveCell.Resize(UBound(Block_Info, 2), UBound(Block_Info, 1)) = WorksheetFunction.Transpose(WorksheetFunction.Transpose(Block_Info))
    arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(Block_Info))
    ReDim brr(1 To UBound(arr), 1 To UBound(arr, 2) - 2)
    For i = 1 To UBound(arr)
        For j = 3 To UBound(arr, 2)
            brr(i, j - 2) = arr(i, j)
        Next
    Next
    ActiveCell.Resize(UBound(brr), UBound(brr, 2)) = brr
    MsgBox "导出完成!"
    Unload Me
End Sub


Private Sub UserForm_Initialize()
'//窗体加载初始化事件,有一些必要的错误判断,以及读取块属性到数组中。
    Me.OptionButton1.Value = True
    Set d_TagStr = CreateObject("scripting.dictionary")
    Set oAcadApp = GetObject(, "AutoCAD.Application")
    If Err.Number = 0 Then
        Set oAcadDoc = oAcadApp.ActiveDocument
        '如果没有错误,表示CAD已经运行
        '遍历CAD选择集所有块,采集名字
        Set oSset = oAcadDoc.PickfirstSelectionSet
        BloCount = oSset.Count
        For Each oElem In oSset
            If oElem.EntityName = "AcDbBlockReference" Then
                Set oBlock = oElem
                oBlock.Update
                If oBlock.HasAttributes = True Then
                    oAttrs = oBlock.GetAttributes
                    For iInt1 = LBound(oAttrs) To UBound(oAttrs)
                        'oAttrs(0).TextString
                        d_TagStr(oAttrs(iInt1).TagString) = ""
                    Next iInt1
                End If
            End If
        Next
        '//把块属性字段名,写入窗体
        krr = d_TagStr.Keys
        For i = 0 To UBound(krr)
            Me.ComboBox1.AddItem krr(i)
        Next
        Me.ComboBox1.ListIndex = 0
        '//
        ReDim Block_Info(1 To BloCount + 11 To d_TagStr.Count + 2)
        '//开始处理块属性信息
        For i = 3 To d_TagStr.Count + 2
            Block_Info(11) = 99999  'x坐标
            Block_Info(12) = 99999  'y坐标
            Block_Info(1, i) = krr(i - 3'把属性写入数组第一行
        Next
        '开始写块属性
        k = 1
        For Each oElem In oSset
            If oElem.EntityName = "AcDbBlockReference" Then
                Set oBlock = oElem
                oBlock.Update
                If oBlock.HasAttributes = True Then
                    oAttrs = oBlock.GetAttributes
                    PtBlock = oBlock.InsertionPoint
                    k = k + 1
                    For iInt1 = LBound(oAttrs) To UBound(oAttrs)
                        txts = oAttrs(iInt1).TextString
                        tags = oAttrs(iInt1).TagString
                        col = Getcol(Block_Info, tags)
                        Block_Info(k, 1) = PtBlock(0'x坐标
                        Block_Info(k, 2) = PtBlock(1'y坐标
                        Block_Info(k, col) = txts '属性值
                    Next
                End If
            End If
        Next
        '//
    End If
End Sub


Function Getcol(arr, keystr)
    '//返回关键字在数组中的列
    For i = 1 To UBound(arr, 2)
        If arr(1, i) = keystr Then
            Getcol = i
            Exit Function
        End If
    Next
End Function

上述代码中:ArraySortTwo这个对二维数组进行排序的自定义函数过长们需要的单独找我咨询即可。

▎知识点扩展

  • PickfirstSelectionSet属性

获取命令执行前已经选定了的选择集。通俗的说,就是获取已经选定的所有CAD图元。

Sub Example_PickfirstSelectionSet()
    Dim pfSS As AcadSelectionSet
    Dim ssobject As AcadEntity
    Dim msg As String
    msg = vbCrLf
    Set pfSS = ThisDrawing.PickfirstSelectionSet
    For Each ssobject In pfSS
        msg = msg & vbCrLf & ssobject.ObjectName
    Next ssobject
    MsgBox "选择集包括以下内容: " & msg
End Sub
  • GetAttributes属性


获取在块参照中的属性。该方法返回一个附着在块参照上可编辑的属性参照数组。

Sub 遍历所有块获取块属性()
    For Each oElem In oSset '遍历选择集中所有的块
        If oBlock.HasAttributes = True Then '如果该块有块属性,接着就开始读取
            oAttrs = oBlock.GetAttributes '获取块属性的属性数组
            For iInt1 = LBound(oAttrs) To UBound(oAttrs) '遍历数组
                txts = oAttrs(iInt1).TextString '获取块属性的标识文字和值
                tags = oAttrs(iInt1).TagString
            Next
        End If
    Next
End Sub

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多