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
留言
張貼留言