Tools.bas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. Attribute VB_Name = "Tools"
  2. Public Sub 填入居中文字(Str)
  3. Dim s As Shape
  4. Set s = ActiveSelection
  5. X = s.CenterX
  6. Y = s.CenterY
  7. Set s = ActiveLayer.CreateArtisticText(0, 0, Str)
  8. s.CenterX = X
  9. s.CenterY = Y
  10. End Sub
  11. Public Sub 尺寸标注()
  12. ActiveDocument.Unit = cdrMillimeter
  13. Set s = ActiveSelection
  14. X = s.CenterX: Y = s.TopY
  15. sw = s.SizeWidth: sh = s.SizeHeight
  16. Text = Int(sw) & "x" & Int(sh) & "mm"
  17. Set s = ActiveLayer.CreateArtisticText(0, 0, Text)
  18. s.CenterX = X: s.BottomY = Y + 5
  19. End Sub
  20. Public Sub 批量居中文字(Str)
  21. Dim s As Shape, sr As ShapeRange
  22. Set sr = ActiveSelectionRange
  23. For Each s In sr.Shapes
  24. X = s.CenterX: Y = s.CenterY
  25. Set s = ActiveLayer.CreateArtisticText(0, 0, Str)
  26. s.CenterX = X: s.CenterY = Y
  27. Next
  28. End Sub
  29. Public Sub 批量标注()
  30. ActiveDocument.Unit = cdrMillimeter
  31. Set sr = ActiveSelectionRange
  32. For Each s In sr.Shapes
  33. X = s.CenterX: Y = s.TopY
  34. sw = s.SizeWidth: sh = s.SizeHeight
  35. Text = Int(sw + 0.5) & "x" & Int(sh + 0.5) & "mm"
  36. Set s = ActiveLayer.CreateArtisticText(0, 0, Text)
  37. s.CenterX = X: s.BottomY = Y + 5
  38. Next
  39. End Sub
  40. Public Sub 智能群组()
  41. Set s1 = ActiveSelectionRange.CustomCommand("Boundary", "CreateBoundary")
  42. Set brk1 = s1.BreakApartEx
  43. For Each s In brk1
  44. Set sh = ActivePage.SelectShapesFromRectangle(s.LeftX, s.TopY, s.RightX, s.BottomY, True)
  45. sh.Shapes.All.group
  46. s.Delete
  47. Next
  48. End Sub
  49. ' 实践应用: 选择物件群组,页面设置物件大小,物件页面居中
  50. Public Function 群组居中页面()
  51. ActiveDocument.Unit = cdrMillimeter
  52. Dim OrigSelection As ShapeRange, sh As Shape
  53. Set OrigSelection = ActiveSelectionRange
  54. Set sh = OrigSelection.group
  55. ' MsgBox "选择物件尺寸: " & sh.SizeWidth & "x" & sh.SizeHeight
  56. ActivePage.SetSize Int(sh.SizeWidth + 0.9), Int(sh.SizeHeight + 0.9)
  57. #If VBA7 Then
  58. ActiveDocument.ClearSelection
  59. sh.AddToSelection
  60. ActiveSelection.AlignAndDistribute 3, 3, 2, 0, False, 2
  61. #Else
  62. sh.AlignToPageCenter cdrAlignHCenter + cdrAlignVCenter
  63. #End If
  64. End Function
  65. Public Function 批量多页居中()
  66. If 0 = ActiveSelectionRange.Count Then Exit Function
  67. On Error GoTo ErrorHandler
  68. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  69. ActiveDocument.Unit = cdrMillimeter
  70. Set sr = ActiveSelectionRange
  71. total = sr.Count
  72. '// 建立多页面
  73. Set doc = ActiveDocument
  74. doc.AddPages (total - 1)
  75. Dim sh As Shape
  76. '// 遍历批量物件,放置物件到页面
  77. For i = 1 To sr.Count
  78. doc.Pages(i).Activate
  79. Set sh = sr.Shapes(i)
  80. ActivePage.SetSize Int(sh.SizeWidth + 0.9), Int(sh.SizeHeight + 0.9)
  81. '// 物件居中页面
  82. #If VBA7 Then
  83. ActiveDocument.ClearSelection
  84. sh.AddToSelection
  85. ActiveSelection.AlignAndDistribute 3, 3, 2, 0, False, 2
  86. #Else
  87. sh.AlignToPageCenter cdrAlignHCenter + cdrAlignVCenter
  88. #End If
  89. Next i
  90. ActiveDocument.EndCommandGroup: Application.Optimization = False
  91. ActiveWindow.Refresh: Application.Refresh
  92. Exit Function
  93. ErrorHandler:
  94. Application.Optimization = False
  95. MsgBox "请先选择一些物件"
  96. On Error Resume Next
  97. End Function
  98. '// 安全线: 点击一次建立辅助线,再调用清除参考线
  99. Public Function guideangle(actnumber As ShapeRange, cardblood As Integer)
  100. Dim sr As ShapeRange
  101. Set sr = ActiveDocument.MasterPage.GuidesLayer.FindShapes(Type:=cdrGuidelineShape)
  102. If sr.Count <> 0 Then
  103. sr.Delete
  104. Exit Function
  105. End If
  106. If 0 = ActiveSelectionRange.Count Then Exit Function
  107. ActiveDocument.Unit = cdrMillimeter
  108. With actnumber
  109. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(0, .TopY - cardblood, 0#)
  110. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(0, .BottomY + cardblood, 0#)
  111. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(.LeftX + cardblood, 0, 90#)
  112. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(.RightX - cardblood, 0, 90#)
  113. End With
  114. End Function
  115. Public Function 按面积排列(space_width As Double)
  116. If 0 = ActiveSelectionRange.Count Then Exit Function
  117. ActiveDocument.Unit = cdrMillimeter
  118. ActiveDocument.ReferencePoint = cdrCenter
  119. Set ssr = ActiveSelectionRange
  120. cnt = 1
  121. #If VBA7 Then
  122. ssr.Sort "@shape1.width * @shape1.height < @shape2.width * @shape2.height"
  123. #Else
  124. ' X4 不支持 ShapeRange.sort
  125. #End If
  126. Dim Str As String, size As String
  127. For Each sh In ssr
  128. size = Int(sh.SizeWidth + 0.5) & "x" & Int(sh.SizeHeight + 0.5) & "mm"
  129. sh.SetSize Int(sh.SizeWidth + 0.5), Int(sh.SizeHeight + 0.5)
  130. Str = Str & size & vbNewLine
  131. Next sh
  132. ActiveDocument.ReferencePoint = cdrTopLeft
  133. For Each s In ssr
  134. If cnt > 1 Then s.SetPosition ssr(cnt - 1).LeftX, ssr(cnt - 1).BottomY - space_width
  135. cnt = cnt + 1
  136. Next s
  137. ' 写文件,可以EXCEL里统计
  138. ' Set fs = CreateObject("Scripting.FileSystemObject")
  139. ' Set f = fs.CreateTextFile("D:\size.txt", True)
  140. ' f.WriteLine str: f.Close
  141. Str = 分类汇总(Str)
  142. Debug.Print Str
  143. Dim s1 As Shape
  144. ' Set s1 = ActiveLayer.CreateParagraphText(0, 0, 100, 150, Str, Font:="华文中宋")
  145. X = ssr.FirstShape.LeftX - 100
  146. Y = ssr.FirstShape.TopY
  147. Set s1 = ActiveLayer.CreateParagraphText(X, Y, X + 90, Y - 150, Str, Font:="华文中宋")
  148. End Function
  149. '// 实现Excel里分类汇总功能
  150. Private Function 分类汇总(Str As String) As String
  151. Dim a, b, d, arr
  152. Str = VBA.Replace(Str, vbNewLine, " ")
  153. Do While InStr(Str, " ")
  154. Str = VBA.Replace(Str, " ", " ")
  155. Loop
  156. arr = Split(Str)
  157. Set d = CreateObject("Scripting.dictionary")
  158. For i = 0 To UBound(arr) - 1
  159. If d.Exists(arr(i)) = True Then
  160. d.Item(arr(i)) = d.Item(arr(i)) + 1
  161. Else
  162. d.Add arr(i), 1
  163. End If
  164. Next
  165. Str = " 规 格" & vbTab & vbTab & vbTab & "数量" & vbNewLine
  166. a = d.keys: b = d.items
  167. For i = 0 To d.Count - 1
  168. ' Debug.Print a(i), b(i)
  169. Str = Str & a(i) & vbTab & vbTab & b(i) & "条" & vbNewLine
  170. Next
  171. 分类汇总 = Str & "合计总量:" & vbTab & vbTab & vbTab & UBound(arr) & "条" & vbNewLine
  172. End Function
  173. ' 两个端点的坐标,为(x1,y1)和(x2,y2) 那么其角度a的tan值: tana=(y2-y1)/(x2-x1)
  174. ' 所以计算arctan(y2-y1)/(x2-x1), 得到其角度值a
  175. ' VB中用atn(), 返回值是弧度,需要 乘以 PI /180
  176. Private Function lineangle(x1, y1, x2, y2) As Double
  177. pi = 4 * VBA.Atn(1) ' 计算圆周率
  178. If x2 = x1 Then
  179. lineangle = 90: Exit Function
  180. End If
  181. lineangle = VBA.Atn((y2 - y1) / (x2 - x1)) / pi * 180
  182. End Function
  183. Public Function 角度转平()
  184. On Error GoTo ErrorHandler
  185. ' ActiveDocument.ReferencePoint = cdrCenter
  186. Set sr = ActiveSelectionRange
  187. Set nr = sr.LastShape.DisplayCurve.Nodes.All
  188. If nr.Count = 2 Then
  189. x1 = nr.FirstNode.PositionX: y1 = nr.FirstNode.PositionY
  190. x2 = nr.LastNode.PositionX: y2 = nr.LastNode.PositionY
  191. a = lineangle(x1, y1, x2, y2): sr.Rotate -a
  192. ' sr.LastShape.Delete '// 删除参考线
  193. End If
  194. ErrorHandler:
  195. End Function
  196. Public Function 自动旋转角度()
  197. On Error GoTo ErrorHandler
  198. ' ActiveDocument.ReferencePoint = cdrCenter
  199. Set sr = ActiveSelectionRange
  200. Set nr = sr.LastShape.DisplayCurve.Nodes.All
  201. If nr.Count = 2 Then
  202. x1 = nr.FirstNode.PositionX: y1 = nr.FirstNode.PositionY
  203. x2 = nr.LastNode.PositionX: y2 = nr.LastNode.PositionY
  204. a = lineangle(x1, y1, x2, y2): sr.Rotate 90 + a
  205. sr.LastShape.Delete '// 删除参考线
  206. End If
  207. ErrorHandler:
  208. End Function
  209. Public Function 交换对象()
  210. Set sr = ActiveSelectionRange
  211. If sr.Count = 2 Then
  212. X = sr.LastShape.CenterX: Y = sr.LastShape.CenterY
  213. sr.LastShape.CenterX = sr.FirstShape.CenterX: sr.LastShape.CenterY = sr.FirstShape.CenterY
  214. sr.FirstShape.CenterX = X: sr.FirstShape.CenterY = Y
  215. End If
  216. End Function
  217. '// ===================================================
  218. Private Sub btn_autoalign_byrow_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  219. If get_events("btn_autoalign_byrow", Shift, Button) = "exit" Then Exit Sub
  220. autogroup("group_lines", 16 + Shift).CreateSelection
  221. End Sub
  222. Private Sub btn_autoalign_bycolumn_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  223. If get_events("btn_autoalign_bycolumn", Shift, Button) = "exit" Then Exit Sub
  224. autogroup("group_lines", 13 + Shift).CreateSelection
  225. End Sub
  226. Private Sub btn_autogroup_byrow_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  227. If get_events("btn_autogroup_byrow", Shift, Button) = "exit" Then Exit Sub
  228. autogroup("group_lines", 6).CreateSelection
  229. End Sub
  230. Private Sub btn_autogroup_bycolumn_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  231. If get_events("btn_autogroup_bycolumn", Shift, Button) = "exit" Then Exit Sub
  232. autogroup("group_lines", 3).CreateSelection
  233. End Sub
  234. Private Sub btn_autogroup_bysquare_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  235. If get_events("btn_autogroup_bysquare", Shift, Button) = "exit" Then Exit Sub
  236. autogroup("group").CreateSelection
  237. End Sub
  238. Private Sub btn_autogroup_byshape_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  239. If get_events("btn_autogroup_byshape", Shift, Button) = "exit" Then Exit Sub
  240. autogroup("group", 1).CreateSelection
  241. End Sub
  242. Public Sub begin_func(Optional undoname = "nul", Optional units = cdrMillimeter, Optional undogroup = True, Optional optimize = True, Optional sett = "before")
  243. ActiveDocument.SaveSettings sett
  244. ActiveDocument.Unit = units
  245. If undogroup Then ActiveDocument.BeginCommandGroup undoname
  246. Application.Optimization = optimize
  247. EventsEnabled = Not optimize
  248. End Sub
  249. Public Sub end_func(Optional undogroup = True, Optional sett = "before")
  250. cure_app undogroup
  251. ActiveDocument.RestoreSettings sett
  252. End Sub
  253. Sub cure_app(Optional undogroup = True)
  254. EventsEnabled = True
  255. Application.Optimization = False
  256. Application.Refresh
  257. DoEvents
  258. If undogroup Then ActiveDocument.EndCommandGroup
  259. End Sub
  260. Public Function collect_arr(arr, ci, ki)
  261. lim = UBound(arr)
  262. For k = 1 To lim
  263. If arr(ki, k) > 0 Then
  264. arr(ci, k) = k
  265. If ki <> ci Then arr(ki, k) = Empty
  266. If ci <> k And ki <> k Then arr = collect_arr(arr, ci, k)
  267. End If
  268. Next k
  269. 'If ki <> ci Then arr(ki, ki) = Empty
  270. collect_arr = arr
  271. End Function
  272. Public Function autogroup(Optional group As String = "group", Optional shft = 0, Optional sss As Shapes = Nothing, Optional undogroup = True) As ShapeRange
  273. Dim sr As ShapeRange, sr_all As ShapeRange, os As ShapeRange
  274. Dim sp As SubPaths
  275. Dim arr()
  276. Dim s As Shape
  277. If sss Is Nothing Then Set os = ActiveSelectionRange Else Set os = sss.All
  278. 'On Error GoTo errn
  279. If ActiveSelection.Shapes.Count > 0 Then
  280. begin_func "autogroup" & group, cdrMillimeter, undogroup
  281. gcnt = os.Shapes.Count
  282. ReDim arr(1 To gcnt, 1 To gcnt)
  283. Set sr_all = ActiveSelectionRange
  284. sr_all.RemoveAll
  285. If group = "group_lines" Then
  286. For i = 1 To gcnt
  287. If shft = 3 Or shft = 13 Or shft = 14 Then
  288. coord = Int(os.Shapes(i).CenterX)
  289. Else
  290. coord = Int(os.Shapes(i).CenterY)
  291. End If
  292. fnd = False
  293. For k = 1 To gcnt
  294. If arr(k, 1) > 0 Then
  295. If arr(k, 2) = coord Then
  296. arr(k, 1) = arr(k, 1) + 1
  297. arr(k, 2 + arr(k, 1)) = i
  298. fnd = True
  299. Exit For
  300. End If
  301. Else
  302. Exit For
  303. End If
  304. Next k
  305. If Not fnd Then
  306. arr(k, 1) = 1
  307. arr(k, 2) = coord
  308. arr(k, 3) = i
  309. End If
  310. Next i
  311. Set sr = ActiveSelectionRange
  312. For i = 1 To gcnt
  313. If arr(i, 1) > 0 Then
  314. sr.RemoveAll
  315. For k = 3 To gcnt
  316. If arr(i, k) > 0 Then sr.Add os.Shapes(arr(i, k))
  317. Next k
  318. If sr.Shapes.Count > 0 Then
  319. sr.CreateSelection
  320. If shft = 13 Then
  321. sr.AlignAndDistribute cdrAlignDistributeHNone, cdrAlignDistributeVDistributeSpacing
  322. ElseIf shft = 14 Then
  323. sr.AlignAndDistribute cdrAlignDistributeHNone, cdrAlignDistributeVDistributeCenter
  324. ElseIf shft = 16 Then
  325. sr.AlignAndDistribute cdrAlignDistributeHDistributeSpacing, cdrAlignDistributeVNone
  326. ElseIf shft = 17 Then
  327. sr.AlignAndDistribute cdrAlignDistributeHDistributeCenter, cdrAlignDistributeVNone
  328. Else
  329. sr.group
  330. End If
  331. sr_all.AddRange sr
  332. End If
  333. End If
  334. Next i
  335. Else
  336. ReDim arr(1 To gcnt, 1 To gcnt)
  337. ActiveDocument.Unit = cdrTenthMicron
  338. sgap = 10
  339. If shft = 2 Or shft = 3 Or shft = 6 Or shft = 7 Then
  340. os.RemoveAll
  341. For Each s In ActiveSelectionRange.Shapes
  342. os.Add ActivePage.SelectShapesFromRectangle(s.LeftX - sgap, s.BottomY - sgap, s.RightX + sgap, s.TopY + sgap, True)
  343. Next s
  344. End If
  345. For i = 1 To os.Shapes.Count
  346. Set s1 = os.Shapes(i)
  347. arr(i, i) = i
  348. For j = 1 To os.Shapes.Count
  349. Set s2 = os.Shapes(j)
  350. If s2.LeftX < s1.RightX + sgap And s2.RightX > s1.LeftX - sgap And s2.BottomY < s1.TopY + sgap And s2.TopY > s1.BottomY - sgap Then
  351. If shft = 1 Or shft = 3 Or shft = 5 Or shft = 7 Then
  352. Set isec = s1.Intersect(s2)
  353. If Not isec Is Nothing Then
  354. arr(i, j) = j
  355. isec.CreateSelection
  356. isec.Delete
  357. End If
  358. Else
  359. arr(i, j) = j
  360. End If
  361. End If
  362. Next j
  363. Next i
  364. For i = 1 To gcnt
  365. arr = collect_arr(arr, i, i)
  366. Next i
  367. Set sr = ActiveSelectionRange
  368. For i = 1 To gcnt
  369. sr.RemoveAll
  370. inar = 0
  371. For j = 1 To gcnt
  372. If arr(i, j) > 0 Then
  373. sr.Add os.Shapes(j)
  374. inar = inar + 1
  375. End If
  376. Next j
  377. If inar > 1 Then
  378. If group = "group" Then
  379. If shft < 4 Then sr_all.Add sr.group
  380. Else
  381. If group = "front" Then
  382. sr.Sort "@shape1.com.zOrder > @shape2.com.zOrder"
  383. ElseIf group = "back" Then
  384. sr.Sort "@shape1.com.zOrder < @shape2.com.zOrder"
  385. Else
  386. sr.Sort "@shape1.width*@shape1.height < @shape2.width*@shape2.height"
  387. End If
  388. Set fs = sr.FirstShape
  389. Set ls = sr.LastShape
  390. For Each s In sr.Shapes
  391. If Not s Is ls And Not s Is fs Then
  392. If group = "autocut" Then
  393. Set isec = ls.Intersect(s)
  394. If Not isec Is Nothing Then
  395. If isec.Curve.Area = s.Curve.Area Then
  396. Set ls = fs.Trim(ls, False)
  397. Else
  398. Set ls = fs.Weld(ls, False)
  399. End If
  400. isec.Delete
  401. End If
  402. Else
  403. Set fs = s.Weld(fs, False, False)
  404. End If
  405. End If
  406. Next s
  407. If group = "weld" Then
  408. Set ls = fs.Weld(ls, False)
  409. Else
  410. Set ls = fs.Trim(ls, False)
  411. End If
  412. sr_all.Add ls
  413. End If
  414. Else
  415. If sr.Shapes.Count > 0 Then sr_all.AddRange sr
  416. End If
  417. Next i
  418. End If
  419. Set autogroup = sr_all
  420. End If
  421. errn:
  422. end_func undogroup
  423. End Function
  424. Sub auto_cut()
  425. autogroup("autocut").CreateSelection
  426. End Sub
  427. Sub auto_big_small()
  428. autogroup("big").CreateSelection
  429. End Sub
  430. Sub auto_group()
  431. autogroup.CreateSelection
  432. End Sub
  433. Sub auto_weld()
  434. autogroup("weld").CreateSelection
  435. End Sub
  436. Sub auto_group_lines()
  437. autogroup("group_lines", 6).CreateSelection
  438. End Sub
  439. Sub auto_group_columns()
  440. autogroup("group_lines", 3).CreateSelection
  441. End Sub