QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
6天前
查看: 8936|回复: 8
收起左侧

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。# v; |7 j) j# @# X( I
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:7 d' Z+ E7 s8 ?( P
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
6 R2 g+ G- R- |. Z2 k2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
$ ]: t  g9 k/ N$ C: C之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
, Y7 V  |# ^) h% d; a版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()! H( F0 N7 E! f1 ~6 w6 {) {1 p
  2. Dim ptInsert(2) As Double' S" \  D& p. F. y" V
  3. Dim lastSel As AcadSelectionSet  g. @" O7 ]$ J" m3 V2 ], T2 o2 p
  4. Dim lastBlock As Variant
    ! w' }, K5 e$ g" |: N; N
  5. ptInsert(0) = 0: f) R7 {3 B2 U/ q  B9 ^8 {
  6. ptInsert(1) = 0
    / T  B7 }& ~, S# I# v6 Q
  7. ptInsert(2) = 0
    1 O6 m  }( s4 Y) J; r7 n2 O
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 07 k8 M) l; F2 m" O
  9. 7 Z; T6 u, D5 J0 @/ z8 D

  10. ) m. u/ q% Y! g; X

  11. " \" g4 C# {9 ?
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    7 e" H8 u9 O' \* ]; v
  13. lastSel.Select acSelectionSetLast3 c6 t; k. ^8 o* W) E4 q
  14.   v3 Q  A8 v! B4 g4 r* C
  15. Dim B As AcadBlockReference '声明一个块参照变量6 m( H$ P0 ]5 C' W
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标: C3 u9 K# f$ |  ~1 F# A
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    % m2 [" p6 {$ y0 W4 _
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    / }3 x( I+ G% m6 U; A

  19. , q0 I3 k3 D3 G) m5 i
  20. lastSel.Delete '删除选择集: a1 e/ \. N* u; \

  21. / I! ^( Y1 @7 R7 q
  22. , [6 e; Z3 s6 q: f; s4 N
  23. ThisDrawing.Regen acActiveViewport
    / x  ]7 Z: G+ Y. l2 o( r' F% [. ^4 D8 l
  24. " z1 o+ r5 E7 |/ r
  25. 9 E+ U- W( l& A9 g
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    3 j6 x* c8 [6 Q* W$ o9 ~4 t8 {
  2. Dim ptInsert(2) As Double
    " `+ \) h+ q: D4 O: E% d+ {
  3. 'Dim lastSel As AcadSelectionSet! w  x8 P- O* C" Q! K
  4. Dim lastBlock As Variant
    3 k) R1 B0 }) k% a9 G, W' b+ W
  5. ptInsert(0) = 09 `1 o4 K* s1 H3 m1 u8 ~
  6. ptInsert(1) = 0
    6 H* e) X+ I5 _7 D3 y
  7. ptInsert(2) = 0
    8 t8 S- m# L3 ?% a( Y! G- Q8 K" f* e

  8. : U$ ?) W/ [' P  W  O( q+ s
  9. % m# N8 P1 ^3 X. v5 e* Z3 E8 P
  10. * B5 k" U# u, D9 d2 d
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    - _+ D* A, `* N3 l! ]. C4 W. R
  12. 'lastSel.Select acSelectionSetLast8 |) A2 X' o2 x& d) G8 ~, M: f, X

  13. # C& j- @8 R$ U5 s/ o" k; O; p
  14. Dim B As AcadBlockReference '声明一个块参照变量  U0 d/ r5 L1 t4 U8 v1 q
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    3 |/ i7 s! V7 T1 I2 s
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)" O2 }) a$ D& M( B( ?& c) b
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    " b" ~$ m0 F/ f# F

  18. - K1 n7 V" x4 P& ]* _7 k
  19. 'lastSel.Delete '删除选择集' q7 j- B/ k0 j' b$ P
  20. - M9 l* ?1 |( J1 J9 D

  21. ( ?  @% A' N8 u) s2 ~# {
  22. ThisDrawing.Regen acActiveViewport
    & l: _6 w* Z, E* F$ h6 k4 {

  23. 9 y. p9 B  x# P. t$ ?

  24. 9 s$ o# g- x) r
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 : x8 D) M5 ?$ _7 z. F: c

! |4 x7 m0 G# B( b* M2 l0 m首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
# H" c5 ~# `2 M1 T) Y  m: X
  1. pNew(0) = P(0) - 500
    ) Y% t+ J8 e% i5 p' l* [7 B( R+ [
  2. pNew(1) = P(1) + 1405.8
    1 m- N, q1 |3 E+ N( y# O+ V
  3. pNew(2) = P(2)
复制代码

0 y/ k0 |3 Z* r0 e) `2 f我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
. ^7 o4 g3 p/ T) N4 F) p就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。9 h9 w* i+ m4 n' R; k/ Q
谢谢版主
  b/ U' |; X1 @& {0 Y( X4 |
) A' S+ z) T) @7 N1 C' ^3 N) r3 H- T0 [( y/ d
  1. Private Sub cmdInsert_Click()& F: _6 D: x% F: K
  2. Dim ptInsert(2) As Double* K( F2 X8 v7 `, S
  3. Dim lastBlock As Variant. x0 h# A  I& }$ Z! V) F& B" y
  4. ptInsert(0) = 0' d4 h3 Y4 b- |$ x
  5. ptInsert(1) = 0
    ' f& P$ D( z. ~# U
  6. ptInsert(2) = 0
    % x. _! |. i- O% w* C' o

  7. 9 E! x" h0 X# }! C0 V5 f
  8. '----------插入块A 仅仅一个---------------------------------
    6 u0 u6 E% A; [( v
  9. Dim B As AcadBlockReference '声明一个块参照变量
    1 M* z) O) O: A: g3 b  R0 K
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标2 x3 @7 S* C$ Y  w: S0 Z2 ^' N1 `
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    & x7 Q) K: {8 n
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组" f; t: U7 L$ O& Y# m
  13. '----------插入块A 完成---------------------------------
    ( E: ~$ x+ n! s; a) t* \; ]

  14. ( ~1 K  L6 C, Q; e4 ~' u
  15. '----------插入块B---------------------------------- j" [  e1 v) @/ ~5 G6 @, |
  16. '第一个块,需要单独插入5 G5 i" `# ~3 U' i! q
  17. Dim pNew(2) As Double' k# d7 W/ r6 q. I. G! O
  18. pNew(0) = P(0) - 500& o; g2 g0 u3 G
  19. pNew(1) = P(1) + 1405.8
    # q" W0 e- ?; K& Q# E
  20. pNew(2) = P(2). @& R4 a  A! e! A5 f
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    " E; e' X1 f" R1 B
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    6 C! ~( w# o' m! U% W& M* K2 W: F! @! N
  23. ThisDrawing.Regen acActiveViewport
    , ^$ |1 _! h* S
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
7 W9 n$ `  T7 @. i+ L5 |+ C7 @: v
* I9 k  Z$ y+ M# L4 ^5 K  G3# tataki % u  g3 M1 B2 B3 X. h
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 1 e& u9 V/ b4 E3 ]# I
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    % i( O2 ?* w2 |; T5 s
  2. Dim MaxPoint As Variant'右上角7 i, V* E0 {5 p8 c' Q
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
3 t6 o) i3 [0 S5 t9 P0 o7 d0 P原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..% f4 Z' g' i; d
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
6 G  @% a  m% M+ W& W0 c
6 b4 a& h' B$ a& \1 O3 @( Z- X另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..+ ]& s/ }1 I* Q' d
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
! w6 ]  t1 `! e* q- ]; M, ctataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
: r% v! G6 S2 p" `! v) R1 ^" }
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 )

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