QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
: L! e" E7 r; t0 x5 ?: h3 V' Z其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:* c# j3 p3 X( y$ y) }+ B
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?+ A6 q2 b, L( t  b$ c/ x5 y
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
2 k/ _4 A4 i: m8 _9 F! V之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了9 U* y6 R& _+ Z- v7 ]% N
版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
2012-4-3 19-29-23.jpg

块自动插入.dwg

42.84 KB, 下载次数: 11

InsertBlock.rar

7.03 KB, 下载次数: 8

发表于 2012-4-4 08:29:21 | 显示全部楼层 来自: 中国辽宁
方法一:按照楼主的思路使用选择集
  1. Private Sub cmdInsert_Click()
    3 J8 P, Z& y" M, o" n
  2. Dim ptInsert(2) As Double' @) `- i. J3 ?2 b
  3. Dim lastSel As AcadSelectionSet
      j2 w7 F, o7 Y
  4. Dim lastBlock As Variant
    2 i3 I1 i9 v" ~$ L: m/ Z8 Y
  5. ptInsert(0) = 02 h5 ^, v; X. s+ p7 f! K
  6. ptInsert(1) = 0
      O& |4 m. k$ i  z
  7. ptInsert(2) = 04 |; r6 J* V0 h) A3 B# n( l: z
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 08 c6 ?) L" z  w% r* O

  9.   D& y) B4 x0 t5 l$ a8 ]
  10. - k! R8 _: Q5 L! p. r6 _+ Q6 G
  11. , Z. P! m, H3 s7 n, {: M
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '6 q+ P9 H4 k: Q6 {
  13. lastSel.Select acSelectionSetLast
    ) H6 y! O8 b  a" g# [

  14. : k/ x9 y1 I* W
  15. Dim B As AcadBlockReference '声明一个块参照变量
    & E2 M- T7 {, Y; T/ a0 p3 X
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标- G& G3 u; H3 v5 c+ R  ]
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    7 C, `' ]' Y- l, R9 V3 O  A4 Q! N
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
      Q) j1 i& [8 r$ b( c% V1 |' Y/ [# m

  19. 0 W2 a6 X- N$ U1 p* ?& ^
  20. lastSel.Delete '删除选择集! v  t* j' d; l0 y

  21. & Q- k: w: ]6 _+ f' c
  22. * b: b4 u+ g) T2 I; F: a# M
  23. ThisDrawing.Regen acActiveViewport1 ~- r' T1 t1 ?% ?. z; m2 X4 F- S; Q: }
  24. / {$ l: r- L( R2 `9 f$ r0 y

  25. 0 i) I0 W6 ^+ u, O
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    5 D" s! K- D4 X, _& w! [
  2. Dim ptInsert(2) As Double
      x$ y/ j0 o/ P1 h/ X1 \
  3. 'Dim lastSel As AcadSelectionSet( o; G9 @9 ?. Y) Q; V' B
  4. Dim lastBlock As Variant
    ; I4 v$ V/ i  E7 C- M
  5. ptInsert(0) = 0! u. A; ]2 ^3 M, Z/ M+ O4 F
  6. ptInsert(1) = 0
    4 t- M: u8 Y+ {; |+ [8 E3 P, }
  7. ptInsert(2) = 0
    . O+ B* F& F1 [6 d) Q- m

  8. + p/ t3 K0 i" J+ H0 G  g5 U3 N/ |8 ~

  9. 4 |+ }  F* y& q- i6 ~
  10. ; [, C6 q. I) f, {; |3 q$ U7 u8 \: J
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '( i* e9 ^6 f/ ]* i: Z3 e
  12. 'lastSel.Select acSelectionSetLast
    / ^8 H" e! M0 u; x" i1 H$ M) b

  13. 7 j( M4 F2 j6 n( I
  14. Dim B As AcadBlockReference '声明一个块参照变量
    3 ~+ X& v+ {8 v8 u! ?, H+ `" j; U
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标* e' `8 X" K  H! L& ^" R
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    3 D( V2 G* {% C# x, p1 V' y/ Q
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组- `# d$ K. N2 X5 c7 N

  18. - P0 z, O) ]) P7 T9 v+ f
  19. 'lastSel.Delete '删除选择集
    8 o. f5 `$ e# t3 l

  20. , j, T! i  A* ^* F; |3 _- Y
  21. * F2 C" t6 o3 A0 m/ V
  22. ThisDrawing.Regen acActiveViewport# f" p0 h+ S2 [% b1 q

  23. 0 H2 R# \! F3 y
  24. ! j7 t( R* }/ ^, y$ n
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
; t/ Y0 ]- a2 A
& _$ g1 W$ Q  D首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
+ ~6 B# m! A$ w5 r) M
  1. pNew(0) = P(0) - 500
    # T! S/ a2 \  J! \6 k/ B
  2. pNew(1) = P(1) + 1405.8. q- {# B, i0 M7 }! \7 e. j
  3. pNew(2) = P(2)
复制代码

$ P( K: r  a9 R1 L我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
+ c9 E& |/ y/ T0 R, B1 F就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。. L3 t2 {9 s6 M7 f% [. e5 r
谢谢版主% R; f5 c; v$ h% Z* ~

( |& N- ]* i( B" ?: d% C4 A# d% R6 [2 c8 K5 @7 K
  1. Private Sub cmdInsert_Click()
    + H  L5 W( ]6 @$ F8 t
  2. Dim ptInsert(2) As Double
    4 _- m3 o) |' n* @/ \, [& }
  3. Dim lastBlock As Variant
    3 p. q5 H$ M4 L; Y
  4. ptInsert(0) = 06 B2 l/ i" v) A* s& Y+ e. h9 u
  5. ptInsert(1) = 0
    + U1 `9 ^! K( ~
  6. ptInsert(2) = 0) q; C1 d$ S0 H# ]$ Q& Q* S" {
  7.   Y/ m& v/ G. g+ |9 `
  8. '----------插入块A 仅仅一个---------------------------------6 j3 H2 F- r- X, M& s1 J3 ]* U$ A
  9. Dim B As AcadBlockReference '声明一个块参照变量. N) `( z8 L6 Q, d. h
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    ) g, s; Q6 O- Y
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)0 @- i+ n! e" o( I! k9 ]
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    1 V8 R+ a1 Q# Y" a
  13. '----------插入块A 完成---------------------------------
    . e; R- y' }" a4 S
  14. & O0 E* Y2 E! S" c5 T5 g& J
  15. '----------插入块B---------------------------------
    , x8 L3 Y- \8 r9 \- m5 `. k
  16. '第一个块,需要单独插入% i- H. T2 \5 d5 N
  17. Dim pNew(2) As Double
    ; V  i* I/ T/ W  y  h4 l
  18. pNew(0) = P(0) - 500
    0 D( [" P) k  N* g
  19. pNew(1) = P(1) + 1405.8: j' k3 I5 S& T# ^/ R
  20. pNew(2) = P(2)
    # V7 t+ x) n( q+ O/ d7 T; T& z. T
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    2 V: j; e5 H+ r  Y/ d# t
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组7 \3 y3 T3 b; U7 v* q
  23. ThisDrawing.Regen acActiveViewport- z! l7 D# `6 O8 X4 S& |
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
3 ]+ _) j. A; H" Z: _) l; |: k2 b  G. A6 f& f# m
3# tataki
9 m, r) x+ p; s看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
/ H3 D- E5 T3 v7 M7 F# gVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角) s! X+ ?+ A/ Z
  2. Dim MaxPoint As Variant'右上角
    ' X- `5 l9 Z2 U3 Y
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
4 d3 ?  G7 o0 N) }$ R7 Y: p原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
- D; ?; X) W0 G* d4 ^& f0 U哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
9 z# w* y: ~0 E* H2 F& w
/ I/ N) Z- V3 Q* r- {另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着... \0 r3 g" a4 Z' o
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...2 b* h& F0 R/ l( J
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
$ L# ?+ C8 {& }! b  {7 n
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 )

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