QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

查看: 8916|回复: 8
收起左侧

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。( t# _$ _5 w/ I7 h  x" p0 p
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:. V: v0 _& s: i
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
+ E) X; g  ^& i- J" e) |6 r2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
1 Z" w2 t" K9 v* _之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
) n7 [( K: w) O, D$ f: G版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    * V8 M# u- l" e1 E
  2. Dim ptInsert(2) As Double) ^: Q" d/ p+ M9 X5 o7 @
  3. Dim lastSel As AcadSelectionSet
    : ~# t: ^! L  m2 e  q" }; j
  4. Dim lastBlock As Variant- D# B3 [. n) Y0 J  a. _
  5. ptInsert(0) = 0! c' I) r7 }6 g" L8 f
  6. ptInsert(1) = 07 N5 g- o7 l6 h+ {' p* B$ Y
  7. ptInsert(2) = 08 y8 r! N% @5 J* [( d7 e& h: F5 G
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    . M" `8 z/ }7 F+ `  [: u$ x6 B
  9. ! l% p0 t9 |+ l$ G" Y# V) B- t
  10. 5 ^7 t3 n/ Q' g, b7 B3 v6 N# C
  11. , R* y- ~5 v: Z; z# R) e
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '7 x: m0 \( q9 n" J/ V; L6 I+ n
  13. lastSel.Select acSelectionSetLast2 l  n$ H# G2 x$ Y
  14. 1 r' k$ @$ p, @/ P2 J; @
  15. Dim B As AcadBlockReference '声明一个块参照变量4 V9 R; f; s: D5 [% e) Y/ q* s$ ~
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标1 i/ \% f/ {9 ?7 Z9 V
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量! g0 q) ?( l' E( L8 o& L3 y5 f! O
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组' V, Z* k* j) S; K& c6 V' d

  19. ! O0 x0 N9 P; h2 L! ^% F$ q
  20. lastSel.Delete '删除选择集" u  C) F4 [; D
  21. 4 y9 R* w2 W. ^5 l4 o

  22. " b: M1 \+ L. h2 |7 a+ H2 t
  23. ThisDrawing.Regen acActiveViewport
    # i2 T; S& D5 Q. [/ ~( g: r

  24. ! s4 i" G* d9 y. O# w
  25. , g8 h; k5 t3 m* _, l9 W
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()4 M$ [, V- N7 A7 T
  2. Dim ptInsert(2) As Double
    : m' n6 }4 f) Y
  3. 'Dim lastSel As AcadSelectionSet$ M# S4 l4 F, B/ z
  4. Dim lastBlock As Variant
    : y4 ~. h7 {6 g( c) p# h& ~" L7 A/ K
  5. ptInsert(0) = 0
    - i) R+ S9 `5 G3 ]7 L, D
  6. ptInsert(1) = 07 o, ^- J% L# G
  7. ptInsert(2) = 0- p4 }  u& a$ U; ?0 a
  8. 6 H& F" T1 C3 n% k9 J6 z3 ~) B
  9. 0 T+ m. s7 m- I9 m9 ^0 o- s7 J5 r
  10. * v( N7 q' o& ^/ |3 W
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '  `8 A1 q" x* A; s. }1 J; V
  12. 'lastSel.Select acSelectionSetLast
    ; U4 S, s  w# M% k5 O
  13. * f; F1 O! k9 S5 A* y
  14. Dim B As AcadBlockReference '声明一个块参照变量
    9 t2 a9 Y9 `/ k! w. ]
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    6 u4 K& J0 m) t2 g, H" m5 ^; R
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)% Q8 S# Z4 [" `$ a; O
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组  k5 W  N# S* p- m8 R! x- u
  18. % U$ U/ P! G; w# p6 X
  19. 'lastSel.Delete '删除选择集
    ( j( F8 ~8 e) X3 k8 C; v1 K

  20. 1 f) |& U9 \  r4 ~/ M5 m
  21. 7 S) ]* E, F/ D) d$ M5 I5 Z" |* }- O( k
  22. ThisDrawing.Regen acActiveViewport. ^9 ^& U+ L: A" k, I

  23. , ]6 o1 }4 u. H9 n8 i
  24. + P+ [& p. W8 a" c. Q
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 . l& i: \' @# D6 J
6 M# v3 I9 t5 T! P6 k) Q5 X, b
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:$ w+ d  G9 @% z1 \; h
  1. pNew(0) = P(0) - 500( L3 {7 W! S' o$ U
  2. pNew(1) = P(1) + 1405.8
    $ p# Q. b8 ]! ]; A+ z
  3. pNew(2) = P(2)
复制代码

) K$ ?( p/ E; T; n( `0 o6 K我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
2 D; r; u: q' Q+ H5 q& s就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
; w( r$ O: v4 q1 V2 F2 e谢谢版主" ^' T8 b/ @+ H: x3 k
1 v$ l4 {$ Q6 w: S3 g
! A5 ]/ G( l: ^3 v
  1. Private Sub cmdInsert_Click()
    ' W- B* z, ?! K5 p3 k8 `' g* V$ D
  2. Dim ptInsert(2) As Double% b4 ]( j( Y* U: U; [
  3. Dim lastBlock As Variant
    / V' g& X( h: e& d! G: J; Y0 L6 l
  4. ptInsert(0) = 0
    7 w0 `8 X0 p3 `; S) z6 f
  5. ptInsert(1) = 08 s, w0 y0 I2 S: H. K, \( b6 v) P5 x6 H
  6. ptInsert(2) = 05 n1 o) O/ _8 \. `" N2 R4 `

  7. ( }+ C7 p6 }' r- S2 J  S; `3 J# ]4 Y- i
  8. '----------插入块A 仅仅一个---------------------------------+ w* y9 o" w3 g4 }' R* q
  9. Dim B As AcadBlockReference '声明一个块参照变量& \7 T# B* ^. F8 P6 ~8 r6 k
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    : u* Q7 h  ?9 i/ d/ V9 @
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    1 F2 i% L8 C8 q4 @
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组/ r6 w, Z- \6 P; s2 t, ^+ V* ^/ @
  13. '----------插入块A 完成---------------------------------
    8 y, W$ H3 C% D3 l
  14. , }9 {  E5 z/ s- o6 A
  15. '----------插入块B---------------------------------' K2 c2 \7 q4 F7 u# p: B
  16. '第一个块,需要单独插入! R. @5 Q/ v( P) y1 O
  17. Dim pNew(2) As Double
    . p$ T3 j" ^# x0 z/ a0 n
  18. pNew(0) = P(0) - 500# M% Q2 }* v5 Y- y
  19. pNew(1) = P(1) + 1405.8
      Z" x+ c  U; @0 ~
  20. pNew(2) = P(2)
    + F1 U2 B- v& U( u# Y
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    # i8 f0 O4 F7 }6 F( |* q( O
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    " N( r: o& j' S1 C- h$ a* \( e0 ?
  23. ThisDrawing.Regen acActiveViewport
    , |- ~5 p/ z! V: z/ ]) W$ `$ h
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
* a! b6 W& L/ b/ v8 P, Z+ N7 R7 d! A9 ?. N) H
3# tataki
: n& D% D) X9 P% a9 t看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 : [) M8 s6 {9 Z8 n+ p, M9 w5 t' u
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角$ f4 {0 h4 p8 Q4 D6 C( p+ E: a8 K' d0 \
  2. Dim MaxPoint As Variant'右上角
    - q' h" T2 o' m% V0 @! y; v* f
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!: K2 `8 }$ {" Y# a; v
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..# W" M0 e9 O* r) x
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。3 A' ^) z: L; s

0 Y6 y/ }; F4 i7 \0 s另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..  S' ~+ G2 O: O! w4 b
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...8 I, m" N" g  `3 }0 j& g- `) {- @
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
# q& f# h# q! E0 [
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 )

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