QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
goto3d 说: 版主微信号:caivin811031;还未入三维微信群的小伙伴,速度加
2022-07-04
全站
goto3d 说: 此次SW竞赛获奖名单公布如下,抱歉晚了,版主最近太忙:一等奖:塔山817;二等奖:a9041、飞鱼;三等奖:wx_dfA5IKla、xwj960414、bzlgl、hklecon;请以上各位和版主联系,领取奖金!!!
2022-03-11
查看: 8108|回复: 8
收起左侧

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

[复制链接]
发表于 2012-4-3 19:49:29 | 显示全部楼层 |阅读模式

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。6 f: C' I; O: L: r0 z% s& g3 K
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
) v0 S1 K( v: v9 L1 z6 z1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?2 u/ ]/ R1 s! i
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
2 o$ @; F' T8 Z) l: V4 t) h4 E# @之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了: j+ n: v- V& A, `- H6 D- |( ]
版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()6 @' d' u. a, x. }* i9 |2 w( @% L
  2. Dim ptInsert(2) As Double! |# b& x- D3 S8 q
  3. Dim lastSel As AcadSelectionSet) B2 C0 {7 i! |9 ^9 z8 I
  4. Dim lastBlock As Variant6 h( d# R' k( n% C# E
  5. ptInsert(0) = 0& b- V( ^% X5 O/ ?" U
  6. ptInsert(1) = 0
    7 U/ r/ P% l9 b
  7. ptInsert(2) = 0( g! z) B5 ?- g
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    : C8 A) o- }/ I( Q0 m& p

  9. + K% _5 J3 `# Y# O6 ^5 F- _

  10. , }* R/ |( i8 G: E: `0 }2 |: u8 k; x4 e

  11. ) z$ F0 k# X2 {
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    # b' [0 B# Q" w4 v! ^
  13. lastSel.Select acSelectionSetLast
    : p% [, P9 ~( F# n
  14. + s- ]9 y9 t6 ^3 R4 Z- @( B
  15. Dim B As AcadBlockReference '声明一个块参照变量3 Y3 _4 z  {" V; H+ Y
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    ' N; g' F. v$ B/ h; T0 @
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量) k+ t9 F% @( [) s
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组/ P3 I7 G- f7 k, C! P' |- _# E

  19. 3 E# H/ C7 Z6 o9 \  q
  20. lastSel.Delete '删除选择集& P2 k) P/ T4 U' k, \! J0 D: U& w

  21. 6 A. G9 E6 P" w1 n, w. Q; X0 K

  22. 1 u" O) M- z& R: w
  23. ThisDrawing.Regen acActiveViewport
    8 l' V5 {. ^; _* Z1 ~4 Y
  24. ) E+ p; D8 M: U0 |

  25. 6 w8 E% Z9 f4 q( t- n
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()2 S3 w* v' C4 p8 Y& D
  2. Dim ptInsert(2) As Double
    6 G- C1 P5 j' B
  3. 'Dim lastSel As AcadSelectionSet1 _6 Q* N  `7 }2 T/ z* c) R
  4. Dim lastBlock As Variant
    2 D8 _- w2 g% X6 X" p. w7 g
  5. ptInsert(0) = 0; P6 P' {  v* Y* r' b0 k
  6. ptInsert(1) = 0
    ' n$ }+ L- i, h" o- l
  7. ptInsert(2) = 0
    $ j) n8 \/ A: k. ]

  8.   q: _+ s3 w$ |
  9. ! D* E/ K: r' |$ f2 r% b$ _
  10. . L7 \0 j$ _; c* R5 g
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '" }: m9 Q& p- c; K! U
  12. 'lastSel.Select acSelectionSetLast* |/ h, `0 W+ L% ~+ P. f

  13. 0 S$ ]! l( L: K0 d; ~' c; g" a
  14. Dim B As AcadBlockReference '声明一个块参照变量: W& C  b# V/ `( R
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    # d/ Z. x# w  H4 U9 J" t
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    5 S9 F( j7 W6 n& E- I
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组, a4 H* }  M: m5 P3 P3 ]( l! H. l

  18. 1 B7 A3 O* W9 f# @+ X2 @
  19. 'lastSel.Delete '删除选择集* o! ^3 X0 B& [( A

  20. 2 t1 p. U6 `& T% S% C3 Z+ Q
  21. 1 d6 F& e8 V! ~' V$ K
  22. ThisDrawing.Regen acActiveViewport; b6 m0 A- H. \2 P0 E; _
  23. 2 g* g5 n, ^, |! J2 `2 I8 l, w

  24. $ r# I& M; f7 h. L3 V
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
# w/ J' e6 A2 Z7 f$ e8 s$ ?# Y0 f7 E
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
2 I3 x- Q7 W$ v7 p9 V5 Z: R
  1. pNew(0) = P(0) - 5000 M; Q- g- }. w; ^$ A% l/ P3 @
  2. pNew(1) = P(1) + 1405.8
    7 I8 [9 O) O) M+ _4 i, [; [* H
  3. pNew(2) = P(2)
复制代码
0 m  \- s; g" X; X
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
9 Y9 N- u3 ^4 F就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
8 E+ P2 c) Z5 q- s; ^" u7 J6 g, O谢谢版主
5 q* p- R1 j4 g7 E7 L% |, l" E  _0 W2 {
2 q! A3 X: p# @5 {7 N) M4 \. I. B
  1. Private Sub cmdInsert_Click()
    % W% X+ i* @* E+ V
  2. Dim ptInsert(2) As Double
    1 R4 T8 U5 o3 ~0 C- |; c4 ?
  3. Dim lastBlock As Variant
    9 M; C$ H1 q* i6 o* K
  4. ptInsert(0) = 0: F( j. Z% ]( _
  5. ptInsert(1) = 0
    4 o0 E  Q9 n% e, @! U
  6. ptInsert(2) = 0$ M9 V$ b7 `4 E/ i
  7. 7 _$ E4 k! c" y, l6 b' t4 E
  8. '----------插入块A 仅仅一个---------------------------------
    / B. F/ L2 Z; m# Q& A
  9. Dim B As AcadBlockReference '声明一个块参照变量
    ( G8 c, o, D9 }/ J3 m0 m8 x
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标/ F2 M& U. h4 H5 w
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)0 ^- P" k9 `8 ~3 ]
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
      }& k3 y! a2 K) C' u- d
  13. '----------插入块A 完成---------------------------------8 `! Z. x, |$ u+ {7 M

  14. * C1 m$ w8 J7 _: M) ?) I
  15. '----------插入块B---------------------------------2 K0 J  p4 Q' f  K+ R
  16. '第一个块,需要单独插入
    ( z3 `: S* c0 a$ q, Z" }
  17. Dim pNew(2) As Double6 @+ z( s. s2 t5 ~
  18. pNew(0) = P(0) - 500- x/ ~* a! Y' e) o* {! s! a0 L
  19. pNew(1) = P(1) + 1405.8( k2 U+ w, Y7 W% ?7 r7 X8 R. v
  20. pNew(2) = P(2)4 [7 A/ w' y; w, x
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)8 D, M4 {0 Z! N: o
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    & b- R, v# ?3 @0 z- a
  23. ThisDrawing.Regen acActiveViewport0 A" r3 c- c- T3 U0 r6 r% _
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
; G* x- e4 U* Z: j. a
* f5 L1 u7 R* P0 D4 I  A; R3# tataki 8 U' l, b, T+ n
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 / }: X( B+ M; u1 P. f/ w  d
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角: ~& U) k& h& z4 Y# M
  2. Dim MaxPoint As Variant'右上角
    , i% Y1 E; D% M9 X, E9 X3 `/ @
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层
呵呵,漏看了一位数,罪过罪过啊!
! |- T6 E4 ?, W# b5 e1 j! I1 p原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
2 N, Z  Q. f2 P2 a' A. G) l哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
) j- @5 c$ N2 H# z0 Q8 N7 u4 H
) U3 p" |2 q; l; L) ~3 Z另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
: n4 e( H& c! {  V" N2 N7 ]哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...: y" Q- y+ X: C" ?. u+ ~
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
3 f6 _8 g( o. A# A
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备13008828号-1 )

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