QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。9 J& |( O8 T+ D
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:, M7 {. ]1 G% W+ q9 i) L
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
7 b. D) j6 k" g7 x: n4 e* k2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
& `* f4 y9 A( I% b之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
( D  g3 I+ U; a: F版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    5 c7 \, `; U# D# ]$ V
  2. Dim ptInsert(2) As Double, J0 x* B: ~) @" V7 e- J
  3. Dim lastSel As AcadSelectionSet) g7 ]" n+ D. G( P; `4 ~1 o4 R2 I( |
  4. Dim lastBlock As Variant
    0 N3 {9 T9 i% S. \1 _
  5. ptInsert(0) = 0
    2 [. I4 d" R, u& k
  6. ptInsert(1) = 04 O% X0 G7 z4 ]3 b) i3 g8 T
  7. ptInsert(2) = 0" Y  U6 t3 I# R8 B0 o
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 01 O0 t) d, U" V% @% E, O

  9. * M/ P+ x3 e2 f; V" W4 I

  10. 8 y: x! m- a' F0 d

  11. : T; s" i) c3 d4 U9 U( r8 s
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    ) @3 u) B1 }7 _9 Q+ e5 C
  13. lastSel.Select acSelectionSetLast
    * r% g' l  D& I# X' f. E

  14. 3 S& V4 j% ~. P7 n# S7 ]2 p! f
  15. Dim B As AcadBlockReference '声明一个块参照变量
    4 V" p3 z+ n/ Y) q2 x
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    & {8 G2 N0 |4 F) }# e
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    & i+ F6 N0 M" u
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    $ R2 B' ~3 z9 u/ c+ T

  19. 0 P- p" v3 R' t2 U) w/ I
  20. lastSel.Delete '删除选择集6 f, y" g$ l7 x& \. @$ k+ f4 p
  21. ) u8 F7 m2 ~8 A0 e. K) S, G+ a

  22. 7 Y4 l! V! b1 l
  23. ThisDrawing.Regen acActiveViewport" ^/ L: p, x' p9 _4 o7 c
  24. 0 ^. Q8 S6 w0 C: ?+ \9 B8 g) x; x4 k5 |

  25. 8 n1 N) J2 |. b3 p" R3 q: {2 A
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    & m2 }$ c7 ?" x7 D
  2. Dim ptInsert(2) As Double4 c* B9 C9 K# V7 \
  3. 'Dim lastSel As AcadSelectionSet
    - V' d% b4 N3 w. P
  4. Dim lastBlock As Variant0 v0 _' b2 \8 B+ x2 B" c' Q
  5. ptInsert(0) = 0
    - B7 ^1 D' N# M1 Q9 u2 ^
  6. ptInsert(1) = 0- A6 [" o8 \- q# t. |3 V
  7. ptInsert(2) = 0
    $ l9 e# |) G; `( Y

  8. / l, p5 h) s9 b( n3 A# j

  9. 2 [8 V1 n0 o( a6 E; ~
  10. ) [- m# u* g0 ^# m6 k
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    0 b; b4 t( t% \. j
  12. 'lastSel.Select acSelectionSetLast3 X/ `$ j2 H. |+ h: P* |* m" Q
  13. + W7 D/ D# ^! a
  14. Dim B As AcadBlockReference '声明一个块参照变量
    4 q9 O7 {+ Q3 t  O
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标" ?  r+ H$ c$ \- i8 W
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)# Y5 X1 L5 m" T4 s$ p: N
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组6 Q. Z* S0 f4 ~9 e- D8 G0 b

  18. / Q! u* y' ?4 [: `( e
  19. 'lastSel.Delete '删除选择集. T1 z7 Z8 J) S

  20. $ o3 [  d) [  n2 O+ H& p0 W

  21. " b; c3 A4 b" ]  b, d1 y4 A
  22. ThisDrawing.Regen acActiveViewport  H5 K# [/ E4 s! k" R
  23. 7 ]9 a( T5 ?4 H  {

  24. , ~3 r' R2 ]5 c
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
7 U0 F; P1 c4 k  J# `4 F3 G0 v' G" P" l& ^5 f
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:9 V: V# \5 B9 o1 f: X
  1. pNew(0) = P(0) - 500
    9 t6 m3 q& x: I8 O. {' v
  2. pNew(1) = P(1) + 1405.8
    ! }( m4 U5 x, D6 w7 M# L1 l# u$ x& d
  3. pNew(2) = P(2)
复制代码
; t  L1 Z  y5 a3 f
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
" n. e$ _* L- _; n就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
- j/ c; t0 C; }  e! v' [' w0 c谢谢版主/ B2 g8 Y/ G6 Q8 u

' ?7 R% @# Z$ ^, A! @4 {1 J  H) X0 Y
  1. Private Sub cmdInsert_Click()
    : t! t" ~  r8 O- L
  2. Dim ptInsert(2) As Double! K; p* A% g) f9 K' i
  3. Dim lastBlock As Variant2 @1 x0 r) B7 x( {, H4 c0 l' [! H
  4. ptInsert(0) = 02 J& u$ _1 Q8 @8 {) \2 V
  5. ptInsert(1) = 0
    : ^4 X6 o7 F! @! ^, h
  6. ptInsert(2) = 0" Y) C' w; Q* g+ I2 m9 y

  7. & ^4 i8 e( x* b" e! f
  8. '----------插入块A 仅仅一个---------------------------------0 m2 r3 A! J3 }! o
  9. Dim B As AcadBlockReference '声明一个块参照变量! |  t3 ^: q; P
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    ) O1 i7 H' w! Q: F0 n
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    6 e. v# v) F# |/ {/ k
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组( y/ R$ {) D/ {7 ~/ V
  13. '----------插入块A 完成---------------------------------
    + D/ K% M/ p$ o5 E  b; Z1 H! u
  14. 0 d9 j( t/ c5 X' K; x
  15. '----------插入块B---------------------------------
    ) Z8 e# X1 ^5 ?; R/ A
  16. '第一个块,需要单独插入2 i* ?% w' X9 l5 F( F: ]& u; r& V; w
  17. Dim pNew(2) As Double6 ^7 v% b4 }$ q+ E. q/ C9 T8 `. T
  18. pNew(0) = P(0) - 5006 I5 o% H# b2 @
  19. pNew(1) = P(1) + 1405.8
    - ^& W6 g) k' C! Q' x
  20. pNew(2) = P(2). |' r0 s/ z! w2 g1 O
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)) o1 Y, `1 C, U) b7 {
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组% W0 m& {/ h, g1 e
  23. ThisDrawing.Regen acActiveViewport
    : ]) |* I% M* i( [% F! w+ h  H- {
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
" v+ d8 F/ W# u
2 ?8 _& }& Y9 o- j0 k3# tataki
/ E0 s) U' w! Z3 P& Y( K4 }5 k+ {: _看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
& i, @: O0 [7 ^8 O6 w  K  j1 FVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    3 Q4 m. p" `( K8 a( f. h) y
  2. Dim MaxPoint As Variant'右上角
    0 h9 d3 r- Q& y+ A  b1 e* A4 m
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!1 l' D) f* r8 a+ s+ d- u
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
* _7 {4 J% W: g3 {/ l) U哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
  @3 F; C2 O! h" n2 o" O' u8 c6 `. e3 E  Z$ v2 r! I4 _/ v9 u
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
4 F7 w. I$ @8 S哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
* P# o8 M2 {6 B0 h! i3 ^) ?tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

* T. w  P8 u. rlisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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