QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
( C' d3 {& d/ b' D$ t. [; n其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
* X3 E- X( Y+ b3 e1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?7 a* D* W. T( y
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
- c* }& H6 z$ u7 D/ |之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
  z! S. Z+ u% @9 S版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()1 q8 E+ \3 ~; m* V
  2. Dim ptInsert(2) As Double
    9 U% }; u: H6 ~3 K+ h4 l
  3. Dim lastSel As AcadSelectionSet) k* n" Y3 I* t6 M2 {: l6 o. B
  4. Dim lastBlock As Variant) Z1 Q9 t- y: v( O. z2 m$ a
  5. ptInsert(0) = 0
    # _& M5 q6 C7 K& ?$ X( u4 k
  6. ptInsert(1) = 0" Y; \6 V5 e. i, S5 T9 d3 r
  7. ptInsert(2) = 0/ c( V7 _  B3 w7 r3 l7 t" `$ [
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 05 B) [6 Z5 r1 t# ~) T- W' w

  9. 1 {( f; v, I1 G4 ]
  10. 1 Z) U7 O& D: e1 A9 f( U) B
  11. ) l" F# ?( `( ^; K
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '0 I8 b6 Y. n6 U/ A! c( V
  13. lastSel.Select acSelectionSetLast7 K  F8 f) E% J7 }" B4 f0 y) d5 G; u

  14. 0 |% h9 p7 n! e. _
  15. Dim B As AcadBlockReference '声明一个块参照变量5 I% a: o: X/ U! Z. L6 Y
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    $ q& g! z8 E7 f) z2 `. ^
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量% a) J9 V( Z/ j" w5 l3 \! T3 g
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
      e9 D9 F% @4 g1 I2 b
  19. - @  m8 g  f$ r: k. P* K
  20. lastSel.Delete '删除选择集
    $ x& B- c3 l; {

  21. 0 B6 I8 C1 D! n) V3 r% b1 l1 R8 l
  22. ) o1 s# `: y/ C' r9 W
  23. ThisDrawing.Regen acActiveViewport2 O5 z7 j4 d1 G) s
  24. & z1 R7 F% \; r' Q; q6 n0 F! d, {

  25. * n* t3 w3 t" z' E5 W# `
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()) R* n: X5 N) N# K" s5 j4 O: y
  2. Dim ptInsert(2) As Double
    # l* I( o& l( _' O3 O
  3. 'Dim lastSel As AcadSelectionSet
    ; F+ S: [0 l( [& \" T1 X. [
  4. Dim lastBlock As Variant
    " l0 @' ~) v, A7 c
  5. ptInsert(0) = 0
    ) B5 M$ C- k+ O3 C
  6. ptInsert(1) = 0& U/ i2 H0 n  S) Z; w; o  K2 h
  7. ptInsert(2) = 0
    . R  r2 ~" L8 I, b

  8. + |, s, E$ n) L2 F/ j; L

  9. 0 l# O! c/ \* k' f; b' K" L

  10. 0 f( i* b. x3 @! u1 k0 s
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    ) e* k4 x+ E; d- A* K1 K
  12. 'lastSel.Select acSelectionSetLast, o) |% p, b/ T

  13. ! H# Z# {3 C7 P, r' ]% l
  14. Dim B As AcadBlockReference '声明一个块参照变量
    : t: a3 U8 r: o) L
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标: n: p0 u( m5 r
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    # _9 |# d* Y/ X: w  N4 i
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组0 {' x; n# V; h- O! c

  18. # d( I+ n- l, F0 `- Q' T
  19. 'lastSel.Delete '删除选择集7 ?: d) |$ W- P9 S

  20. ! @; U) e: g/ `% ~0 E( S/ Q. A

  21. + r# S* K, e! B& S
  22. ThisDrawing.Regen acActiveViewport
    9 F( @1 J9 l  U& x7 C
  23. ; Z/ J# ], D% l; `6 c$ _

  24. 8 a; ^. T& i4 n& s0 W; y+ B7 P
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
2 A2 a' `+ P% A9 Y, i6 K+ G4 C) R" J; x5 s2 q" o
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
# d; K( n  B9 n- U1 Q7 I
  1. pNew(0) = P(0) - 5004 p! G- V6 U/ o2 P/ H& B2 n
  2. pNew(1) = P(1) + 1405.88 W* V+ r" A* f6 ?# @3 j+ {
  3. pNew(2) = P(2)
复制代码
: E/ m& m( d: A6 F8 Y% F6 ]
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
1 h; W7 m" u) `# L就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
2 p7 @) ]9 S* O谢谢版主- H0 H  n$ X4 P  }8 O

% Z  v. d: m2 L$ V2 L: ]
7 j3 N) ^$ J7 z9 F- c
  1. Private Sub cmdInsert_Click()
    6 W. N- o" d' \2 B; b
  2. Dim ptInsert(2) As Double( V& g$ M# Y0 P3 w
  3. Dim lastBlock As Variant
    0 ?7 C: K' g: c7 T; Y1 U: k
  4. ptInsert(0) = 0
    & S$ N7 N: E% I1 f3 x
  5. ptInsert(1) = 0$ O9 M* v. `. O& l5 }% e* x( _
  6. ptInsert(2) = 0
    9 u- {8 w6 j3 P: \

  7. + y- O8 q; r) F; Y" q4 s( t. f+ c
  8. '----------插入块A 仅仅一个---------------------------------
    3 g; e: I8 P+ e7 o: V
  9. Dim B As AcadBlockReference '声明一个块参照变量
    ' f0 S) l& g1 U
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    9 i. P) c/ Z( v/ ?7 m2 |: U
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ; f" q$ U; t, C$ z. L1 x) p8 m* T
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组6 _( h  l0 ?5 H( {8 n" t
  13. '----------插入块A 完成---------------------------------
    & y# D- |. s! M

  14. ; l0 E  E- m- M
  15. '----------插入块B---------------------------------8 |5 W4 f: b2 ]- C4 O# V$ {9 ]
  16. '第一个块,需要单独插入
    ) m+ X% j( ]9 ~0 G* k
  17. Dim pNew(2) As Double
    $ R; J3 e3 r. w1 u* g
  18. pNew(0) = P(0) - 5006 i! v. b2 s2 Q! b7 l% j- _
  19. pNew(1) = P(1) + 1405.8
    9 _6 M  `8 V, l
  20. pNew(2) = P(2)
    0 x* G  v# \! @( b6 u
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)- S( Z6 B4 z/ {
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    " o5 S: E" ^) J$ J- z& Q
  23. ThisDrawing.Regen acActiveViewport6 m: S3 E: ]% E" W3 K
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 1 `( V5 P# {' ^
3 Y& G2 ~, _7 u) ~4 I  w
3# tataki : R# z  H* R6 p5 j- y& i9 G, B
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 % I, o7 \$ X- P4 K; k+ O6 R
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角" X3 E& \8 {2 D
  2. Dim MaxPoint As Variant'右上角
    6 g6 X1 ~7 e) E, i, x1 z  {) h
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
, k3 l! Z7 \! e4 C# x( q, g. W$ F原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
# u: p" g: W" Q- \" d: R7 E哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
0 J8 P" x: A* ]9 [$ @" K. D& E+ J& X) t; g2 I5 j
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
( _: B8 f+ K+ m  G; S# I哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
1 d6 z* @" t  I' o. J  `6 E6 xtataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

. ?; A; r0 L  p; j, a  K* B$ klisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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