1
1

Tools.bas 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. Attribute VB_Name = "Tools"
  2. Public Function 分分合合()
  3. 拼版裁切线.arrange
  4. CQL查找相同.CQLline_CM100
  5. 拼版裁切线.Cut_lines
  6. ' 记忆选择范围
  7. Dim X As Double, Y As Double, w As Double, h As Double
  8. ActiveSelectionRange.GetBoundingBox X, Y, w, h
  9. Set s = ActivePage.SelectShapesFromRectangle(X, Y, w, h, True)
  10. 自动中线色阶条.Auto_ColorMark
  11. End Function
  12. Public Function 傻瓜火车排列(space_width As Double)
  13. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  14. ActiveDocument.Unit = cdrMillimeter
  15. Dim ssr As ShapeRange, s As Shape
  16. Dim cnt As Integer
  17. Set ssr = ActiveSelectionRange
  18. cnt = 1
  19. #If VBA7 Then
  20. ' ssr.sort " @shape1.top>@shape2.top"
  21. ssr.Sort " @shape1.left<@shape2.left"
  22. #Else
  23. ' X4 不支持 ShapeRange.sort
  24. #End If
  25. ActiveDocument.ReferencePoint = cdrTopLeft
  26. For Each s In ssr
  27. '' 底对齐 If cnt > 1 Then s.SetPosition ssr(cnt - 1).RightX, ssr(cnt - 1).BottomY
  28. '' 改成顶对齐 2022-08-10
  29. ActiveDocument.ReferencePoint = cdrTopLeft + cdrBottomTop
  30. If cnt > 1 Then s.SetPosition ssr(cnt - 1).RightX + space_width, ssr(cnt - 1).TopY
  31. cnt = cnt + 1
  32. Next s
  33. ActiveDocument.EndCommandGroup
  34. Application.Optimization = False
  35. ActiveWindow.Refresh: Application.Refresh
  36. End Function
  37. Public Function 傻瓜阶梯排列(space_width As Double)
  38. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  39. Dim ssr As ShapeRange, s As Shape
  40. Dim cnt As Integer
  41. Set ssr = ActiveSelectionRange
  42. cnt = 1
  43. #If VBA7 Then
  44. ssr.Sort " @shape1.top>@shape2.top"
  45. ' ssr.sort " @shape1.left<@shape2.left"
  46. #Else
  47. ' X4 不支持 ShapeRange.sort
  48. #End If
  49. ActiveDocument.ReferencePoint = cdrTopLeft
  50. For Each s In ssr
  51. If cnt > 1 Then s.SetPosition ssr(cnt - 1).LeftX, ssr(cnt - 1).BottomY - space_width
  52. cnt = cnt + 1
  53. Next s
  54. ActiveDocument.EndCommandGroup
  55. Application.Optimization = False
  56. ActiveWindow.Refresh: Application.Refresh
  57. End Function
  58. '// 文本转曲线
  59. Public Function TextShape_ConvertToCurves()
  60. On Error GoTo ErrorHandler
  61. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  62. Dim s As Shape, cnt As Long
  63. For Each s In API.FindAllShapes.Shapes.FindShapes(, cdrTextShape)
  64. s.ConvertToCurves
  65. cnt = cnt + 1
  66. Next s
  67. MsgBox "转曲物件统计: " & cnt, , "文本转曲线"
  68. ActiveDocument.EndCommandGroup
  69. Application.Optimization = False
  70. ActiveWindow.Refresh: Application.Refresh
  71. Exit Function
  72. ErrorHandler:
  73. Application.Optimization = False
  74. On Error Resume Next
  75. End Function
  76. '' 复制物件
  77. Public Function copy_shape()
  78. Dim OrigSelection As ShapeRange
  79. Set OrigSelection = ActiveSelectionRange
  80. OrigSelection.Copy
  81. End Function
  82. '' 旋转物件角度
  83. Public Function Rotate_Shapes(n As Double)
  84. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  85. ActiveDocument.Unit = cdrMillimeter
  86. Dim sh As Shape, shs As Shapes
  87. Set shs = ActiveSelection.Shapes
  88. Dim s As String, size As String
  89. For Each sh In shs
  90. sh.Rotate n
  91. Next sh
  92. ActiveDocument.EndCommandGroup
  93. Application.Optimization = False
  94. ActiveWindow.Refresh: Application.Refresh
  95. End Function
  96. '' 得到物件尺寸
  97. Public Function get_shape_size(ByRef sx As Double, ByRef sy As Double)
  98. ActiveDocument.Unit = cdrMillimeter
  99. Dim sh As ShapeRange
  100. Set sh = ActiveSelectionRange
  101. sx = sh.SizeWidth
  102. sy = sh.SizeHeight
  103. sx = Int(sx * 100 + 0.5) / 100
  104. sy = Int(sy * 100 + 0.5) / 100
  105. End Function
  106. '' 批量设置物件尺寸
  107. Public Function Set_Shapes_size(ByRef sx As Double, ByRef sy As Double)
  108. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  109. ActiveDocument.Unit = cdrMillimeter
  110. ActiveDocument.ReferencePoint = cdrCenter
  111. Dim sh As Shape, shs As Shapes
  112. Set shs = ActiveSelection.Shapes
  113. Dim s As String, size As String
  114. For Each sh In shs
  115. sh.SizeWidth = sx
  116. sh.SizeHeight = sy
  117. Next sh
  118. ActiveDocument.EndCommandGroup
  119. Application.Optimization = False
  120. ActiveWindow.Refresh: Application.Refresh
  121. End Function
  122. Public Function 尺寸取整()
  123. If 0 = ActiveSelectionRange.Count Then Exit Function
  124. ActiveDocument.Unit = cdrMillimeter
  125. ' 修改变形尺寸基准
  126. ActiveDocument.ReferencePoint = cdrCenter
  127. Dim sh As Shape, shs As Shapes
  128. Set shs = ActiveSelection.Shapes
  129. Dim s As String, size As String
  130. For Each sh In shs
  131. size = Int(sh.SizeWidth + 0.5) & "x" & Int(sh.SizeHeight + 0.5) & "mm"
  132. sh.SetSize Int(sh.SizeWidth + 0.5), Int(sh.SizeHeight + 0.5)
  133. s = s & size & vbNewLine
  134. Next sh
  135. MsgBox "物件尺寸信息到剪贴板" & vbNewLine & s & vbNewLine
  136. API.WriteClipBoard s
  137. End Function
  138. Public Function 居中页面()
  139. If 0 = ActiveSelectionRange.Count Then Exit Function
  140. ' 实践应用: 选择物件群组,页面设置物件大小,物件页面居中
  141. ActiveDocument.Unit = cdrMillimeter
  142. Dim OrigSelection As ShapeRange, sh As Shape
  143. Set OrigSelection = ActiveSelectionRange
  144. Set sh = OrigSelection.group
  145. ActivePage.SetSize Int(sh.SizeWidth + 0.9), Int(sh.SizeHeight + 0.9)
  146. #If VBA7 Then
  147. ActiveDocument.ClearSelection
  148. sh.AddToSelection
  149. ActiveSelection.AlignAndDistribute 3, 3, 2, 0, False, 2
  150. #Else
  151. sh.AlignToPageCenter cdrAlignHCenter + cdrAlignVCenter
  152. #End If
  153. End Function
  154. '''/// 使用Python脚本 整理尺寸 提取条码数字 建立二维码 位图转文本 ///'''
  155. Public Function Python_Organize_Size()
  156. mypy = Path & "GMS\262235.xyz\Organize_Size.py"
  157. cmd_line = "pythonw " & Chr(34) & mypy & Chr(34)
  158. Shell cmd_line
  159. End Function
  160. Public Function Python_Get_Barcode_Number()
  161. mypy = Path & "GMS\262235.xyz\Get_Barcode_Number.py"
  162. cmd_line = "pythonw " & Chr(34) & mypy & Chr(34)
  163. Shell cmd_line
  164. End Function
  165. Public Function Python_BITMAP()
  166. mypy = Path & "GMS\262235.xyz\BITMAP.py"
  167. cmd_line = "pythonw " & Chr(34) & mypy & Chr(34)
  168. Shell cmd_line
  169. End Function
  170. Public Function Python_BITMAP2()
  171. Bitmap = "C:\TSP\BITMAP.exe"
  172. Shell Bitmap
  173. End Function
  174. Public Function Python_Make_QRCode()
  175. mypy = Path & "GMS\262235.xyz\Make_QRCode.py"
  176. cmd_line = "pythonw " & Chr(34) & mypy & Chr(34)
  177. Shell cmd_line
  178. End Function
  179. '' QRCode二维码制作
  180. Public Function QRCode_replace()
  181. On Error GoTo ErrorHandler
  182. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  183. Dim image_path As String
  184. image_path = API.GetClipBoardString
  185. ActiveDocument.ReferencePoint = cdrCenter
  186. Dim sh As Shape, shs As Shapes, cs As Shape
  187. Dim X As Double, Y As Double
  188. Set shs = ActiveSelection.Shapes
  189. cnt = 0
  190. For Each sh In shs
  191. If cnt = 0 Then
  192. ActiveDocument.ClearSelection
  193. ActiveLayer.Import image_path
  194. Set sc = ActiveSelection
  195. cnt = 1
  196. Else
  197. sc.Duplicate 0, 0
  198. End If
  199. sh.GetPosition X, Y
  200. sc.SetPosition X, Y
  201. sh.GetSize X, Y
  202. sc.SetSize X, Y
  203. sh.Delete
  204. Next sh
  205. '// 代码操作结束恢复窗口刷新
  206. ActiveDocument.EndCommandGroup
  207. Application.Optimization = False
  208. ActiveWindow.Refresh: Application.Refresh
  209. Exit Function
  210. ErrorHandler:
  211. Application.Optimization = False
  212. On Error Resume Next
  213. End Function
  214. '' QRCode二维码转矢量图
  215. Public Function QRCode_to_Vector()
  216. On Error GoTo ErrorHandler
  217. Set sr = ActiveSelectionRange
  218. With sr(1).Bitmap.Trace(cdrTraceHighQualityImage)
  219. .TraceType = cdrTraceHighQualityImage
  220. .Smoothing = 50 '数值小则平滑,数值大则细节多
  221. .RemoveBackground = False
  222. .DeleteOriginalObject = True
  223. .Finish
  224. End With
  225. Exit Function
  226. ErrorHandler:
  227. On Error Resume Next
  228. End Function
  229. '''//// 选择多物件,组合然后拆分线段,为角线爬虫准备 ////'''
  230. Public Function Split_Segment()
  231. On Error GoTo ErrorHandler
  232. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  233. Dim ssr As ShapeRange
  234. Set ssr = ActiveSelectionRange
  235. Dim s As Shape
  236. Dim nr As NodeRange
  237. Dim nd As Node
  238. Set s = ssr.UngroupAllEx.Combine
  239. Set nr = s.Curve.Nodes.All
  240. nr.BreakApart
  241. s.BreakApartEx
  242. ' For Each nd In nr
  243. ' nd.BreakApart
  244. ' Next nd
  245. ActiveDocument.EndCommandGroup
  246. Application.Optimization = False
  247. ActiveWindow.Refresh: Application.Refresh
  248. Exit Function
  249. ErrorHandler:
  250. Application.Optimization = False
  251. On Error Resume Next
  252. End Function
  253. '''//// 标记画框 支持容差 ////'''
  254. Public Function Mark_CreateRectangle(expand As Boolean)
  255. On Error GoTo ErrorHandler
  256. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  257. ActiveDocument.Unit = cdrMillimeter
  258. ActiveDocument.ReferencePoint = cdrBottomLeft
  259. Dim ssr As ShapeRange
  260. Set ssr = ActiveSelectionRange
  261. Dim sh As Shape
  262. Dim tr As Double
  263. tr = 0
  264. If GlobalUserData.Exists("Tolerance", 1) Then
  265. tr = Val(GlobalUserData("Tolerance", 1))
  266. End If
  267. For Each sh In ssr
  268. If expand = False Then
  269. mark_shape sh
  270. Else
  271. mark_shape_expand sh, tr
  272. End If
  273. Next sh
  274. ActiveDocument.EndCommandGroup
  275. Application.Optimization = False
  276. ActiveWindow.Refresh: Application.Refresh
  277. Exit Function
  278. ErrorHandler:
  279. Application.Optimization = False
  280. On Error Resume Next
  281. End Function
  282. Private Function mark_shape_expand(sh As Shape, tr As Double)
  283. Dim s As Shape
  284. Dim X As Double, Y As Double, w As Double, h As Double, r As Double
  285. sh.GetBoundingBox X, Y, w, h
  286. X = X - tr: Y = Y - tr: w = w + 2 * tr: h = h + 2 * tr
  287. r = Max(w, h) / Min(w, h) / 30 * Math.Sqr(w * h)
  288. If w < h Then
  289. Set s = ActiveLayer.CreateRectangle2(X - r, Y, w + 2 * r, h)
  290. Else
  291. Set s = ActiveLayer.CreateRectangle2(X, Y - r, w, h + 2 * r)
  292. End If
  293. s.Outline.SetProperties Color:=CreateRGBColor(0, 255, 0)
  294. End Function
  295. Private Function mark_shape(sh As Shape)
  296. Dim s As Shape
  297. Dim X As Double, Y As Double, w As Double, h As Double
  298. sh.GetBoundingBox X, Y, w, h, True
  299. Set s = ActiveLayer.CreateRectangle2(X, Y, w, h)
  300. s.Outline.SetProperties Color:=CreateRGBColor(0, 255, 0)
  301. End Function
  302. Private Function Max(ByVal a, ByVal b)
  303. If a < b Then
  304. a = b
  305. End If
  306. Max = a
  307. End Function
  308. Private Function Min(ByVal a, ByVal b)
  309. If a > b Then
  310. a = b
  311. End If
  312. Min = a
  313. End Function
  314. '''//// 批量组合合并 ////'''
  315. Public Function Batch_Combine()
  316. On Error GoTo ErrorHandler
  317. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  318. Dim ssr As ShapeRange
  319. Set ssr = ActiveSelectionRange
  320. Dim sh As Shape
  321. For Each sh In ssr
  322. sh.UngroupAllEx.Combine
  323. Next sh
  324. ActiveDocument.EndCommandGroup
  325. Application.Optimization = False
  326. ActiveWindow.Refresh: Application.Refresh
  327. Exit Function
  328. ErrorHandler:
  329. Application.Optimization = False
  330. On Error Resume Next
  331. End Function
  332. '''//// 一键拆开多行组合的文字字符 ////''' ''' 本功能由群友半缘君赞助发行 '''
  333. Public Function Take_Apart_Character()
  334. On Error GoTo ErrorHandler
  335. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  336. ActiveDocument.Unit = cdrMillimeter
  337. ActiveDocument.ReferencePoint = cdrBottomLeft
  338. Dim ssr As ShapeRange
  339. Set ssr = ActiveSelectionRange
  340. Dim s1 As Shape, sh As Shape, s As Shape
  341. Dim tr As Double
  342. ' 记忆选择范围
  343. Dim X As Double, Y As Double, w As Double, h As Double
  344. ssr.GetBoundingBox X, Y, w, h
  345. Set s1 = ActiveLayer.CreateRectangle2(X, Y, w, h)
  346. ' 解散群组,先组合,再散开
  347. Set s = ssr.UngroupAllEx.Combine
  348. Set ssr = s.BreakApartEx
  349. ' 读取容差值
  350. tr = 0
  351. If GlobalUserData.Exists("Tolerance", 1) Then
  352. tr = Val(GlobalUserData("Tolerance", 1))
  353. End If
  354. ' 标记画框,选择标记框
  355. For Each sh In ssr
  356. mark_shape_expand sh, tr
  357. Next sh
  358. Set ssr = ActivePage.Shapes.FindShapes(query:="@colors.find(RGB(0, 255, 0))")
  359. ActiveDocument.ClearSelection
  360. ssr.AddToSelection
  361. ' 调用 智能群组 后删除标记画框
  362. 智能群组和查找.智能群组
  363. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  364. ssr.Delete
  365. Set sh = ActivePage.SelectShapesFromRectangle(s1.LeftX, s1.TopY, s1.RightX, s1.BottomY, False)
  366. ' sh.Shapes.All.Group
  367. s1.Delete
  368. ' 通过s1矩形范围选择群组后合并组合
  369. For Each s In sh.Shapes
  370. s.UngroupAllEx.Combine
  371. Next s
  372. ActiveDocument.EndCommandGroup
  373. Application.Optimization = False
  374. ActiveWindow.Refresh: Application.Refresh
  375. Exit Function
  376. ErrorHandler:
  377. Application.Optimization = False
  378. On Error Resume Next
  379. End Function
  380. '''//// 简单一刀切 识别群组 ////''' ''' 本功能由群友宏瑞广告赞助发行 '''
  381. Public Function Single_Line()
  382. If 0 = ActiveSelectionRange.Count Then Exit Function
  383. On Error GoTo ErrorHandler
  384. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  385. ActiveDocument.Unit = cdrMillimeter
  386. Dim cm(2) As Color
  387. Set cm(0) = CreateRGBColor(0, 255, 0) ' RGB 绿
  388. Set cm(1) = CreateRGBColor(255, 0, 0) ' RGB 红
  389. Dim ssr As ShapeRange
  390. Dim SrNew As New ShapeRange
  391. Dim s As Shape, s1 As Shape, line As Shape, line2 As Shape
  392. Dim cnt As Integer
  393. cnt = 1
  394. If 1 = ActiveSelectionRange.Count Then
  395. Set ssr = ActiveSelectionRange(1).UngroupAllEx
  396. Else
  397. Set ssr = ActiveSelectionRange
  398. End If
  399. ' 记忆选择范围
  400. Dim X As Double, Y As Double, w As Double, h As Double
  401. ssr.GetBoundingBox X, Y, w, h
  402. Set s1 = ActiveLayer.CreateRectangle2(X, Y, w, h)
  403. s1.Outline.SetProperties Color:=cm(0)
  404. SrNew.Add s1
  405. #If VBA7 Then
  406. ' ssr.sort " @shape1.top>@shape2.top"
  407. ssr.Sort " @shape1.left<@shape2.left"
  408. #Else
  409. ' X4 不支持 ShapeRange.sort
  410. #End If
  411. ''' 相交 Set line2 = line.Intersect(s, True, True)
  412. ''' 判断相交 line.Curve.IntersectsWith(s.Curve)
  413. For Each s In ssr
  414. If cnt > 1 Then
  415. s.ConvertToCurves
  416. Set line = ActiveLayer.CreateLineSegment(s.LeftX, s.TopY, s.LeftX, s.TopY - s.SizeHeight)
  417. line.Outline.SetProperties Color:=cm(1)
  418. SrNew.Add line
  419. End If
  420. cnt = cnt + 1
  421. Next s
  422. SrNew.group
  423. ActiveDocument.EndCommandGroup
  424. Application.Optimization = False
  425. ActiveWindow.Refresh: Application.Refresh
  426. Exit Function
  427. ErrorHandler:
  428. Application.Optimization = False
  429. On Error Resume Next
  430. End Function
  431. Public Function Single_Line_Vertical()
  432. If 0 = ActiveSelectionRange.Count Then Exit Function
  433. On Error GoTo ErrorHandler
  434. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  435. ActiveDocument.Unit = cdrMillimeter
  436. Dim cm(2) As Color
  437. Set cm(0) = CreateRGBColor(0, 255, 0) ' RGB 绿
  438. Set cm(1) = CreateRGBColor(255, 0, 0) ' RGB 红
  439. Dim ssr As ShapeRange
  440. Dim SrNew As New ShapeRange
  441. Dim s As Shape, s1 As Shape, line As Shape, line2 As Shape
  442. Dim cnt As Integer
  443. cnt = 1
  444. If 1 = ActiveSelectionRange.Count Then
  445. Set ssr = ActiveSelectionRange(1).UngroupAllEx
  446. Else
  447. Set ssr = ActiveSelectionRange
  448. End If
  449. ' 记忆选择范围
  450. Dim X As Double, Y As Double, w As Double, h As Double
  451. ssr.GetBoundingBox X, Y, w, h
  452. Set s1 = ActiveLayer.CreateRectangle2(X, Y, w, h)
  453. s1.Outline.SetProperties Color:=cm(0)
  454. SrNew.Add s1
  455. #If VBA7 Then
  456. ssr.Sort " @shape1.top>@shape2.top"
  457. #Else
  458. ' X4 不支持 ShapeRange.sort
  459. #End If
  460. For Each s In ssr
  461. If cnt > 1 Then
  462. s.ConvertToCurves
  463. Set line = ActiveLayer.CreateLineSegment(s.LeftX, s.TopY, s.RightX, s.TopY)
  464. line.Outline.SetProperties Color:=cm(1)
  465. SrNew.Add line
  466. End If
  467. cnt = cnt + 1
  468. Next s
  469. SrNew.group
  470. ActiveDocument.EndCommandGroup
  471. Application.Optimization = False
  472. ActiveWindow.Refresh: Application.Refresh
  473. Exit Function
  474. ErrorHandler:
  475. Application.Optimization = False
  476. On Error Resume Next
  477. End Function
  478. Public Function Single_Line_LastNode()
  479. If 0 = ActiveSelectionRange.Count Then Exit Function
  480. On Error GoTo ErrorHandler
  481. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  482. ActiveDocument.Unit = cdrMillimeter
  483. Dim cm(2) As Color
  484. Set cm(0) = CreateRGBColor(0, 255, 0) ' RGB 绿
  485. Set cm(1) = CreateRGBColor(255, 0, 0) ' RGB 红
  486. Dim ssr As ShapeRange
  487. Dim SrNew As New ShapeRange
  488. Dim s As Shape, s1 As Shape, line As Shape, line2 As Shape
  489. Dim cnt As Integer
  490. cnt = 1
  491. If 1 = ActiveSelectionRange.Count Then
  492. Set ssr = ActiveSelectionRange(1).UngroupAllEx
  493. Else
  494. Set ssr = ActiveSelectionRange
  495. End If
  496. ' 记忆选择范围
  497. Dim X As Double, Y As Double, w As Double, h As Double
  498. ssr.GetBoundingBox X, Y, w, h
  499. Set s1 = ActiveLayer.CreateRectangle2(X, Y, w, h)
  500. s1.Outline.SetProperties Color:=cm(0)
  501. SrNew.Add s1
  502. #If VBA7 Then
  503. ssr.Sort " @shape1.left<@shape2.left"
  504. #Else
  505. ' X4 不支持 ShapeRange.sort
  506. #End If
  507. Dim nr As NodeRange
  508. For Each s In ssr
  509. If cnt > 1 Then
  510. Set nr = s.DisplayCurve.Nodes.All
  511. Set line = ActiveLayer.CreateLineSegment(nr.FirstNode.PositionX, nr.FirstNode.PositionY, nr.LastNode.PositionX, nr.LastNode.PositionY)
  512. line.Outline.SetProperties Color:=cm(1)
  513. SrNew.Add line
  514. End If
  515. cnt = cnt + 1
  516. Next s
  517. SrNew.group
  518. ActiveDocument.EndCommandGroup
  519. Application.Optimization = False
  520. ActiveWindow.Refresh: Application.Refresh
  521. Exit Function
  522. ErrorHandler:
  523. Application.Optimization = False
  524. On Error Resume Next
  525. End Function
  526. '''//// 选择范围画框 ////'''
  527. Public Function Mark_Range_Box()
  528. If 0 = ActiveSelectionRange.Count Then Exit Function
  529. ActiveDocument.Unit = cdrMillimeter
  530. Dim s1 As Shape, ssr As ShapeRange
  531. Set ssr = ActiveSelectionRange
  532. Dim X As Double, Y As Double, w As Double, h As Double
  533. ssr.GetBoundingBox X, Y, w, h
  534. Set s1 = ActiveLayer.CreateRectangle2(X, Y, w, h)
  535. s1.Outline.SetProperties Color:=CreateRGBColor(0, 255, 0) ' RGB 绿
  536. End Function
  537. '''//// 快速颜色选择 ////'''
  538. Function quickColorSelect()
  539. Dim X As Double, Y As Double
  540. Dim s As Shape, s1 As Shape
  541. Dim sr As ShapeRange, sr2 As ShapeRange
  542. Dim Shift As Long, bClick As Boolean
  543. Dim c As New Color, c2 As New Color
  544. EventsEnabled = False
  545. Set sr = ActivePage.Shapes.FindShapes(query:="@fill.type = 'uniform'")
  546. ActiveDocument.ClearSelection
  547. bClick = False
  548. While Not bClick
  549. On Error Resume Next
  550. bClick = ActiveDocument.GetUserClick(X, Y, Shift, 10, False, cdrCursorPickNone)
  551. If Not bClick Then
  552. Set s = ActivePage.SelectShapesAtPoint(X, Y, False)
  553. Set s = s.Shapes.Last
  554. c2.CopyAssign s.Fill.UniformColor
  555. Set sr2 = New ShapeRange
  556. For Each s1 In sr.Shapes
  557. c.CopyAssign s1.Fill.UniformColor
  558. If c.IsSame(c2) Then
  559. sr2.Add s1
  560. End If
  561. Next s1
  562. sr2.CreateSelection
  563. ActiveWindow.Refresh
  564. End If
  565. Wend
  566. EventsEnabled = True
  567. End Function
  568. '''//// 切割图形-垂直分割-水平分割 ////'''
  569. Function divideVertically()
  570. If 0 = ActiveSelectionRange.Count Then Exit Function
  571. On Error GoTo ErrorHandler
  572. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  573. cutInHalf 1
  574. ActiveDocument.EndCommandGroup
  575. Application.Optimization = False
  576. ActiveWindow.Refresh: Application.Refresh
  577. Exit Function
  578. ErrorHandler:
  579. Application.Optimization = False
  580. On Error Resume Next
  581. End Function
  582. Function divideHorizontally()
  583. If 0 = ActiveSelectionRange.Count Then Exit Function
  584. On Error GoTo ErrorHandler
  585. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  586. cutInHalf 2
  587. ActiveDocument.EndCommandGroup
  588. Application.Optimization = False
  589. ActiveWindow.Refresh: Application.Refresh
  590. Exit Function
  591. ErrorHandler:
  592. Application.Optimization = False
  593. On Error Resume Next
  594. End Function
  595. Private Function cutInHalf(Optional method As Integer)
  596. Dim s As Shape, rect As Shape, rect2 As Shape
  597. Dim trimmed1 As Shape, trimmed2 As Shape
  598. Dim X As Double, Y As Double, w As Double, h As Double
  599. Dim vBool As Boolean
  600. Dim leeway As Double
  601. Dim sr As ShapeRange, sr2 As New ShapeRange
  602. vBool = True
  603. If method = 2 Then
  604. vBool = False
  605. End If
  606. leeway = 0.1
  607. Set sr = ActiveSelectionRange
  608. ActiveDocument.BeginCommandGroup "Cut in half"
  609. For Each s In sr
  610. s.GetBoundingBox X, Y, w, h
  611. If (vBool) Then
  612. 'vertical slice
  613. Set rect = ActiveLayer.CreateRectangle2(X - leeway, Y - leeway, (w / 2) + leeway, h + (leeway * 2))
  614. Set rect2 = ActiveLayer.CreateRectangle2(X + (w / 2), Y - leeway, (w / 2) + leeway, h + (leeway * 2))
  615. Else
  616. Set rect = ActiveLayer.CreateRectangle2(X - leeway, Y - leeway, w + (leeway * 2), (h / 2) + leeway)
  617. Set rect2 = ActiveLayer.CreateRectangle2(X - leeway, Y + (h / 2), w + (leeway * 2), (h / 2) + leeway)
  618. End If
  619. Set trimmed1 = rect.Intersect(s, True, True)
  620. rect.Delete
  621. Set trimmed2 = rect2.Intersect(s, True, True)
  622. s.Delete
  623. rect2.Delete
  624. sr2.Add trimmed1
  625. sr2.Add trimmed2
  626. Next s
  627. ActiveDocument.EndCommandGroup
  628. sr2.CreateSelection
  629. End Function
  630. '// 批量多页居中-遍历批量物件,放置物件到页面
  631. Public Function 批量多页居中()
  632. If 0 = ActiveSelectionRange.Count Then Exit Function
  633. On Error GoTo ErrorHandler
  634. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  635. ActiveDocument.Unit = cdrMillimeter
  636. Set sr = ActiveSelectionRange
  637. total = sr.Count
  638. '// 建立多页面
  639. Set doc = ActiveDocument
  640. doc.AddPages (total - 1)
  641. #If VBA7 Then
  642. sr.Sort " @shape1.Top * 100 - @shape1.Left > @shape2.Top * 100 - @shape2.Left"
  643. #Else
  644. ' X4 不支持 ShapeRange.sort
  645. #End If
  646. Dim sh As Shape
  647. '// 遍历批量物件,放置物件到页面
  648. For i = 1 To sr.Count
  649. doc.Pages(i).Activate
  650. Set sh = sr.Shapes(i)
  651. ActivePage.SetSize Int(sh.SizeWidth + 0.9), Int(sh.SizeHeight + 0.9)
  652. '// 物件居中页面
  653. #If VBA7 Then
  654. ActiveDocument.ClearSelection
  655. sh.AddToSelection
  656. ActiveSelection.AlignAndDistribute 3, 3, 2, 0, False, 2
  657. #Else
  658. sh.AlignToPageCenter cdrAlignHCenter + cdrAlignVCenter
  659. #End If
  660. Next i
  661. ActiveDocument.EndCommandGroup: Application.Optimization = False
  662. ActiveWindow.Refresh: Application.Refresh
  663. Exit Function
  664. ErrorHandler:
  665. Application.Optimization = False
  666. MsgBox "请先选择一些物件"
  667. On Error Resume Next
  668. End Function
  669. '// 安全线: 点击一次建立辅助线,再调用清除参考线
  670. Public Function guideangle(actnumber As ShapeRange, cardblood As Integer)
  671. Dim sr As ShapeRange
  672. Set sr = ActiveDocument.MasterPage.GuidesLayer.FindShapes(Type:=cdrGuidelineShape)
  673. If sr.Count <> 0 Then
  674. sr.Delete
  675. Exit Function
  676. End If
  677. If 0 = ActiveSelectionRange.Count Then Exit Function
  678. ActiveDocument.Unit = cdrMillimeter
  679. With actnumber
  680. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(0, .TopY - cardblood, 0#)
  681. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(0, .BottomY + cardblood, 0#)
  682. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(.LeftX + cardblood, 0, 90#)
  683. Set s1 = ActiveDocument.MasterPage.GuidesLayer.CreateGuideAngle(.RightX - cardblood, 0, 90#)
  684. End With
  685. End Function
  686. '// 标注尺寸 批量简单标注数字
  687. Public Function Simple_Label_Numbers()
  688. ActiveDocument.Unit = cdrMillimeter
  689. Set sr = ActiveSelectionRange
  690. For Each s In sr.Shapes
  691. X = s.CenterX: Y = s.TopY
  692. sw = s.SizeWidth: sh = s.SizeHeight
  693. text = Int(sw + 0.5) & "x" & Int(sh + 0.5) & "mm"
  694. Set s = ActiveLayer.CreateArtisticText(0, 0, text)
  695. s.CenterX = X: s.BottomY = Y + 5
  696. Next
  697. End Function
  698. '// 修复圆角缺角到直角
  699. Public Sub corner_off()
  700. Dim os As ShapeRange
  701. Dim s As Shape, fir As Shape, ci As Shape
  702. Dim nd As Node, nds As Node, nde As Node
  703. Set os = ActiveSelectionRange
  704. ud = ActiveDocument.Unit
  705. ActiveDocument.Unit = cdrMillimeter
  706. On Error GoTo errn
  707. ActiveDocument.BeginCommandGroup "corners off"
  708. Application.Optimization = True
  709. selec = False
  710. If os.Shapes.Count = 1 Then
  711. Set s = os.FirstShape
  712. If Not s.Curve Is Nothing Then
  713. For Each nd In s.Curve.Nodes
  714. If nd.Selected Then
  715. selec = True
  716. Exit For
  717. End If
  718. Next nd
  719. End If
  720. End If
  721. If os.Shapes.Count > 1 Or Not selec Then
  722. os.ConvertToCurves
  723. For Each s In os.Shapes
  724. Set nds = Nothing
  725. Set nde = Nothing
  726. For k = 1 To 3
  727. For i = 1 To s.Curve.Nodes.Count
  728. If i <= s.Curve.Nodes.Count Then
  729. Set nd = s.Curve.Nodes(i)
  730. If Not nd.NextSegment Is Nothing And Not nd.PrevSegment Is Nothing Then
  731. If Abs(nd.PrevSegment.Length - nd.NextSegment.Length) < (nd.PrevSegment.Length + nd.NextSegment.Length) / 30 And nd.PrevSegment.Type = cdrCurveSegment And nd.NextSegment.Type = cdrCurveSegment Then
  732. corner_off_make s, nd.Previous, nd.Next
  733. ElseIf Not nd.Next.NextSegment Is Nothing Then
  734. If (nd.PrevSegment.Type = cdrLineSegment Or Abs(Abs(nd.PrevSegment.StartingControlPointAngle - nd.PrevSegment.EndingControlPointAngle) - 180) < 1) _
  735. And (nd.Next.NextSegment.Type = cdrLineSegment Or Abs(Abs(nd.Next.NextSegment.StartingControlPointAngle - nd.Next.NextSegment.EndingControlPointAngle) - 180) < 1) _
  736. And nd.NextSegment.Type = cdrCurveSegment Then
  737. corner_off_make s, nd, nd.Next
  738. End If
  739. End If
  740. End If
  741. End If
  742. Next i
  743. Next k
  744. Next s
  745. ElseIf os.Shapes.Count = 1 And selec Then
  746. Set nds = Nothing
  747. Set nde = Nothing
  748. For Each nd In s.Curve.Nodes
  749. If Not nd.Selected And Not nd.Next.Selected Then Exit For
  750. Next nd
  751. If Not nd Is s.Curve.Nodes.Last Then
  752. For i = 1 To s.Curve.Nodes.Count
  753. Set nd = nd.Next
  754. If Not nde Is Nothing And Not nds Is Nothing And Not nd.Selected Then Exit For
  755. If Not nds Is Nothing And nd.Selected Then Set nde = nd
  756. If nde Is Nothing And nds Is Nothing And nd.Selected Then Set nds = nd
  757. Next i
  758. If Not nds Is Nothing And Not nde Is Nothing Then
  759. 'ActiveLayer.CreateEllipse2 nds.PositionX, nds.PositionY, nde.PrevSegment.Length / 4
  760. 'ActiveLayer.CreateEllipse2 nde.PositionX, nde.PositionY, nde.PrevSegment.Length / 4
  761. corner_off_make s, nds, nde
  762. End If
  763. End If
  764. End If
  765. errn:
  766. Application.Optimization = False
  767. ActiveDocument.EndCommandGroup
  768. Application.Refresh
  769. ActiveDocument.Unit = ud
  770. End Sub
  771. Private Sub corner_off_make(s As Shape, nds As Node, nde As Node)
  772. Dim l1 As Shape, l2 As Shape
  773. Dim os As ShapeRange
  774. Dim ss As Shape
  775. ud = ActiveDocument.Unit
  776. ActiveDocument.Unit = cdrMillimeter
  777. Set l1 = ActiveLayer.CreateLineSegment(nds.PositionX, nds.PositionY, nds.PositionX + s.SizeWidth * 3, nds.PositionY)
  778. l1.RotationCenterX = nds.PositionX
  779. l1.RotationAngle = nds.PrevSegment.EndingControlPointAngle + 180
  780. Set l2 = ActiveLayer.CreateLineSegment(nde.PositionX, nde.PositionY, nde.PositionX + s.SizeWidth * 3, nde.PositionY)
  781. l2.RotationCenterX = nde.PositionX
  782. l2.RotationAngle = nde.NextSegment.StartingControlPointAngle + 180
  783. Set lcross = l2.Curve.Segments.First.GetIntersections(l1.Curve.Segments.First)
  784. If lcross.Count > 0 Then
  785. cx = lcross(1).PositionX
  786. cy = lcross(1).PositionY
  787. sx = nds.PositionX
  788. sy = nds.PositionY
  789. ex = nde.PositionX
  790. ey = nde.PositionY
  791. l1.Curve.Nodes.Last.PositionX = cx
  792. l1.Curve.Nodes.Last.PositionY = cy
  793. l2.Curve.Nodes.Last.PositionX = cx
  794. l2.Curve.Nodes.Last.PositionY = cy
  795. s.Curve.Nodes.Range(Array(nds.AbsoluteIndex, nde.AbsoluteIndex)).BreakApart
  796. Set os = s.BreakApartEx
  797. oscnt = os.Shapes.Count
  798. For Each ss In os.Shapes
  799. If ss.Curve.Nodes.First.PositionX = ex And ss.Curve.Nodes.First.PositionY = ey Then Set s2 = ss
  800. If ss.Curve.Nodes.Last.PositionX = sx And ss.Curve.Nodes.Last.PositionY = sy Then Set s1 = ss
  801. If ss.Curve.Nodes.First.PositionX = sx And ss.Curve.Nodes.First.PositionY = sy Then ss.Delete
  802. Next ss
  803. If s1.Curve.Segments.Last.Type = cdrLineSegment Or Abs(Abs(s1.Curve.Segments.Last.StartingControlPointAngle - s1.Curve.Segments.Last.EndingControlPointAngle) - 180) < 1 Then
  804. s1.Curve.Nodes.Last.PositionX = lcross(1).PositionX
  805. s1.Curve.Nodes.Last.PositionY = lcross(1).PositionY
  806. l1.Delete
  807. Else
  808. Set s1 = l1.Weld(s1)
  809. End If
  810. If oscnt = 2 Then Set s2 = s1
  811. If s2.Curve.Segments.First.Type = cdrLineSegment Or Abs(Abs(s2.Curve.Segments.First.StartingControlPointAngle - s2.Curve.Segments.First.EndingControlPointAngle) - 180) < 1 Then
  812. s2.Curve.Nodes.First.PositionX = lcross(1).PositionX
  813. s2.Curve.Nodes.First.PositionY = lcross(1).PositionY
  814. l2.Delete
  815. Else
  816. Set s2 = l2.Weld(s2)
  817. End If
  818. If oscnt > 2 Then Set s2 = s1.Weld(s2)
  819. s2.CustomCommand "ConvertTo", "JoinCurves", 0.1
  820. Set s = s2
  821. Else
  822. l1.Delete
  823. l2.Delete
  824. End If
  825. ActiveDocument.Unit = ud
  826. End Sub
  827. Public Function autogroup(Optional group As String = "group", Optional shft = 0, Optional sss As Shapes = Nothing, Optional undogroup = True) As ShapeRange
  828. Dim sr As ShapeRange, sr_all As ShapeRange, os As ShapeRange
  829. Dim sp As SubPaths
  830. Dim arr()
  831. Dim s As Shape
  832. If sss Is Nothing Then Set os = ActiveSelectionRange Else Set os = sss.All
  833. On Error GoTo errn
  834. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  835. If ActiveSelection.Shapes.Count > 0 Then
  836. gcnt = os.Shapes.Count
  837. ReDim arr(1 To gcnt, 1 To gcnt)
  838. Set sr_all = ActiveSelectionRange
  839. sr_all.RemoveAll
  840. ReDim arr(1 To gcnt, 1 To gcnt)
  841. ActiveDocument.Unit = cdrTenthMicron
  842. sgap = 10
  843. If shft = 2 Or shft = 3 Or shft = 6 Or shft = 7 Then
  844. os.RemoveAll
  845. For Each s In ActiveSelectionRange.Shapes
  846. os.Add ActivePage.SelectShapesFromRectangle(s.LeftX - sgap, s.BottomY - sgap, s.RightX + sgap, s.TopY + sgap, True)
  847. Next s
  848. End If
  849. For i = 1 To os.Shapes.Count
  850. Set s1 = os.Shapes(i)
  851. arr(i, i) = i
  852. For j = 1 To os.Shapes.Count
  853. Set s2 = os.Shapes(j)
  854. 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
  855. If shft = 1 Or shft = 3 Or shft = 5 Or shft = 7 Then
  856. Set isec = s1.Intersect(s2)
  857. If Not isec Is Nothing Then
  858. arr(i, j) = j
  859. isec.CreateSelection
  860. isec.Delete
  861. End If
  862. Else
  863. arr(i, j) = j
  864. End If
  865. End If
  866. Next j
  867. Next i
  868. For i = 1 To gcnt
  869. arr = collect_arr(arr, i, i)
  870. Next i
  871. Set sr = ActiveSelectionRange
  872. For i = 1 To gcnt
  873. sr.RemoveAll
  874. inar = 0
  875. For j = 1 To gcnt
  876. If arr(i, j) > 0 Then
  877. sr.Add os.Shapes(j)
  878. inar = inar + 1
  879. End If
  880. Next j
  881. If inar > 1 Then
  882. If group = "group" Then
  883. If shft < 4 Then sr_all.Add sr.group
  884. End If
  885. Else
  886. If sr.Shapes.Count > 0 Then sr_all.AddRange sr
  887. End If
  888. Next i
  889. Set autogroup = sr_all
  890. End If
  891. ActiveDocument.EndCommandGroup
  892. Application.Optimization = False
  893. ActiveWindow.Refresh: Application.Refresh
  894. Exit Function
  895. errn:
  896. Application.Optimization = False
  897. End Function
  898. Public Function collect_arr(arr, ci, ki)
  899. lim = UBound(arr)
  900. For k = 1 To lim
  901. If arr(ki, k) > 0 Then
  902. arr(ci, k) = k
  903. If ki <> ci Then arr(ki, k) = Empty
  904. If ci <> k And ki <> k Then arr = collect_arr(arr, ci, k)
  905. End If
  906. Next k
  907. 'If ki <> ci Then arr(ki, ki) = Empty
  908. collect_arr = arr
  909. End Function
  910. ' 两个端点的坐标,为(x1,y1)和(x2,y2) 那么其角度a的tan值: tana=(y2-y1)/(x2-x1)
  911. ' 所以计算arctan(y2-y1)/(x2-x1), 得到其角度值a
  912. ' VB中用atn(), 返回值是弧度,需要 乘以 PI /180
  913. Private Function lineangle(x1, y1, x2, y2) As Double
  914. pi = 4 * VBA.Atn(1) ' 计算圆周率
  915. If x2 = x1 Then
  916. lineangle = 90: Exit Function
  917. End If
  918. lineangle = VBA.Atn((y2 - y1) / (x2 - x1)) / pi * 180
  919. End Function
  920. Public Function 角度转平()
  921. On Error GoTo ErrorHandler
  922. ' ActiveDocument.ReferencePoint = cdrCenter
  923. Set sr = ActiveSelectionRange
  924. Set nr = sr.LastShape.DisplayCurve.Nodes.All
  925. If nr.Count = 2 Then
  926. x1 = nr.FirstNode.PositionX: y1 = nr.FirstNode.PositionY
  927. x2 = nr.LastNode.PositionX: y2 = nr.LastNode.PositionY
  928. a = lineangle(x1, y1, x2, y2): sr.Rotate -a
  929. ' sr.LastShape.Delete '// 删除参考线
  930. End If
  931. ErrorHandler:
  932. End Function
  933. Public Function 自动旋转角度()
  934. On Error GoTo ErrorHandler
  935. ' ActiveDocument.ReferencePoint = cdrCenter
  936. Set sr = ActiveSelectionRange
  937. Set nr = sr.LastShape.DisplayCurve.Nodes.All
  938. If nr.Count = 2 Then
  939. x1 = nr.FirstNode.PositionX: y1 = nr.FirstNode.PositionY
  940. x2 = nr.LastNode.PositionX: y2 = nr.LastNode.PositionY
  941. a = lineangle(x1, y1, x2, y2): sr.Rotate 90 + a
  942. sr.LastShape.Delete '// 删除参考线
  943. End If
  944. ErrorHandler:
  945. End Function
  946. Public Function 交换对象()
  947. Set sr = ActiveSelectionRange
  948. If sr.Count = 2 Then
  949. X = sr.LastShape.CenterX: Y = sr.LastShape.CenterY
  950. sr.LastShape.CenterX = sr.FirstShape.CenterX: sr.LastShape.CenterY = sr.FirstShape.CenterY
  951. sr.FirstShape.CenterX = X: sr.FirstShape.CenterY = Y
  952. End If
  953. End Function
  954. Public Function 参考线镜像()
  955. On Error GoTo ErrorHandler
  956. Set sr = ActiveSelectionRange
  957. Set nr = sr.LastShape.DisplayCurve.Nodes.All
  958. If nr.Count = 2 Then
  959. ActiveDocument.BeginCommandGroup "Mirror": Application.Optimization = True
  960. byshape = False
  961. x1 = nr.FirstNode.PositionX: y1 = nr.FirstNode.PositionY
  962. x2 = nr.LastNode.PositionX: y2 = nr.LastNode.PositionY
  963. a = lineangle(x1, y1, x2, y2) '// 参考线和水平的夹角 a
  964. sr.Remove sr.Count
  965. ang = 90 - a ' 镜像的旋转角度
  966. For Each s In sr
  967. With s
  968. .Duplicate ' // 复制物件保留,然后按 x1,y1 点 旋转
  969. .RotationCenterX = x1
  970. .RotationCenterY = y1
  971. .Rotate ang
  972. If Not byshape Then
  973. lx = .LeftX
  974. .Stretch -1#, 1# ' // 通过拉伸完成镜像
  975. .LeftX = lx
  976. .Move (x1 - .LeftX) * 2 - .SizeWidth, 0
  977. .RotationCenterX = x1 '// 之前因为镜像,旋转中心点反了,重置回来
  978. .RotationCenterY = y1
  979. .Rotate -ang
  980. End If
  981. .RotationCenterX = .CenterX '// 重置回旋转中心点为物件中心
  982. .RotationCenterY = .CenterY
  983. End With
  984. Next s
  985. ActiveDocument.EndCommandGroup
  986. End If
  987. ActiveDocument.EndCommandGroup
  988. Application.Optimization = False
  989. ActiveWindow.Refresh: Application.Refresh
  990. ErrorHandler:
  991. Application.Optimization = False
  992. End Function
  993. Public Function 按面积排列(space_width As Double)
  994. If 0 = ActiveSelectionRange.Count Then Exit Function
  995. ActiveDocument.BeginCommandGroup: Application.Optimization = True
  996. ActiveDocument.Unit = cdrMillimeter
  997. ActiveDocument.ReferencePoint = cdrCenter
  998. Set ssr = ActiveSelectionRange
  999. cnt = 1
  1000. #If VBA7 Then
  1001. ssr.Sort "@shape1.width * @shape1.height < @shape2.width * @shape2.height"
  1002. #Else
  1003. ' X4 不支持 ShapeRange.sort
  1004. #End If
  1005. Dim Str As String, size As String
  1006. For Each sh In ssr
  1007. size = Int(sh.SizeWidth + 0.5) & "x" & Int(sh.SizeHeight + 0.5) & "mm"
  1008. sh.SetSize Int(sh.SizeWidth + 0.5), Int(sh.SizeHeight + 0.5)
  1009. Str = Str & size & vbNewLine
  1010. Next sh
  1011. ActiveDocument.ReferencePoint = cdrTopLeft
  1012. For Each s In ssr
  1013. If cnt > 1 Then s.SetPosition ssr(cnt - 1).LeftX, ssr(cnt - 1).BottomY - space_width
  1014. cnt = cnt + 1
  1015. Next s
  1016. ' 写文件,可以EXCEL里统计
  1017. ' Set fs = CreateObject("Scripting.FileSystemObject")
  1018. ' Set f = fs.CreateTextFile("D:\size.txt", True)
  1019. ' f.WriteLine str: f.Close
  1020. Str = 分类汇总(Str)
  1021. Debug.Print Str
  1022. Dim s1 As Shape
  1023. ' Set s1 = ActiveLayer.CreateParagraphText(0, 0, 100, 150, Str, Font:="华文中宋")
  1024. X = ssr.FirstShape.LeftX - 100
  1025. Y = ssr.FirstShape.TopY
  1026. Set s1 = ActiveLayer.CreateParagraphText(X, Y, X + 90, Y - 150, Str, Font:="华文中宋")
  1027. ActiveDocument.EndCommandGroup
  1028. Application.Optimization = False
  1029. ActiveWindow.Refresh: Application.Refresh
  1030. End Function
  1031. '// 实现Excel里分类汇总功能
  1032. Private Function 分类汇总(Str As String) As String
  1033. Dim a, b, d, arr
  1034. Str = VBA.Replace(Str, vbNewLine, " ")
  1035. Do While InStr(Str, " ")
  1036. Str = VBA.Replace(Str, " ", " ")
  1037. Loop
  1038. arr = Split(Str)
  1039. Set d = CreateObject("Scripting.dictionary")
  1040. For i = 0 To UBound(arr) - 1
  1041. If d.Exists(arr(i)) = True Then
  1042. d.Item(arr(i)) = d.Item(arr(i)) + 1
  1043. Else
  1044. d.Add arr(i), 1
  1045. End If
  1046. Next
  1047. Str = " 规 格" & vbTab & vbTab & vbTab & "数量" & vbNewLine
  1048. a = d.keys: b = d.items
  1049. For i = 0 To d.Count - 1
  1050. ' Debug.Print a(i), b(i)
  1051. Str = Str & a(i) & vbTab & vbTab & b(i) & "条" & vbNewLine
  1052. Next
  1053. 分类汇总 = Str & "合计总量:" & vbTab & vbTab & vbTab & UBound(arr) & "条" & vbNewLine
  1054. End Function