QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。6 k& p6 k" m5 T, {4 H) i4 u; C
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
) h1 B8 X; u& c+ L( X2 V1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?( E* E" R6 n3 N5 x- o; n  \/ I; N$ \
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?8 |$ ~1 z/ _' I, q( t1 k/ ^
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
) C$ [% d( Y2 w' p; a3 w, _版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
      w# {: d; H* X! E& P6 v
  2. Dim ptInsert(2) As Double
    / E5 c( j2 o0 p* t" u7 @0 L0 q) |* f
  3. Dim lastSel As AcadSelectionSet
    8 N% Q! Q5 b4 w, h
  4. Dim lastBlock As Variant. ~7 I0 x/ d; @! t5 J0 |4 A8 ~/ |
  5. ptInsert(0) = 04 v# {. ^0 i: M) q" l) a) N' \) z
  6. ptInsert(1) = 0& @( q( d0 P) `7 _
  7. ptInsert(2) = 05 L0 D7 K4 w2 U  ]% h% g, A
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0, m2 J; m. j" |- V& h" {

  9. 3 V3 u" ?" j) C! A+ j
  10. ; y8 v3 r3 O, z6 J- V* t( x2 `1 B

  11. 0 ^' t* W; J1 E  Z
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '- u- |( c  s6 ?3 ^
  13. lastSel.Select acSelectionSetLast
    ; l& b6 B9 @/ ^* |2 @6 J  U5 H
  14. 3 J8 _) ]$ L5 l0 T& G
  15. Dim B As AcadBlockReference '声明一个块参照变量/ C" g0 b- x' e  a) }0 g; \
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标# \4 L0 y  V0 D3 n: d+ t
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    ( k0 k2 R) N8 W' b! \
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    7 B0 E* _  j: p1 \: K, h: L9 Q
  19. 5 E' o. X# y: ]3 H7 ?: v
  20. lastSel.Delete '删除选择集3 r7 V; P8 A; h5 ~5 C

  21. 5 T: B( z- n$ e" h% N4 Z% v

  22. 7 F; e3 v8 Z% E# [% y
  23. ThisDrawing.Regen acActiveViewport( ^  \1 i: ~: i& c4 `

  24. & d9 r* n2 q' u, _6 X6 {
  25. ; p( P$ S8 s; [$ B9 P& u
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    * u8 u! ^8 I5 W% b4 A, k
  2. Dim ptInsert(2) As Double+ ^+ O; y$ t5 V& I
  3. 'Dim lastSel As AcadSelectionSet
    " u. f' W  h# o! Y
  4. Dim lastBlock As Variant
    : r6 F* u5 w" n7 k
  5. ptInsert(0) = 0, K; j+ t  s% n
  6. ptInsert(1) = 0
    : W4 `& w" c! g0 }% n
  7. ptInsert(2) = 0# F4 J4 t" g6 Y  S8 \
  8. & }5 E: Z, |3 R) C# a
  9. 5 @" O3 Y& y: t

  10. , L2 l2 q7 L/ Y9 o# K: f2 M4 C
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '1 H6 n# Q* z* L" z: ^- z
  12. 'lastSel.Select acSelectionSetLast6 l! T5 c  E3 g/ |% c

  13. 2 Y6 e9 q5 k2 G, L- U
  14. Dim B As AcadBlockReference '声明一个块参照变量
    + s3 S' I% ?7 [. P" c7 i! D
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
      W( r7 V: b" A% O* V, M
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ' ~+ r  g5 s" W) B- y4 p
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组' `3 T: t! h( N( I
  18. ' o) m  Z3 W/ w0 a7 @0 Z1 u! O/ g
  19. 'lastSel.Delete '删除选择集
    ' [  u) q" F8 w! T' c" F; W
  20. / l7 q* ~7 I" ]' ?  I" z

  21. 9 m" T; V$ k0 e9 a& u. \1 m
  22. ThisDrawing.Regen acActiveViewport  I' J4 l7 E' H% I/ v; z# W
  23. 7 _: G; s+ [3 J1 ~" V1 q" Y
  24. # @9 N. y; C" |! R- L( v
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 2 j! y8 T0 ^+ V/ p) N% H+ e7 v/ }

! Y) U! x6 ^* i' O% e首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
1 r, i9 D  G- K8 u% T( a; ?* d0 h
  1. pNew(0) = P(0) - 500) i5 j1 R( L3 f! d
  2. pNew(1) = P(1) + 1405.8) G! j; O- ~5 Q! Y" d4 @4 s0 E0 h
  3. pNew(2) = P(2)
复制代码
: G/ T$ K* g+ r7 R
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
. J+ m) S# p" h4 [5 ^# t就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。9 `+ q' j6 C  T4 ^- \9 W7 z
谢谢版主
6 |# _$ i1 J$ t# T; P; K- q
* w( d3 K2 w  G9 B& i& F- A5 S; |- {* F/ i* b
  1. Private Sub cmdInsert_Click()8 n5 T: h; J5 g9 W. [1 `1 J
  2. Dim ptInsert(2) As Double
    % v' A! _- a/ a/ A/ H. h
  3. Dim lastBlock As Variant, Q0 S8 A( ^' z$ ?4 O. n8 V
  4. ptInsert(0) = 0. o8 U4 D8 [9 k1 m
  5. ptInsert(1) = 0
    / E- x5 d' |4 U' z: |# w
  6. ptInsert(2) = 0
    - l8 u; K* z) O& q) A
  7. + {; b4 ~7 y8 e+ L8 d' `
  8. '----------插入块A 仅仅一个---------------------------------
    # h; V. ~2 e4 C4 J( k+ F% f
  9. Dim B As AcadBlockReference '声明一个块参照变量
    * O# a) k) I4 ~) F
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
      @% D& ~/ f3 [9 @! R# \# o7 q& J
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)$ D" @' o- C/ u0 n: ~
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组. i; K; J) n" c- H$ c
  13. '----------插入块A 完成---------------------------------2 S6 d/ V( \8 A  y

  14. . E+ r3 c0 F" U6 Y( e. H
  15. '----------插入块B---------------------------------; |1 y( ^$ {  U4 F* }' o$ o1 o4 [7 O
  16. '第一个块,需要单独插入! C, S. j% a& I
  17. Dim pNew(2) As Double
    - c, |. {) |/ _! o4 e6 ~
  18. pNew(0) = P(0) - 500
    6 g( T' }. O+ }) f; \
  19. pNew(1) = P(1) + 1405.8$ L" Y5 n7 B, y/ a  d
  20. pNew(2) = P(2)6 ^( g7 B4 ^9 t  J2 T6 c) p
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)0 K* X) ~# L  M3 D! k. F
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组& N3 p: r9 U. j
  23. ThisDrawing.Regen acActiveViewport
    # }* Q" a3 t  W  e
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
5 i/ C; S% f, K& }/ [8 f( f6 U! Y* w) r) v! ^
3# tataki
2 B. U% r* }3 P2 n+ J( O" C看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 / I+ v9 t) t. m( l9 x: t* ~
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    2 m+ r6 {' [$ }
  2. Dim MaxPoint As Variant'右上角
    $ f* v7 R" k* U* s+ }
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
( t6 e2 M( h! [8 v! Q# E原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..9 U) }/ _2 V# [3 k6 w/ g
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。. S* N  q4 [' S" J2 G! ]

+ {! [+ m9 R0 E6 m, w另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..: F1 E" G7 C+ y+ j! U8 J, c
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...+ p& |" V7 X" j  x& b% }/ H
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

" @# d: A4 a/ _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 )

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