Tools.bas 37 KB

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