QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
2 s0 M5 N! Z* Z7 v/ G其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:$ O2 J& k1 F5 z+ S8 J- w
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?$ ^1 m! {6 ?- X0 M) o  w0 Y
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
. N8 |; R5 x  v之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了# O$ A' i# K% X1 \. B; P  d7 D9 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()
    ' P" U5 r; a3 t
  2. Dim ptInsert(2) As Double% T7 a& G6 _! J4 z' ~
  3. Dim lastSel As AcadSelectionSet
    " G+ v: o$ }- S- q9 q0 e0 ^
  4. Dim lastBlock As Variant9 b4 s! Z' m8 y
  5. ptInsert(0) = 0
    7 B$ l' m% P# {( K
  6. ptInsert(1) = 0
    2 Z% W& m1 ~1 M
  7. ptInsert(2) = 0$ c% h( {4 C$ m* A/ ?, H1 n
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    & [- T1 q. j% [, }) f! q) ^7 S: r
  9. . l/ {! k/ Q! R9 e4 m( m' ~1 |

  10. , A+ ^& C3 f& }$ m0 S

  11.   h* k9 [& _# {! x
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '( J# B( u5 R4 o* }+ R% c- e0 o
  13. lastSel.Select acSelectionSetLast+ I0 e& ^2 I  j3 u6 n( T* S
  14. 6 p) n4 h: g: B1 P) L7 p' w
  15. Dim B As AcadBlockReference '声明一个块参照变量
    . o/ D* D6 F9 @
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    " r- t9 w4 ]# a5 f, `  N. r
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量7 l& o) V7 ~1 I( r, [
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组4 x9 E. R# O/ _' \: l1 h6 q

  19. : N) Z. U$ x7 H( I
  20. lastSel.Delete '删除选择集
    $ u. n- E8 G$ R9 q1 K
  21. . n, b8 K) [! C; K
  22. 6 k- |4 B  @0 V" V! F2 U" T
  23. ThisDrawing.Regen acActiveViewport0 f3 y6 l; C. m. K+ m7 i$ F( t% [8 u

  24. ! t( Y& n9 j; p8 H: Q
  25. 5 v' ^3 s: a( w, f+ E
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()& p0 x% `- [. U* h/ q
  2. Dim ptInsert(2) As Double+ l7 K+ Z3 e9 k/ z) Y
  3. 'Dim lastSel As AcadSelectionSet
    " N; n7 L/ \8 A3 m- W
  4. Dim lastBlock As Variant
    " l& @, L9 f2 M2 N/ _' w" t2 E2 |
  5. ptInsert(0) = 0
    & c3 F. |; }( L+ x9 J. m
  6. ptInsert(1) = 0. t1 @4 B8 W% L2 x, ~5 n" ~
  7. ptInsert(2) = 0
    # u- f6 @" q* S3 J4 B
  8. ! ^5 D1 ]6 i5 t- n

  9. , A6 u% ]% @: \! a6 f

  10. ' p& A, m( z8 v/ z" A( b
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") ': j4 B/ a5 i& I( K; w8 G
  12. 'lastSel.Select acSelectionSetLast- X" B- h* {! o, z

  13. ; M6 s1 Q8 ~8 Z5 M$ r
  14. Dim B As AcadBlockReference '声明一个块参照变量! S2 Q; j9 F1 l" c. s& R, p
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    ' g8 w5 W5 [6 @1 ~6 z% N9 U5 ?
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)1 c- _7 _% P3 d! R4 v* x9 q
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组+ A3 m$ U/ I. O

  18. 3 N' P4 C2 v3 }5 D0 N" @* R
  19. 'lastSel.Delete '删除选择集
    + K6 @$ k. [/ z
  20. 2 Z. l% D- }# ]! ?3 J$ k% [% p
  21. 8 W2 e, |  d, A
  22. ThisDrawing.Regen acActiveViewport7 J4 Y2 J$ e  I

  23. 2 k1 R- a- |" _( k8 a) \2 [6 Q- i

  24. ; y1 t  z$ M( j: _8 _+ ~. x
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
4 ]6 j* P9 n, {7 y! x! v
% ~* J4 b) ~3 ^9 U首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:+ j' \3 r+ I, {. W6 k( W0 B( _$ f
  1. pNew(0) = P(0) - 500
    / d1 x& G: J6 w" S$ G$ c* v, B
  2. pNew(1) = P(1) + 1405.8( [8 U; A: O( v, g
  3. pNew(2) = P(2)
复制代码

8 f: D. H; J3 `$ V( T' w我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
- p# I1 O( g: Y: v就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
4 O3 r$ X) W/ T$ W谢谢版主
7 ~% |9 G- C8 P. Q, B* a2 F
3 H( a8 e/ ?$ E$ J1 k" p* n
- e( x# ?3 i" N* z6 q
  1. Private Sub cmdInsert_Click()6 J2 _& E& W5 {
  2. Dim ptInsert(2) As Double
    % f0 T4 Y8 f( ~: W5 A% c2 J
  3. Dim lastBlock As Variant* }- f& q; m  k2 g4 z
  4. ptInsert(0) = 0* l$ m1 |- v+ E; v+ g  ~( {
  5. ptInsert(1) = 0
    ( e$ h, c3 v/ ?" X( R
  6. ptInsert(2) = 0- \$ s( P( c9 y& W, C) Z8 h% F

  7. . r" f7 H9 ~: Z8 i$ o( y2 x
  8. '----------插入块A 仅仅一个---------------------------------( }. ?  U6 v5 [8 v* f
  9. Dim B As AcadBlockReference '声明一个块参照变量
    + k$ b4 t1 Y+ k7 [' H/ \; j/ U) C# ~
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    9 W+ A$ \1 l6 s( \( F( C
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0): N( }6 _' S* f0 ~- o2 o3 q$ `
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    6 E( I: i2 \2 Y+ Z7 I: |, k
  13. '----------插入块A 完成---------------------------------
    0 ?! ]8 q0 Y  @& Z- Q, P( _

  14. ' Z) c2 O8 e0 Q4 o$ \: b& C
  15. '----------插入块B---------------------------------0 J+ p9 z, t' d1 V" [% H3 _
  16. '第一个块,需要单独插入
    . z' h  C) k& ?) D, p" u
  17. Dim pNew(2) As Double
    ) G6 f5 ?. \5 z4 Z8 m- }5 E
  18. pNew(0) = P(0) - 500
    9 a- m; c( g0 a7 `' J+ ]5 @! O
  19. pNew(1) = P(1) + 1405.8
    - D- i9 A6 O3 o8 H) {
  20. pNew(2) = P(2)! ~: Z4 @3 W% w, Y7 p' Z
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    % ~+ {  v. G+ t: Q9 I
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组9 \$ \, X8 r, j: p
  23. ThisDrawing.Regen acActiveViewport
    ; u& N8 g! w  d
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 3 O! H4 Y! N* o5 }. {  m. }

: ^  o- m0 X: h3# tataki
" b. `- i/ f& f+ \$ Q看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 / ^9 S$ W" a& {' W  ^
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角! ]4 i" E- e0 j8 q0 I
  2. Dim MaxPoint As Variant'右上角( }* w0 Q- B4 {$ W
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!  {6 U# V- i* x6 I5 Z: [5 S& N+ d
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..5 P" ]' J5 W2 b
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
) Y: T& c1 w. @$ H6 R9 B7 C
* G6 z' V* l5 d4 S: U6 h另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..9 o) L4 T( b5 q9 w5 n: c" Z) n
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
$ Y/ _; Q3 ~' a- i& m& Ntataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

; ?, H( d$ ~0 nlisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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