QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
7天前
查看: 9326|回复: 8
收起左侧

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
- p* W  o( g; {. |- T! b* A  ^其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
9 m2 N- P' @* o1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?% S3 L" }1 p3 ?* i4 q
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?' k- ]! n7 o( p" M$ B, w" Q: ]2 i
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
- {2 ]8 [: D: ]4 z2 W$ p" _版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()/ G  }% a; P+ ?2 D
  2. Dim ptInsert(2) As Double. |. |) c! @! H6 p4 _% d5 {
  3. Dim lastSel As AcadSelectionSet
    0 k; u# F! v% t' b2 R
  4. Dim lastBlock As Variant: U: u) S# f  _1 c
  5. ptInsert(0) = 0
    ; s& C% W7 e) D' u
  6. ptInsert(1) = 0
    6 J6 T5 V3 z) d1 {. s, ^5 f& U
  7. ptInsert(2) = 0& w0 T0 [8 B) A) D( {) j
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 07 O' F, r4 K# ~
  9. 8 c$ ?4 q( ~0 S# T1 F" O" ^

  10. 3 D3 |* T. m! @1 J; k' \, y* g
  11. - {4 @1 a6 d: L) G$ J- y
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") ': \- u1 P5 U& }; i
  13. lastSel.Select acSelectionSetLast
    ' E7 K( U$ o. m- N+ t( A' @
  14. : L0 q/ q" F7 j0 X  O
  15. Dim B As AcadBlockReference '声明一个块参照变量
    & Q7 R3 ]7 l; @# K( r
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    5 A' d5 O7 e( S
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量: M; F/ p# e) _* y% Z0 P
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组) k/ M* z, o4 _5 w
  19. ( Y9 k: b: c+ {% k4 K5 Z2 J' F
  20. lastSel.Delete '删除选择集3 \$ E- y& k; V- r. {9 d

  21. ( d/ n6 J0 V- N$ P/ L; G
  22. 1 ~8 B; i) J8 z9 [. l) z7 X1 h4 s
  23. ThisDrawing.Regen acActiveViewport
    + q9 ]; u$ P) s! B' u2 Z
  24. 7 U) b9 d" c( \* o5 B) W& l
  25. . X# S  U' h$ B* Y/ i
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    : ]% `% F. l! o2 |
  2. Dim ptInsert(2) As Double
    + H/ ]; }' S5 V7 i1 u# ]5 V. a
  3. 'Dim lastSel As AcadSelectionSet
    % k1 P; m- }$ J1 ~" e0 e
  4. Dim lastBlock As Variant: I* J; R; Z$ L3 v, U$ E
  5. ptInsert(0) = 06 g5 x, L  `- r+ S3 l) g8 }- x6 O
  6. ptInsert(1) = 0
    " ~2 K  y) c0 j7 y- f" \) `& |; j
  7. ptInsert(2) = 0
    / l* N! s3 H+ O6 O

  8. / h. [: V7 l0 O( C

  9. ( N2 L9 O5 h- E3 S) a- \7 d
  10. 8 r, D$ F0 R0 ~% }6 r9 x+ [
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '- r2 q4 @- P8 J7 `2 I
  12. 'lastSel.Select acSelectionSetLast
    * l3 O: q4 k0 q1 f9 \- O4 g
  13. 9 t0 k* q9 K5 ^% l+ I
  14. Dim B As AcadBlockReference '声明一个块参照变量5 x! P0 }% {. m9 m/ O# p
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    2 a* D9 X9 q0 l* U/ W
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)1 y, a6 Z3 m' {( h7 U6 M
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    1 c1 Z/ b; C' n" G: A) e

  18. 6 \) m9 z' o; a7 N
  19. 'lastSel.Delete '删除选择集! i, ]  i( t0 t' K/ z/ F
  20. 1 N, W! g+ W9 e0 k- p  c
  21. + k+ n* I. i0 H
  22. ThisDrawing.Regen acActiveViewport
    " s: a9 i" I7 Y' N, R/ f

  23. & }7 _6 l6 k! ^

  24. $ {( Q, S3 h! _$ _6 I
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
  c. [1 f: ^+ Y( K0 A
. M# H- [- _9 e7 ?2 A& t' @* n首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
0 D) D% e/ n5 U+ G, G
  1. pNew(0) = P(0) - 500
    % B7 U  d5 [$ L, p: @- V8 G
  2. pNew(1) = P(1) + 1405.86 w2 [4 s& X8 R4 l2 R
  3. pNew(2) = P(2)
复制代码
: s3 z/ u" C, u* u/ @
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
4 X1 w! M' `+ g0 M+ c, q1 D+ X就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
* A1 p# I# X  V5 f谢谢版主! U+ D7 f. _! X$ M% c
" t) J; [5 E2 z: R8 p+ z# T9 F& l( |

! z) F1 O7 Z+ O6 t0 n& o- e
  1. Private Sub cmdInsert_Click()
    $ z% K) x! ]0 y( o2 j. n2 j: X7 L
  2. Dim ptInsert(2) As Double
    2 z' I6 \; [8 b$ ]
  3. Dim lastBlock As Variant
    ! f, ]9 w" l( u5 G+ s
  4. ptInsert(0) = 0# S# a3 O5 K3 W
  5. ptInsert(1) = 0
    ; p5 c9 B& S3 ^- Z9 a
  6. ptInsert(2) = 0) X4 z# k" O' Z/ H7 G
  7. - ^2 V' h- ^6 ?; W" {
  8. '----------插入块A 仅仅一个---------------------------------
    8 z, f* e2 \* ^
  9. Dim B As AcadBlockReference '声明一个块参照变量8 |, u3 @3 D( |9 @
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    $ q, |! l* s2 X# k4 u/ S" ~  a
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)2 A5 Q: e; N# d. w
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
      k; R& V% F) I3 ~) _
  13. '----------插入块A 完成---------------------------------; E7 A1 Z6 P+ y, f8 q

  14. ( p0 `# k6 t6 B; V7 X  u/ W) }
  15. '----------插入块B---------------------------------
      z+ r# {6 A9 S% E! v5 ?
  16. '第一个块,需要单独插入
    0 q" _- _+ h, ^1 ^  L3 z/ q
  17. Dim pNew(2) As Double/ T) Q! o* l: l7 N, ^2 w/ X* Z# ?
  18. pNew(0) = P(0) - 500
    6 d. I; G0 d# W1 g7 H
  19. pNew(1) = P(1) + 1405.84 I* K: {( U2 r  v8 e3 p1 \) t# P9 L
  20. pNew(2) = P(2)+ {; Q. o7 P7 ^, B1 c
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    & `& f: P& }! |" f0 X5 H% c* n8 O
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    7 ?# t; ^8 j( N
  23. ThisDrawing.Regen acActiveViewport# O( N( m7 k, j1 Q! r. B/ [
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
2 O" k4 K: L& Z5 Q& P6 V' Q* W% D" ?8 R8 X* g
3# tataki   R  ^* `6 I# ~
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
- Q' ~+ k  G+ j- f* O2 l: uVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    % @/ \7 B" S/ G  d! W
  2. Dim MaxPoint As Variant'右上角& e/ a+ t3 P  V5 s( h2 M
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!, L4 S2 V5 \4 s% ]8 ]; ]
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..) @7 R9 H4 C+ Q6 a6 R$ |
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
% l7 |+ k% V# j. e1 h5 Q" ?' x5 y# n& k: d
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
) V8 i8 B; R% e哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
- s0 y- _& d9 F- d3 O% D" F4 Dtataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
4 h+ ]1 h) `: L& Y0 W: r
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 )

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