QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
7 ~3 C; q1 n2 `& b- S  X0 C其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
; _4 M8 G& ~8 o  W) g1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?# r- U) ^1 h: G& }( B
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?# c! k/ {& J1 T0 i1 F: k1 d8 k+ A
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了4 v& y: ^4 u1 N
版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()7 a3 a; m' |# W5 ]
  2. Dim ptInsert(2) As Double8 _8 R; b" S9 e( ^$ p$ o: e8 l: f
  3. Dim lastSel As AcadSelectionSet
    1 m" l6 t  K' S5 B& K
  4. Dim lastBlock As Variant
    % Z, S5 l* m6 T7 N6 c5 T5 t
  5. ptInsert(0) = 0
    " u) A- z0 ?, }0 E( g
  6. ptInsert(1) = 0
    8 k3 I( @! j" N0 Z" ~9 j
  7. ptInsert(2) = 0/ J5 z% Q0 b  O
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 03 _2 _' t4 s) i; A8 a
  9. * M* |) ]1 w: L
  10. 1 C" F, Y7 I, Y  j0 Z
  11. ; l. n/ S0 o. |) e! U) M+ ]
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '/ X8 A$ y) U) i
  13. lastSel.Select acSelectionSetLast
    5 C# x0 D1 I8 P
  14. $ m3 W  m4 V2 E' M9 s5 y: }
  15. Dim B As AcadBlockReference '声明一个块参照变量2 a: n1 y1 S. G8 V' c; F
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    1 K$ Y6 r  @3 b, e9 E
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    % y: `- T3 E5 j' ^' Y
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    0 `9 v# ^5 K1 E' U

  19. * C; `$ U4 b2 n2 W# P% z3 D
  20. lastSel.Delete '删除选择集0 H, r* h. g: M* L' g4 P
  21. , S3 I; j- Y6 H7 S* Y: K6 o) h/ R' `* ?% Q- Z
  22. " X4 d3 X' t. o
  23. ThisDrawing.Regen acActiveViewport% q* p7 E6 ^* X! ?% F
  24. 5 t) C) S! h0 a* G6 \. A

  25. ) o4 h. v1 m" R/ ~  M: s' ^
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()( h  [4 R- u2 T  I' q
  2. Dim ptInsert(2) As Double
    % b' `' y' e. ^
  3. 'Dim lastSel As AcadSelectionSet
    + q! t3 t6 P! M: F5 m
  4. Dim lastBlock As Variant7 s) B" u  i) Y1 Z, L
  5. ptInsert(0) = 0. O  d0 p: }4 I. q9 Q
  6. ptInsert(1) = 0/ N' K8 u) P7 ^7 A0 H* ~% m
  7. ptInsert(2) = 0% H) ^2 J3 p- R& F# R. K4 m% [

  8. 0 G2 W6 k& v( s' ^: ~' i  N/ e
  9. 1 f* j3 [1 `6 ^0 f7 l. V- A

  10. 2 T0 d3 T& e: F0 ]  g; j: G" Q$ g
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '/ M& f0 p) }7 n8 @4 v
  12. 'lastSel.Select acSelectionSetLast
    ; m8 `0 t5 F; ~( U& o. p9 X
  13. 2 V4 v$ D+ u; q# C* r% a7 p
  14. Dim B As AcadBlockReference '声明一个块参照变量
      j/ y/ g" r" U1 }' D2 o
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标. _8 d/ m  B7 @. S' q4 m# m
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ; V# F) [/ p9 o: M: H( u  K
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    . z0 K& ^# x5 D, i. R% j

  18. ; {. Y- @# e0 z3 y- w
  19. 'lastSel.Delete '删除选择集4 ~; H) O5 k- {- C) k7 x; K

  20. % m# Y! Y/ E( B. \2 }9 @6 G, ^
  21. 9 w$ }9 {( ?1 e* R" L
  22. ThisDrawing.Regen acActiveViewport
    " G# ^& t$ z5 L) h

  23. ! |* l: ?1 U( s0 r0 O: v

  24. 0 j. q7 n: P% k
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
( g4 I$ y8 }" ?! s2 a3 f
2 |- |; D. A* U. w# L首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:: F3 P2 C5 z) w8 G
  1. pNew(0) = P(0) - 5002 V; L% S; G) d: s' W
  2. pNew(1) = P(1) + 1405.8! F8 y4 J* `/ H8 R. y
  3. pNew(2) = P(2)
复制代码
% x# N% M% p1 W6 u1 H* v
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?, D5 V! h6 s' W6 P
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
. u, x0 V/ k! V2 @* |& f) |谢谢版主
: X# E! \! M' B. _% c( }9 G
! P& V/ J# y) _7 b) y! W. |1 R) E4 {  h- a( ~5 @( C3 P- F5 a
  1. Private Sub cmdInsert_Click(). n! w0 J4 C2 s1 A
  2. Dim ptInsert(2) As Double. W/ W, w  o3 ^# G' w4 J% \
  3. Dim lastBlock As Variant; P8 S5 W8 F2 e9 a
  4. ptInsert(0) = 0& j$ B( K5 ~; H$ R5 G" o( Q" {
  5. ptInsert(1) = 0
    / ^# j3 ~# ~$ ^  x  U( A
  6. ptInsert(2) = 0
    , k4 M" V9 N* k1 [: `
  7. 2 L; [& o% N1 V  i9 _& E
  8. '----------插入块A 仅仅一个---------------------------------* \2 `4 T9 v0 u1 c* A, ?
  9. Dim B As AcadBlockReference '声明一个块参照变量( J6 F# [$ X6 X! F9 @5 U6 y6 O
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    4 f. H* {8 @3 ]2 y7 v6 c$ o2 z
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    , ^! }0 y6 d3 O: I& T) ^
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    0 `! n! A  a+ F: \  U( ^
  13. '----------插入块A 完成---------------------------------
      u5 {# V" |! V, n5 H6 p0 g

  14. + x# [  a& g( f0 D; K. _5 W
  15. '----------插入块B---------------------------------, Y& l: {! V# A8 l6 S
  16. '第一个块,需要单独插入5 i$ O. p# f) i8 y9 j
  17. Dim pNew(2) As Double
    - m' n1 g! @8 c0 R0 u* m1 }$ M
  18. pNew(0) = P(0) - 500
    2 p, s' C: c% f- y
  19. pNew(1) = P(1) + 1405.8
    & f  k2 w( A2 t& |
  20. pNew(2) = P(2)
    3 ^$ I* s9 ^" X+ \
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)8 w: y' O  v6 u9 }( X. W* x) |
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    " D0 \. [5 ?# h' s& l/ B& k; j% Q
  23. ThisDrawing.Regen acActiveViewport
    * ^. R0 x  y5 ]: U1 W- P/ V
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 ' b# |! K$ m/ t
0 ]1 i4 d9 W/ p  {3 k- x
3# tataki
) j- }3 H! W% M) y+ {9 t2 L' s看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
7 z  c* a5 n- l$ s1 N! GVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    + J8 ~3 w( x" e9 ~2 _
  2. Dim MaxPoint As Variant'右上角
    . X5 }/ a0 m+ R9 N
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
" ^* p0 z* L5 i原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
# k' h# Z- A6 P" n/ i哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
; S6 Y+ q: Z9 F* E8 R2 V6 c/ o: _' U* _
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
9 n: @% ^) S3 N1 B. N哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...& o. K, Y2 O( s! [; ^
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

8 {8 v+ i3 b0 xlisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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