QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
goto3d 说: 此次SW竞赛获奖名单公布如下,抱歉晚了,版主最近太忙:一等奖:塔山817;二等奖:a9041、飞鱼;三等奖:wx_dfA5IKla、xwj960414、bzlgl、hklecon;请以上各位和版主联系,领取奖金!!!
2022-03-11
系统
[系统通知] 平台第一个项目外包——项目拼多;正式上线,欢迎各单位个人有外包、设计、采购、加工需求的,在此寻找更牛的解决方案
2021-07-01
查看: 8594|回复: 8
收起左侧

[已答复] vba里怎么获取上一个创建对象的坐标啊?

[复制链接]
发表于 2012-4-3 19:49:29 | 显示全部楼层 |阅读模式

马上注册,结识高手,享用更多资源,轻松玩转三维网社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
5 \2 v3 K& J4 e" `& o0 l# \+ T其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
; M$ j) @7 N; k6 D, B, F& f: X1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?4 h" C3 ~1 _4 }3 U- P- m; A
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
! [3 @% H. T1 m2 U0 i之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
6 a% ?0 ~* @7 C5 E- Z9 B' @版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
2012-4-3 19-29-23.jpg

块自动插入.dwg

42.84 KB, 下载次数: 9

InsertBlock.rar

7.03 KB, 下载次数: 6

发表于 2012-4-4 08:29:21 | 显示全部楼层
方法一:按照楼主的思路使用选择集
  1. Private Sub cmdInsert_Click()
    0 S' D/ [+ F' A- ?2 X
  2. Dim ptInsert(2) As Double5 b7 P( |' [. U3 B) \8 @: D
  3. Dim lastSel As AcadSelectionSet, g! H8 V( T' o$ l
  4. Dim lastBlock As Variant
    % y$ {( O9 C. {: R8 [
  5. ptInsert(0) = 0
    / F' G' C5 h5 o; O
  6. ptInsert(1) = 0
    5 T& `7 O2 K$ X
  7. ptInsert(2) = 01 ^; t6 j; h- G' K% f6 X9 N3 g0 X' O
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    8 h- }& }2 e! `7 Q
  9. 5 P& Y0 n+ \( s5 X
  10. ( @2 h2 `( a2 V+ J, A2 q

  11. ; ^( k5 U4 ~; N8 I6 P; X
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    % I3 H* R& j) ?2 z4 i; T
  13. lastSel.Select acSelectionSetLast
    7 J4 X' e5 Z$ J) f' d" a

  14. ( B; D. r" Z6 I  q! B: ]( J
  15. Dim B As AcadBlockReference '声明一个块参照变量
    ( \" Y' o$ e3 r0 f4 f+ w
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    $ H% F  A* f1 I* [) M8 O! `
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量0 k4 G  V1 z' Z
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ; k# t8 J$ U4 i5 Q' l% x

  19. ' n( Z3 t: T, d( \! e
  20. lastSel.Delete '删除选择集
    ) f" e0 j( @$ K  d" I" v) q* `
  21. 1 d7 T# n8 M5 N% N

  22. ! T6 n% v& C. {$ \
  23. ThisDrawing.Regen acActiveViewport
    9 B+ a3 a1 C" y. N7 G$ H7 g: y8 O
  24. % `/ ]% |1 M8 d6 s# ?/ H' [  \

  25. 6 i! o' _4 I% u$ O  ~! [
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()2 j0 l! p# N1 L! _. J
  2. Dim ptInsert(2) As Double5 |, t- p$ K* b3 R
  3. 'Dim lastSel As AcadSelectionSet
    9 S  `8 p' V7 V2 @2 t
  4. Dim lastBlock As Variant; J( l% i% _$ ]) o- y6 q# |
  5. ptInsert(0) = 0* C! ^: a4 \) z* N: `  V
  6. ptInsert(1) = 0# e  z" K1 l  ]. s9 J( p7 V. C) j8 X
  7. ptInsert(2) = 0% w$ W. K- w0 l( B
  8. $ \5 {) k- A8 w+ ?6 j$ h) g% P5 s

  9. 9 |7 N3 U! O3 c2 z  n' \6 R

  10. 7 U  C+ f" f0 b, R7 q4 _
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    6 a9 v0 e0 L+ n) m8 J: _
  12. 'lastSel.Select acSelectionSetLast
    9 I) y, ^" E" F" E

  13. / u) [. ]/ i4 H6 @+ a
  14. Dim B As AcadBlockReference '声明一个块参照变量
    : v: u0 E# h1 G; Q- t
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标% A( e7 v+ e7 T% }
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ' i. W* f6 s9 |, {! ~+ s
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    " K0 b7 V, P& @7 t
  18. 3 {% w3 s% c1 U4 q8 e* k. F& u
  19. 'lastSel.Delete '删除选择集
    0 e" S$ c2 I- I

  20. . U5 {7 a3 ^- U5 P8 v) ]

  21. + F2 p& e5 y0 S# x4 e! l' c
  22. ThisDrawing.Regen acActiveViewport+ }( x. |6 W) d( b, P2 i  F
  23. ' F. `9 u# j# ]  |; v' g
  24. ' ^/ L3 D2 w) G
  25. End Sub
复制代码

评分

参与人数 1三维币 +10 收起 理由
唐昕晨 + 10 应用

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 9 Q: F/ p' N! S$ F/ K( w, `4 ^. t

5 r# K9 Z  z8 h# h: J6 I* y首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
  I  f* D, k. n# u  e
  1. pNew(0) = P(0) - 500$ M, X9 A$ o. d# }& S
  2. pNew(1) = P(1) + 1405.8
    - K/ s& r, r8 Z
  3. pNew(2) = P(2)
复制代码

" t% b  M. W6 q% [我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
: f) J& h' W5 N) q就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。/ c& J' s! p5 F& X( ]
谢谢版主
* ?9 p  e; s% ]5 B4 R8 B5 g! g" X: J$ e* K+ B

. E7 W- k9 o! V) J: a' {
  1. Private Sub cmdInsert_Click()4 a) P1 K6 Y8 P6 V2 I
  2. Dim ptInsert(2) As Double/ Q) i: Z6 l$ ~# U, T
  3. Dim lastBlock As Variant, g& ^6 T( Y3 m+ U4 j
  4. ptInsert(0) = 0) L+ \& V9 v5 I" x
  5. ptInsert(1) = 0
    * p- G) k# n. z% B; S8 @- K
  6. ptInsert(2) = 0
    * d( T4 |- Q" S) E6 i5 C
  7. / f& ?2 e: o( w  x
  8. '----------插入块A 仅仅一个---------------------------------& H  }9 `, K' g7 ]3 k
  9. Dim B As AcadBlockReference '声明一个块参照变量
    ) Y. S4 B5 c' W, D2 X
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    7 U& P8 M( A& O3 [5 w
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)3 @. m& N" E: h
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组' f& _8 {+ q8 l" `7 t
  13. '----------插入块A 完成---------------------------------
    ) W& ^7 b4 Q0 L& k

  14. % s% @# W( ]& h
  15. '----------插入块B---------------------------------
    9 _2 d6 r! }: N( w! e
  16. '第一个块,需要单独插入
    , W  ?8 f0 i' I+ b) K
  17. Dim pNew(2) As Double* M4 L9 t8 f1 ~0 L
  18. pNew(0) = P(0) - 500; ^' s- b+ o8 q) \6 [% E
  19. pNew(1) = P(1) + 1405.8$ c5 \  w- m" C3 I/ Q
  20. pNew(2) = P(2)
    ( {9 J, F( s. g- M9 I* ?! @
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)2 N) B0 A' w0 O- l
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    / p* [4 q8 Z9 L/ \
  23. ThisDrawing.Regen acActiveViewport
      [  M' O# X7 g/ k! k1 a5 P9 J' T
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 7 U# L1 R: @* ?% d3 N0 B2 }  n$ |

. S) V/ V6 _: ?3# tataki
% ^5 M0 b& j: F) I; e% Z) }看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
* V$ P9 k' F# H/ }$ P1 ^VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角4 H. @3 f" n+ z4 W' S
  2. Dim MaxPoint As Variant'右上角. F2 X# j% p# T$ g8 a; e/ ^) I/ X
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层
呵呵,漏看了一位数,罪过罪过啊!
5 q4 y$ M: y8 `7 m原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..2 m* R3 p! ~; E+ Y
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。8 [2 K3 l* Z' r9 H3 w
; [- v. _! l+ m  `" z$ a
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
0 g  }1 I: N/ B, i3 f哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
/ [+ ~3 b" N* {0 c9 d8 ]; _$ atataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

' V7 `: c7 @' m4 n1 Ilisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 2013-2-21 23:23:43 | 显示全部楼层
谢谢楼主分享
发表于 2019-6-27 09:08:48 | 显示全部楼层
版主辛苦,特登录赞一下
发表于 2021-1-21 07:32:00 | 显示全部楼层
学习大神们的经验
发表回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Licensed Copyright © 2016-2020 http://www.3dportal.cn/ All Rights Reserved 京 ICP备13008828号

小黑屋|手机版|Archiver|三维网 ( 京ICP备2023026364号-1 )

快速回复 返回顶部 返回列表