QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。2 \& L% d9 M! h
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:( u$ O( I3 w$ k# E( F9 y
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?4 J2 g# I! ]' i4 ~
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
1 @7 [& P( b  ?, _* x7 [3 S' O# m之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
& I( a) v4 j5 S& x- G  ~1 n9 C3 W, Y版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()" e8 |$ u& ?9 _# m! K
  2. Dim ptInsert(2) As Double
    9 \6 M  U" J4 K
  3. Dim lastSel As AcadSelectionSet
    & I) n& g$ G1 T5 w' U
  4. Dim lastBlock As Variant1 m- y( J4 _- e
  5. ptInsert(0) = 0
    ; F+ |1 V# q/ R1 W( O2 y9 T
  6. ptInsert(1) = 0
    ) J) Q7 w. c# i3 [5 x" x4 R  ?
  7. ptInsert(2) = 0  E  S' k% B6 g! s: A1 @
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    % A; K9 p0 J0 u4 [

  9. $ V- j& I- O1 ]

  10. / Z7 k: z% U" _1 }% l

  11. " y) _. J' M+ m3 v
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '; b7 ~* j$ M6 ~: m, \! ]
  13. lastSel.Select acSelectionSetLast' m, J$ M* o8 G5 c. ]; ]- }
  14. 3 n2 U1 b7 t$ x/ H0 ^4 d/ y+ ^
  15. Dim B As AcadBlockReference '声明一个块参照变量
    . H& {- J" ]$ F2 S/ D; {
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标: S" A( S- n( j9 t+ x
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    + d1 I. P5 e: a- i( C$ i
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ! A% w, s) M$ M% Y) _$ J, P9 Q5 |
  19. $ F% N  K6 t. P+ R4 R
  20. lastSel.Delete '删除选择集
    9 w+ \/ U9 Y6 C- n. Z
  21. + L7 `# [$ Z! _6 f6 t$ e0 j

  22. # D5 _3 J$ Q: s! B7 N2 W6 v
  23. ThisDrawing.Regen acActiveViewport! i- X5 I) |5 Z5 c$ m+ b3 l0 C" N
  24. % T* G' l% ^( A2 M
  25. 8 [0 W* Z% t( ~
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()! p6 j- z9 j, ~" B" R6 f2 m! i
  2. Dim ptInsert(2) As Double- }: Q. }+ b. K* b
  3. 'Dim lastSel As AcadSelectionSet0 E# J: v- }1 |6 Z4 g
  4. Dim lastBlock As Variant0 I3 p1 d; i+ G) C5 u2 p
  5. ptInsert(0) = 07 A% @! p" \4 n
  6. ptInsert(1) = 0; Q. R0 @- q+ g/ @' o/ |5 {- ?
  7. ptInsert(2) = 0
    / n1 X8 x* w% s" e" Z7 V

  8. & d( j  o3 a1 u/ w5 W' o! z- I

  9. / r3 R# g! F/ r7 B8 Q5 g2 |

  10. * u, o" V# _* q: ]; P0 K& W( ]
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '3 m/ [- N8 M; l+ S1 d+ U+ y
  12. 'lastSel.Select acSelectionSetLast  j) U- V+ {$ Q- c2 X

  13. ( T# I2 a$ n2 h
  14. Dim B As AcadBlockReference '声明一个块参照变量
    3 i: j  Z& W* G. j& [/ @) K
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标# J+ y- |6 J- ^3 C8 w
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)) b# [) Z: R- q8 h9 W( o" L
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组* }/ c( U) S% I% }% s# Y, D3 W& C0 B; z
  18. & v, C# |, b& D3 u2 I5 K* X
  19. 'lastSel.Delete '删除选择集
    * T$ j# k# ]+ \! H; F
  20. . o- O: v- c' G# L
  21. 2 z% e% D' _( _" m" b% N6 F
  22. ThisDrawing.Regen acActiveViewport
    1 ^, O) q0 C3 q. c- V1 d6 c  T  L
  23. ( Y' G( h& T- y) J; \

  24. & D. v5 v: V  x5 ^9 g6 p
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
! J1 j  c4 z* ~( p
' U0 U" J* N8 }" m/ U1 D8 c7 |首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
" L5 P' w9 S* U  B- n6 {+ C
  1. pNew(0) = P(0) - 500
    $ [3 Y( L' d. ]$ e3 a  }
  2. pNew(1) = P(1) + 1405.8
    ( Z4 [1 Z$ t# |
  3. pNew(2) = P(2)
复制代码

* h2 H  A# [$ }/ k我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?1 W9 [/ Q+ Z% |5 I# A2 F" d
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。$ m" m4 H5 q9 [( A7 [* A
谢谢版主
% O" Q2 H9 u# Q) x8 Z
% e3 \6 _0 j) n$ Z6 Z7 x' Q9 A) W
1 d. r; a& b4 V
  1. Private Sub cmdInsert_Click()
    3 L! ?2 Y& i7 V# _! ~
  2. Dim ptInsert(2) As Double
    & v( G' {2 C; t2 T' Z' }3 {- l
  3. Dim lastBlock As Variant7 V( J( `8 b5 \% h; N+ ?5 v9 b1 |# p
  4. ptInsert(0) = 09 s3 x9 m( c6 d3 u( t+ |0 X0 c, a  T
  5. ptInsert(1) = 0) c7 Q& g2 w3 c* I6 D' A
  6. ptInsert(2) = 0
    3 r- B5 q, g# Q6 k, [9 J

  7. * z1 Z7 K) G5 E) O! h7 m2 Z$ h
  8. '----------插入块A 仅仅一个---------------------------------
    7 L, _9 {' s# m0 R
  9. Dim B As AcadBlockReference '声明一个块参照变量
    6 y# j& p3 H/ H* w
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标1 Z6 g7 F1 p  t
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)4 a' E6 x8 Y# Q8 m$ |# t
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    5 [- b/ F# R4 p2 V
  13. '----------插入块A 完成---------------------------------, F6 ]) P/ k* \. ?/ h1 W' W
  14. . z: |! }; ~" O5 k( N6 R/ R
  15. '----------插入块B---------------------------------
    6 Z% x/ |% i8 P/ y) X8 ?
  16. '第一个块,需要单独插入
    . ^9 c- X2 v9 D
  17. Dim pNew(2) As Double$ G1 n+ Y& z- _* K$ q. u6 }
  18. pNew(0) = P(0) - 5001 i: A, q1 t/ b1 }
  19. pNew(1) = P(1) + 1405.8
    ) f! G5 `7 y! H! T" W
  20. pNew(2) = P(2), @( a. `. D0 E
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0), M7 h1 n/ ^# `& J
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    . ^/ p5 J1 Z: u* \9 R$ o! r1 P) _! }
  23. ThisDrawing.Regen acActiveViewport5 y! x" c1 }2 ^% a. |: s) U- i
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 3 o3 b8 v1 h' u' f, v! @. ?
* h% [3 m9 U5 x; V
3# tataki
1 g! C: ~# S8 Y1 J看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 1 D. _. s- N5 v4 p5 g  I- r
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    - |6 ]0 s( |" E8 j, E
  2. Dim MaxPoint As Variant'右上角( e% u. j( j' r
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!0 ?5 T5 ~( s8 Q# t
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..6 U* R: Z( u. V0 h9 [/ [2 \
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。. l1 O9 ?9 W0 \4 l' ^
& T! |8 O$ u$ E5 ?$ c! U; ?
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..8 p% ^" O" P" ^+ T0 ^
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...% e; E! D! c& R) \5 z
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
& A: V+ q4 X; Z- M
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 )

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