QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
7 n" w$ \) k. J1 b/ i其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:4 ]3 D) q! p* l
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?+ l1 ]/ Q) D2 |
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
  B& g9 u. F3 Z& Q7 M之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
# q) a1 k& P/ B5 t) D+ l版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
2012-4-3 19-29-23.jpg

块自动插入.dwg

42.84 KB, 下载次数: 10

InsertBlock.rar

7.03 KB, 下载次数: 7

发表于 2012-4-4 08:29:21 | 显示全部楼层 来自: 中国辽宁
方法一:按照楼主的思路使用选择集
  1. Private Sub cmdInsert_Click()# ]2 O- |  w7 k0 c; [
  2. Dim ptInsert(2) As Double
    & M  y+ X" b  b0 B% d( P3 a% j
  3. Dim lastSel As AcadSelectionSet
    $ @2 n0 R5 p4 E$ F! ^
  4. Dim lastBlock As Variant
    $ a# U6 a. p( U$ ~# s3 D
  5. ptInsert(0) = 0
    , I6 |5 _# a' i) z
  6. ptInsert(1) = 0' i$ n, [. x4 Q9 Y' n$ I
  7. ptInsert(2) = 0
    $ E3 X9 z6 g6 S* }
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0+ G# q+ w  R9 j

  9. 0 ?; ?, e6 q9 H7 ~/ {  H4 |& c- {

  10. 4 Q# e# j" {: m2 }

  11. - Z: u# L' W& O, S, V5 ?* r; |
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    ! g5 d1 X, R% V# \: t
  13. lastSel.Select acSelectionSetLast9 r+ @# y* t, L4 N
  14. 1 a- M0 h1 D7 h# I$ r2 U+ N; p! |
  15. Dim B As AcadBlockReference '声明一个块参照变量) G* q5 L4 g: I3 ]
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标( r' Y& N& c9 t# u2 x+ m+ y5 k
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量6 ?+ z' h/ A8 d* {
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组- E: q: o7 ^. Z0 l4 H/ d% M
  19. : P. p% r5 \: {5 |2 m" {
  20. lastSel.Delete '删除选择集
    # ?+ q/ F$ s  Q1 {
  21. 1 U5 ]8 l# f) {0 t$ V
  22. 5 p8 d# c6 G; X- R3 d+ x- \! k
  23. ThisDrawing.Regen acActiveViewport
    ; q& C3 T& v  h/ r# f; `
  24. 9 ^3 E3 q/ M3 e9 v
  25. # N" Y$ ]. G9 X/ Z1 X
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()6 b4 w) b6 G& \0 h/ t+ |2 e3 c
  2. Dim ptInsert(2) As Double
    2 L: P& b" {% c, z& t, l
  3. 'Dim lastSel As AcadSelectionSet
    ( K: O) _2 t0 ?2 O  @3 J
  4. Dim lastBlock As Variant% }/ {- q, h- ^& d( W  D
  5. ptInsert(0) = 0
    , d' z0 \: r3 O. u
  6. ptInsert(1) = 0
    8 R/ C5 Z5 y0 Z1 P& O
  7. ptInsert(2) = 05 b% L& }& i' r3 z

  8. , B. R6 c5 e+ a& E/ Y

  9. 6 F* `! C$ i/ v! T  r

  10. 4 _! N, |( X2 ~8 H0 m5 P% b
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    0 U- t1 [) G. l+ g/ }
  12. 'lastSel.Select acSelectionSetLast
    ) x. V/ w/ X3 Q
  13. 8 k1 i, o) j$ o2 Z% P, C7 v
  14. Dim B As AcadBlockReference '声明一个块参照变量
    3 u8 R3 D2 b1 V' m: T
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标% u5 `1 H1 V% J# R
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    9 x$ ?4 l: [: C8 x! i9 @( T3 E8 L
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组! r) D7 M' m0 X

  18. 7 x4 P& E8 V! g! n4 b0 f
  19. 'lastSel.Delete '删除选择集# c, Q- F. s, a" e

  20. ! w* w3 G& u2 Y8 ~& o6 c8 N6 d; k
  21. + v) c" M$ R' X% U  q' Y! s- j
  22. ThisDrawing.Regen acActiveViewport
    9 ]4 u) A0 A8 t5 E8 j- Y3 ?! m$ c
  23. # j/ @/ c. A  V( E
  24. + X: N& l8 f' _7 H3 }
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
- M* U. F% |( U1 U! x/ Q/ L' s
9 m  O# ?# S& _) r$ c2 o  o9 D" l% a9 }" ]首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
: f: _/ b6 P) o% ]* {! {- ?
  1. pNew(0) = P(0) - 5003 B  j( w; G, w2 ]0 p
  2. pNew(1) = P(1) + 1405.8; d9 H/ U' ^+ K/ n8 s% D) _
  3. pNew(2) = P(2)
复制代码
0 D/ h, B1 v; T
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
$ q) N; H' e! l7 j. _+ K就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
" k1 ]4 e6 z0 Q( D4 v2 a" l7 S谢谢版主
3 ~5 f+ g. L9 _% R6 g
$ V* s) Y- E: A/ {% s; i
/ p: h( d4 S9 c4 z* O
  1. Private Sub cmdInsert_Click()+ l& ?6 c4 B6 g" J: u9 u' X5 }
  2. Dim ptInsert(2) As Double
    1 c% O# G8 ]6 |
  3. Dim lastBlock As Variant5 O" _4 P9 H% A: O
  4. ptInsert(0) = 0( s3 B: |1 J  f6 @
  5. ptInsert(1) = 0
    5 K2 [$ o3 ~* }6 h  d. P
  6. ptInsert(2) = 0
    5 l& O. h- d/ M+ O, Q
  7. $ u. N" i1 O0 l( @+ D
  8. '----------插入块A 仅仅一个---------------------------------' V: z" N9 S9 R' m- c
  9. Dim B As AcadBlockReference '声明一个块参照变量' ~8 s# o) T, O- K1 `7 j8 _
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标. C/ J. w7 ^" i" n9 B
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    6 f5 h# `; I* U9 X4 a/ H
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    & L/ k2 c" D: g8 C7 I
  13. '----------插入块A 完成---------------------------------$ u- o/ S! L. \1 n7 [4 I

  14. 3 \, O$ I3 ]$ c, h& |7 M* y
  15. '----------插入块B---------------------------------
    # y! D4 @- ]" j" c' ~* j3 \" s- r2 ~
  16. '第一个块,需要单独插入
    : z- c) a/ D% }6 }# S* S5 S6 |
  17. Dim pNew(2) As Double! _0 V* x5 |- E! _$ Z# f
  18. pNew(0) = P(0) - 500* f0 T3 p2 q2 g2 V/ v
  19. pNew(1) = P(1) + 1405.8
    1 d5 w4 K% m8 ?
  20. pNew(2) = P(2)
    ( b1 E6 S3 l9 W' d9 D: a
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    & t5 t- E: P0 b: b* p$ Y
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ) y' {% {) w7 z* r# J
  23. ThisDrawing.Regen acActiveViewport& P5 T7 N9 r9 v
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑   W- F/ \- g( q9 N. Y

: m, ?3 A3 \0 [+ E( K1 R/ n, k+ p3# tataki
* N# Y) i: B4 t& C& k6 o! ~3 g看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
3 C8 Z) H# u$ G2 c* cVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    & j% Q. {4 G$ b' P$ m
  2. Dim MaxPoint As Variant'右上角& T$ t0 I$ ~# Q0 j/ Q! @1 J) R& ~' k
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
8 x7 L9 T8 e" E5 g原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
1 `) E/ ~8 }% C哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。) y: |6 O1 L: p% w, \

, j" |5 n. h. G另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
. M& E1 ?2 S! U$ T3 h$ x: |+ X  a0 E/ @哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
/ `9 Q) u* o$ l6 _, stataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

: F& j1 n+ b* U5 S3 O4 Y, _! n" H4 slisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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