AutoCADVBA 圖紙小精靈_Ver1.0
前言:
有鑑於大部分前輩的圖都建立於模型空間(ModelSpace)之下,每次畫圖完畢發現少(多)某一張圖,當要插入或者是刪除時,就會需要在圖框內的頁次欄位進行更動,這點可以說是相當麻煩(尤其是對於超過30頁的圖檔來說),因而引發筆者寫這篇Side Project供參考使用。
Demo影片:
使用方法:
1.程式介面建立於VBA之下,為一個dvb檔,有關如何開啟請參考(如何使用dvb檔)。
2.請檢查頁次項目部分為: 第OO頁共OO頁。
3.請檢查圖框圈選線是否為聚合線(連續線段):偵測(LowerLeftPoint,UpperRightPoint)使用。
4.請檢查圖框圈選線所處圖層是否為 ( 出圖圖框 ):過濾圖框項目。
5.執行VBA巨集→點選第一個module(ShowUserForm)→執行。
按鈕介紹:
1.創造圖框:若需要創建一連串的圖框們,可先在Excel檔中定義圖框內容後批次輸出。
2.新增圖紙:框選所有圖框,輸入要插入的頁次,會把所有框選起來的頁次及>=插入頁次的 部分批次增加。
3.去除圖紙:框選所有圖框,輸入要刪除的頁次,會把所有框選起來的頁次及>=插入頁次的 部分批次減少。
4.批次列印:必須先設定列印配置,請參考 (AutoCAD顧問-批次出圖 )
注意事項:先選擇要輸出的印表機→出圖內容改為視窗(要求圈選時先隨意圈選)→置中出圖→比例為1:1→圖面方位(橫式)→如有需要再更改出圖型式表→套用至配置。
檔案下載:
本機端執行環境 AutoCAD2016 x64,Excel2016 x64,下載點: Frame.dvb
原始碼:
UserFrom比較沒東西就不放上來獻醜了。
比較重要的還是Module的部分:(其實是3個module改來改去,我把他合併起來丟上來而已)
有鑑於大部分前輩的圖都建立於模型空間(ModelSpace)之下,每次畫圖完畢發現少(多)某一張圖,當要插入或者是刪除時,就會需要在圖框內的頁次欄位進行更動,這點可以說是相當麻煩(尤其是對於超過30頁的圖檔來說),因而引發筆者寫這篇Side Project供參考使用。
使用方法:
1.程式介面建立於VBA之下,為一個dvb檔,有關如何開啟請參考(如何使用dvb檔)。
2.請檢查頁次項目部分為: 第OO頁共OO頁。
3.請檢查圖框圈選線是否為聚合線(連續線段):偵測(LowerLeftPoint,UpperRightPoint)使用。
4.請檢查圖框圈選線所處圖層是否為 ( 出圖圖框 ):過濾圖框項目。
5.執行VBA巨集→點選第一個module(ShowUserForm)→執行。
圖一、紅色部分為圖框圈選線。 |
按鈕介紹:
1.創造圖框:若需要創建一連串的圖框們,可先在Excel檔中定義圖框內容後批次輸出。
圖二、圖框內容定義 |
2.新增圖紙:框選所有圖框,輸入要插入的頁次,會把所有框選起來的頁次及>=插入頁次的 部分批次增加。
3.去除圖紙:框選所有圖框,輸入要刪除的頁次,會把所有框選起來的頁次及>=插入頁次的 部分批次減少。
4.批次列印:必須先設定列印配置,請參考 (AutoCAD顧問-批次出圖 )
圖三、列印配置 |
注意事項:先選擇要輸出的印表機→出圖內容改為視窗(要求圈選時先隨意圈選)→置中出圖→比例為1:1→圖面方位(橫式)→如有需要再更改出圖型式表→套用至配置。
檔案下載:
本機端執行環境 AutoCAD2016 x64,Excel2016 x64,下載點: Frame.dvb
原始碼:
UserFrom比較沒東西就不放上來獻醜了。
比較重要的還是Module的部分:(其實是3個module改來改去,我把他合併起來丟上來而已)
Public wrkb As Object Public wrks As Object Public objexcel As Object Public rng As Object Public plineobj As AcadPolyline Public lwplineobj As AcadLWPolyline '2D Public txtobj As AcadText Public lay As AcadLayer Sub ShowUserForm() UserForm1.show End Sub Sub ChangeFrame_Main(ByVal method As Integer) Dim sset As AcadSelectionSet Dim FilterType(0) As Integer Dim FilterData(0) As Variant Dim PlotArr(1 To 100, 1 To 4) As Variant Dim PlotArrFinal(1 To 100, 1 To 4) As Variant Dim k As Integer On Error Resume Next ThisDrawing.SelectionSets("SS1").Delete On Error GoTo 0 Set sset = ThisDrawing.SelectionSets.Add("SS1") FilterType(0) = 8 FilterData(0) = "出圖圖框" sset.SelectOnScreen FilterType, FilterData For Each Item In sset Dim lwpline As AcadLWPolyline On Error GoTo ERROR_HANDLE Set lwpline = Item k = k + 1 'Debug.Print "第" & k & "項目:" max_x = lwpline.Coordinates(0) max_y = lwpline.Coordinates(1) min_x = lwpline.Coordinates(0) min_y = lwpline.Coordinates(1) For i = 0 To 7 co = lwpline.Coordinates(i) If i Mod 2 = 0 Then X = co If X > max_x Then max_x = X If X < min_x Then min_x = X Else Y = co If Y > max_y Then max_y = Y If Y < min_y Then min_y = Y End If Next PlotArr(k, 1) = max_x 'add data to an array PlotArr(k, 2) = max_y PlotArr(k, 3) = min_x PlotArr(k, 4) = min_y 'Debug.Print max_x & vbCrLf & max_y & vbCrLf & min_x & vbCrLf & min_y ERROR_HANDLE: Next On Error GoTo 0 Call AddFrame(PlotArr, method) End Sub Sub AddFrame(ByRef PlotArrFinal() As Variant, ByVal method As Integer) Dim LowerLeft(0 To 2) As Double Dim UpperRight(0 To 2) As Double Dim sset As AcadSelectionSet Dim FilterType(0) As Integer Dim FilterData(0) As Variant If method = 1 Then insertnum = InputBox("你要插入第幾張?", "圖紙小精靈對話小框框") ElseIf method = 2 Then insertnum = InputBox("你要扣除第幾張?", "圖紙小精靈對話小框框") End If insertnum = Val(insertnum) For i = 1 To 100 If PlotArrFinal(i, 3) = "" Then Exit For LowerLeft(0) = PlotArrFinal(i, 1) LowerLeft(1) = PlotArrFinal(i, 2) UpperRight(0) = PlotArrFinal(i, 3) UpperRight(1) = PlotArrFinal(i, 4) On Error Resume Next ThisDrawing.SelectionSets("SS1").Delete On Error GoTo 0 Set sset = ThisDrawing.SelectionSets.Add("SS1") FilterType(0) = 0 FilterData(0) = "Text" sset.Select acSelectionSetCrossing, LowerLeft, UpperRight, FilterType, FilterData For Each Item In sset txt = Item.TextString If txt Like "第*共*" Then 'Debug.Print txt pt1 = InStr(1, txt, "頁") pt2 = InStr(pt1 + 1, txt, "頁") num1 = Val(Mid(txt, 2, pt1 - 2)) If method = 1 Then If num1 >= insertnum Then num1 = num1 + 1 num2 = Val(Mid(txt, pt1 + 2, pt2 - (pt1 + 2))) + 1 ElseIf method = 2 Then If num1 >= insertnum Then num1 = num1 - 1 num2 = Val(Mid(txt, pt1 + 2, pt2 - (pt1 + 2))) - 1 End If 'Debug.Print pt1 & " " & pt2 & " " & num1 & " " & num2 Item.TextString = "第" & num1 & "頁共" & num2 & "頁" End If Next Next End Sub Sub CreateFrame_Main(ByVal a As Integer) Dim txtArr() As Variant Dim ii As Integer ret = ThisDrawing.Utility.GetPoint(, "請選擇圖框產生的起始點") X = ret(0): Y = ret(1) X_origin = X Call GetExcel(wrks) lr = wrks.cells(1, 3).End(-4121).row 'xldown=-4121 lc = wrks.cells(1, 1).End(-4161).column 'xltoright=-4161 ReDim txtArr(1 To lc, 1 To 2) For r = 2 To lr For c = 1 To lc If wrks.cells(r, c) <> "" Then txtArr(c, 1) = wrks.cells(r, c) txtArr(c, 2) = wrks.cells(1, c) Next txtArr(lc, 1) = "第" & r - 1 & "頁共" & lr - 1 & "頁" If r > 2 Then X = X + 500 If ii Mod 10 = 0 And ii <> 0 Then Y = Y - 500 X = X_origin End If Call PlotFrameOuter(X, Y) Call PlotFrame(X, Y) Call PlotFrameInner(X, Y, txtArr) ii = ii + 1 Next End Sub Sub PlotFrameOuter(ByVal X As Double, ByVal Y As Double) Dim txtpt(2) As Double Dim vertices(5 * 2 - 1) As Double vertices(0) = X - 20 vertices(1) = Y - 10 vertices(2) = X - 20 vertices(3) = Y + 277 + 10 vertices(4) = X + 390 + 10 vertices(5) = Y + 277 + 10 vertices(6) = X + 390 + 10 vertices(7) = Y - 10 vertices(8) = X - 20 vertices(9) = Y - 10 ThisDrawing.ActiveLayer = ThisDrawing.Layers("出圖圖框") Set lwplineobj = ThisDrawing.ModelSpace.AddLightWeightPolyline(vertices) ThisDrawing.ActiveLayer = ThisDrawing.Layers("0") txtpt(0) = X + 300 txtpt(1) = Y - 20 Set txtobj = ThisDrawing.ModelSpace.AddText("出圖圈選範圍線(A3) 297*420", txtpt, 5) txtobj.color = acRed End Sub Sub PlotFrame(ByVal X As Double, ByVal Y As Double) Dim vertices(5 * 3 - 1) As Double vertices(0) = X vertices(1) = Y vertices(3) = X vertices(4) = Y + 277 vertices(6) = X + 390 vertices(7) = Y + 277 vertices(9) = X + 390 vertices(10) = Y vertices(12) = X - 0.8 vertices(13) = Y Set plineobj = ThisDrawing.ModelSpace.AddPolyline(vertices) plineobj.ConstantWidth = 1.6 End Sub Sub PlotFrameInner(ByVal X As Double, ByVal Y As Double, ByRef txtArr() As Variant) Dim vertices(3 * 2 - 1) As Double Dim txtpt(2) As Double arr = Array(60, 90, 70, 20, 20, 20, 20, 20, 20, 20, 30) '分割長度(由左到右) For i = 1 To 2 vertices(0) = X vertices(1) = Y + 9.25 * i vertices(3) = X + 390 vertices(4) = Y + 9.25 * i Set plineobj = ThisDrawing.ModelSpace.AddPolyline(vertices) plineobj.ConstantWidth = 0.5 Xt = vertices(0) For j = 0 To UBound(arr) Xt = Xt + arr(j) Xtt = Xt - 0.5 * arr(j) Yt = vertices(1) - 0.5 * 9.25 txtpt(0) = Xtt txtpt(1) = Yt Set txtobj = ThisDrawing.ModelSpace.AddText(txtArr(j + 1, i), txtpt, 3.5) '文字高度3.5 txtobj.Alignment = acAlignmentMiddleCenter txtobj.TextAlignmentPoint = txtpt Next Next For j = 0 To UBound(arr) - 1 X = X + arr(j) vertices(0) = X vertices(1) = Y vertices(3) = X vertices(4) = Y + 18.5 Set plineobj = ThisDrawing.ModelSpace.AddPolyline(vertices) plineobj.ConstantWidth = 0.5 Next End Sub Sub GetExcel(ByRef wrks As Object) On Error Resume Next Set objexcel = GetObject(, "Excel.Application") If Err.Number > 0 Then Set objexcel = CreateObject("Excel.Application") Err.Clear End If Set wrkb = objexcel.ActiveWorkbook Set wrks = objexcel.ActiveSheet Set lay = ThisDrawing.Layers.Add("出圖圖框") lay.color = acRed lay.ViewportDefault = True End Sub Sub PrintOut_Main(ByVal a As Integer) Dim sset As AcadSelectionSet Dim FilterType(0) As Integer Dim FilterData(0) As Variant Dim PlotArr(1 To 100, 1 To 4) As Variant Dim PlotArrFinal(1 To 100, 1 To 4) As Variant Dim k As Integer On Error Resume Next ThisDrawing.SelectionSets("SS1").Delete On Error GoTo 0 Set sset = ThisDrawing.SelectionSets.Add("SS1") FilterType(0) = 8 FilterData(0) = "出圖圖框" sset.SelectOnScreen FilterType, FilterData For Each Item In sset Dim lwpline As AcadLWPolyline On Error GoTo ERROR_HANDLE Set lwpline = Item k = k + 1 'Debug.Print "第" & k & "項目:" max_x = lwpline.Coordinates(0) max_y = lwpline.Coordinates(1) min_x = lwpline.Coordinates(0) min_y = lwpline.Coordinates(1) For i = 0 To 7 co = lwpline.Coordinates(i) If i Mod 2 = 0 Then X = co If X > max_x Then max_x = X If X < min_x Then min_x = X Else Y = co If Y > max_y Then max_y = Y If Y < min_y Then min_y = Y End If Next PlotArr(k, 1) = max_x 'add data to an array PlotArr(k, 2) = max_y PlotArr(k, 3) = min_x PlotArr(k, 4) = min_y 'Debug.Print max_x & vbCrLf & max_y & vbCrLf & min_x & vbCrLf & min_y ERROR_HANDLE: Next On Error GoTo 0 Call SortData(PlotArr, k, PlotArrFinal) Call PrintOut(PlotArrFinal) End Sub Sub SortData(ByRef PlotArr() As Variant, ByVal k As Integer, ByRef PlotArrFinal() As Variant) order = 1 p = 1 For i = 1 To k min_x = PlotArr(i, 3) For j = order To k order_x = PlotArr(j, 3) If order_x < min_x Then min_x = order_x Next For n = 1 To k If PlotArr(n, 3) = min_x Then For z = 1 To 4 PlotArrFinal(p, z) = PlotArr(n, z) 'min PlotArr(n, z) = PlotArr(i, z) PlotArr(i, z) = PlotArrFinal(p, z) Next p = p + 1 Exit For End If Next order = order + 1 Next End Sub Sub PrintOut(ByRef PlotArrFinal() As Variant) Dim LowerLeft(0 To 1) As Double Dim UpperRight(0 To 1) As Double Dim plotobj As AcadPlot Dim lay As AcadLayout Dim IfAsked As Boolean Set lay = ThisDrawing.ActiveLayout Set plotobj = ThisDrawing.Plot 'lay.ConfigName = "DWG to PDF.pc3" 'lay.CanonicalMediaName = "ISO_A3_(297.00_x_420.00_MM)" IfAsked = False For i = 1 To 100 If PlotArrFinal(i, 3) = "" Then Exit For Debug.Print "第" & i & "張圖:列印程序 " LowerLeft(0) = PlotArrFinal(i, 1) LowerLeft(1) = PlotArrFinal(i, 2) UpperRight(0) = PlotArrFinal(i, 3) UpperRight(1) = PlotArrFinal(i, 4) lay.CenterPlot = True lay.PlotType = acWindow lay.SetWindowToPlot LowerLeft, UpperRight lay.GetWindowToPlot LowerLeft, UpperRight If IfAsked = False Then plotobj.DisplayPlotPreview acPartialPreview msg = MsgBox("請問該測試圖檔是不是正確的?", vbYesNo) End If If msg = vbYes Then plotobj.PlotToDevice IfAsked = True Else Exit Sub End If Next End Sub
留言
張貼留言