QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
5天前
查看: 9209|回复: 8
收起左侧

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

[复制链接]
发表于 2012-4-3 19:49:29 | 显示全部楼层 |阅读模式 来自: 中国广东珠海

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。4 |6 f9 j- Q& g& Z+ |
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:/ g/ S- X1 M- ?* g8 I- \+ s9 u
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?- R. s7 j. Y2 R' G" E+ h7 o
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?" a8 J* }8 A3 ?( V
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
* i& _  d. I/ U" u7 T版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()) Q5 _$ Y5 q; ?. C3 K* [9 |
  2. Dim ptInsert(2) As Double
      Z5 K" h% k$ ~0 Y# \8 \1 P' @% w, ^/ j
  3. Dim lastSel As AcadSelectionSet
    % }/ A2 L3 i: m9 V! L6 j
  4. Dim lastBlock As Variant( W$ |9 o. {" k- d0 P+ j6 G
  5. ptInsert(0) = 0
    ! P: i- P8 ?8 S2 g- N* f/ o
  6. ptInsert(1) = 0& w9 w5 q) d* }+ G
  7. ptInsert(2) = 0/ f" N  q% w7 y% Z
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0- L, o& o6 \6 L" C
  9. 9 Q% e4 j* `3 I

  10. 8 A! Z) {- n" J
  11. 9 \% L* G. U: j2 d
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '4 X- }  \5 j$ C# ^
  13. lastSel.Select acSelectionSetLast
    % T3 o! U' ?9 b! `: f

  14. - d& Z4 E. Q/ Y* e+ ~$ i; k; K# M
  15. Dim B As AcadBlockReference '声明一个块参照变量
    2 ^- A4 M: ?4 n4 S7 j/ D, K
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    0 ?6 }8 k1 n8 s0 C; x1 a
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量) N0 W0 C' X4 |# g0 B+ w6 c$ @0 n
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组! d4 l! ^/ n: i. C1 Y6 d# y' m
  19. + p) [: y8 F+ ^( r" X, s9 D
  20. lastSel.Delete '删除选择集( c* [9 S, a+ L1 b5 s0 f
  21. 3 c- j. Y9 d- e( @& T3 F% q2 F

  22. # a3 J' F4 }# t: b" s% k
  23. ThisDrawing.Regen acActiveViewport
    7 g  a, e1 w9 n0 _) i- h* A

  24. . W4 Y2 S* c) D8 J2 E

  25. 9 M$ v( n+ H! \) M. i
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    1 \+ s/ [( L) e
  2. Dim ptInsert(2) As Double
    & G1 C) Q# J9 c$ x
  3. 'Dim lastSel As AcadSelectionSet5 H/ `6 \+ g/ R; b/ {
  4. Dim lastBlock As Variant3 @" y0 {* e# x0 Y& n4 o8 I* C- ^
  5. ptInsert(0) = 0
    0 M. d4 }3 e# l1 t8 Q' L7 ^6 l; |
  6. ptInsert(1) = 0
    7 d6 O7 _; L% W2 o/ y1 n: l/ d
  7. ptInsert(2) = 0
    9 h; t$ d7 a$ z; C
  8. 8 {* _$ `, v% F0 l7 i

  9. . l; _, c; y$ L

  10. . b; s. e5 I& l8 F: t
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") ') R, y1 B8 Y8 i; k% T
  12. 'lastSel.Select acSelectionSetLast
    ) P1 f$ E5 O; u, b! ]- |, o

  13. 6 I0 J/ s* }9 m4 h. Z7 e! Q
  14. Dim B As AcadBlockReference '声明一个块参照变量9 A) @4 r9 z0 M+ ]; ]/ e) M% w! B
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标( K" j$ c# d, w" [( r/ i
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)( A; a. ^; u  Z+ Y+ i! T" r4 C
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    0 a$ V6 ~$ x% U& v
  18. & H2 C4 J6 M- d/ v( G
  19. 'lastSel.Delete '删除选择集- C4 X) {- f3 R# Z7 d
  20. ) a5 M) M! b8 B6 X% u, h

  21. : N+ ^* r2 C! [7 b6 b. |. }
  22. ThisDrawing.Regen acActiveViewport
    / ~) G! x( }+ ?; K2 Z
  23. # j+ Z' r& \0 _$ B' V+ i
  24. - i! n% {) I. k4 d" N
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 8 Q/ w) J% E" E+ g4 U3 I2 k

, H8 F6 _) v! P4 A首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
) |: |! M7 |1 \- k" ]+ [% X) k
  1. pNew(0) = P(0) - 500
    6 h$ |( [6 J2 A  E, |# }4 U
  2. pNew(1) = P(1) + 1405.8* q3 }4 M9 N  P9 P6 |
  3. pNew(2) = P(2)
复制代码
- X% K, m2 q; a3 e
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
" j' ^7 v& Y7 P3 l( J$ R( C& {+ `/ y就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
" I7 Y) [& p; O) s6 H% O谢谢版主& p5 I1 F4 C$ g& `% Q8 r/ y

1 }6 ~8 ^1 Z+ s7 @. d4 C7 R9 M
1 Q/ [6 R2 Q; ?! \& ?
  1. Private Sub cmdInsert_Click()! C  }9 a. L& Q0 ]- _
  2. Dim ptInsert(2) As Double$ a* y* _3 T  H& ?1 s2 R  q
  3. Dim lastBlock As Variant
    ; x: o! n8 N! D- w
  4. ptInsert(0) = 0- t$ X: r4 F$ M* p
  5. ptInsert(1) = 0
    $ T8 K9 F( ~2 S8 j8 [
  6. ptInsert(2) = 09 h3 ^& t. ]$ w5 q: R

  7. 6 U6 b' ~4 L) |
  8. '----------插入块A 仅仅一个---------------------------------, j* u/ c7 V& P! Z4 q' Y& ~0 _# V
  9. Dim B As AcadBlockReference '声明一个块参照变量6 R' Q. r0 \' ~3 l
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    ! I0 R  w% J+ H  V' k
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0). G- W3 F0 N; D2 t- Y8 t+ Q% j6 C
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组2 n8 c: `- ~* i7 W+ c9 J4 t
  13. '----------插入块A 完成---------------------------------, ]1 T3 K& P3 ~) p9 D: m5 C
  14. + R7 c% ?( ?% g. x7 {8 a8 M1 Q9 M* @* \
  15. '----------插入块B---------------------------------! W8 n3 r( |$ _
  16. '第一个块,需要单独插入
    ) ]( K' X  Z4 `# S: a0 Y% j3 }
  17. Dim pNew(2) As Double
    / _1 G$ X% w6 X, V
  18. pNew(0) = P(0) - 500
    - W6 g- F: e# [8 P  j+ e/ C: x
  19. pNew(1) = P(1) + 1405.8
      ?0 I- X! j4 B+ c% F1 k
  20. pNew(2) = P(2)  p' M; V. c; s! P# X/ e" S
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    & I: f7 P& @7 E. {$ ]
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    # T6 v4 Y: K( j& X
  23. ThisDrawing.Regen acActiveViewport) ?7 g+ `/ ^$ H: i
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
9 f9 ~+ W' c3 [* b  }' K  P& M  v; g" d% s' }
3# tataki
  N! s$ u. T$ ?$ k& q看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 3 m" v: K9 a& L. m( J
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角3 C, E2 t( Y6 E$ b
  2. Dim MaxPoint As Variant'右上角6 C3 g6 Z+ u3 C. Q6 Q7 l
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!" M) s8 [6 v) T. A! C: {; ?& I
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
6 V; ]; d- v- d0 f# K; {( z哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。" c7 Y- |# S/ S" O
4 a  \. s2 E- J; q/ h
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..4 R& [% _4 X+ S& r3 t
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
7 E- y( G/ T$ k5 Ztataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
; E- G4 V2 q: y
lisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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