QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
! H: I- {" w  D$ U其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
, ~8 _7 W1 G" u- m- S1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
1 Q7 p$ p5 u& S7 h3 I& C1 w0 V( ^2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?- l' l  H: B9 s4 |4 s
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
$ c0 }) Q  b. T. t% I6 c2 V版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()/ a, g, w# s' e! ]  d/ h' ]9 J7 u8 W5 V
  2. Dim ptInsert(2) As Double
    5 J5 Y% E/ }2 o
  3. Dim lastSel As AcadSelectionSet1 L' h2 D4 L0 |, }# x: F
  4. Dim lastBlock As Variant' J& @, D' d4 R) \' A
  5. ptInsert(0) = 0  h+ d) g4 N0 t) D
  6. ptInsert(1) = 0
    1 q  D) B+ Z7 ?1 V) I8 W% Y0 K; D4 J
  7. ptInsert(2) = 0
    8 D* U8 ^$ Z/ F  j. m* ~, Q+ e
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0* H7 ^- S/ q7 u9 ^
  9. $ l2 r! w: [- Q2 H* w0 D0 g

  10. ) g9 `( W) C; Z; B8 D
  11. . `/ X0 Y* @, R# H4 f
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '4 u; ~' y! ~: _% n
  13. lastSel.Select acSelectionSetLast
    $ s" R& v9 O& Q1 T. p8 ~
  14. 7 U& d1 E: \7 N; p: y
  15. Dim B As AcadBlockReference '声明一个块参照变量
    , w9 B0 q7 g8 M7 A) i
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    6 @# ^+ a. e, E
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量' l% p5 u1 N2 [
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    % w3 ^6 n, {+ p: G5 b' U# D

  19. $ e/ Z" O8 f, _+ i% M6 Y
  20. lastSel.Delete '删除选择集
    4 L& `( Y; K% t) [7 \# F- |
  21. & e( _% e( j7 q
  22. 2 X: I4 n& R: k. z( j. S' a
  23. ThisDrawing.Regen acActiveViewport2 n' s, M5 g; H) B
  24. 0 L4 A0 E! a4 C- X$ e) D
  25. 6 ]& Z! G& E: j0 E7 a8 K( w3 b
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
      m/ G" O8 ]% L3 i* E( m
  2. Dim ptInsert(2) As Double* f( z" m/ u/ G0 T8 V
  3. 'Dim lastSel As AcadSelectionSet
    ) D& d/ U+ A0 L% O( y, \
  4. Dim lastBlock As Variant
    ' Z6 P; d3 b  t( W+ Q
  5. ptInsert(0) = 0
    # i& [8 r8 W( [  G+ w
  6. ptInsert(1) = 08 g7 p: {& [7 ~* {1 p
  7. ptInsert(2) = 0
    # z8 X# ]5 N; Y* h, H% Y

  8. 3 c$ S5 U1 k3 M( @
  9. & @2 Z" Y& R( S/ D3 H
  10. . W4 h' y$ a+ O- z& O( Z% o9 N
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    / M" y5 g2 J5 s! Z  w
  12. 'lastSel.Select acSelectionSetLast! A* u. I3 K3 j* Y

  13. , r- E; |1 q: l/ a
  14. Dim B As AcadBlockReference '声明一个块参照变量
      J/ B  n$ N. ?
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    7 k7 Y# A8 b$ C1 z
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)& |# B0 x- B4 k; b2 j+ D
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    1 V- B2 ~* t2 ~5 V- s+ T% L
  18. ; I* y9 `5 o  `1 Y2 Z1 B' M
  19. 'lastSel.Delete '删除选择集6 t9 n! o! V( s) @$ W

  20. " G+ ^- {4 t+ ?6 d; B% l0 g. Q

  21. 4 w9 q9 U8 R* L# ]1 S
  22. ThisDrawing.Regen acActiveViewport
    2 l$ s! @( C# R" r( N

  23. + Z+ h% f% p3 ^$ l
  24. 7 ~* S- b) ?; T, d
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 8 H4 e# M$ C. p6 _
. N, p' v3 y) h
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
; s, z" [0 a' ^' u0 Q" n1 d: ~
  1. pNew(0) = P(0) - 500
    ; m; `" Z' C" U+ R
  2. pNew(1) = P(1) + 1405.8
    6 \' i! p- N7 M+ b: t6 f9 k. a& W
  3. pNew(2) = P(2)
复制代码

0 y# [  N) K' h( D; ]我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?( N# Z4 u# o) Q' M
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。1 B3 T2 \, I6 l$ N  ]. c+ y1 N
谢谢版主' x6 q1 y. Z1 a# W2 K2 k( }
& t- C( b+ o' |9 L6 B4 _0 [( y/ F

/ L2 g. h1 L& d2 T# o% F& k
  1. Private Sub cmdInsert_Click()/ z2 j! h: n  I' R/ J$ [
  2. Dim ptInsert(2) As Double; s% a6 M5 f0 S6 n/ B
  3. Dim lastBlock As Variant
    " i  B. b% Y' C  u
  4. ptInsert(0) = 0* W2 Y  c$ C- L. c1 h4 n
  5. ptInsert(1) = 08 A2 c1 D' R6 S; S8 i
  6. ptInsert(2) = 01 }) h2 Q( ^5 u$ F" W
  7. ' z" ^8 y) d3 v7 o" o. g8 _
  8. '----------插入块A 仅仅一个---------------------------------
    0 h7 R0 u  F$ ]3 ?! S/ e: g
  9. Dim B As AcadBlockReference '声明一个块参照变量
    + C% N4 E$ g8 H3 Z! C' D3 @
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    , K8 B0 a% I9 n1 [# x
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)% f3 I/ i9 H7 V6 S
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    9 P) b% t  `6 Q5 ?
  13. '----------插入块A 完成---------------------------------
    7 P. l  a1 D4 \4 u9 g- I

  14. 4 X# ?/ r& e: i- T
  15. '----------插入块B---------------------------------
    - Z/ g" U% @' O! {; Q( Q) Q
  16. '第一个块,需要单独插入
    ) H# D& ?0 D( B- y5 u2 E
  17. Dim pNew(2) As Double$ y% U8 J) G' ~2 P6 m  P
  18. pNew(0) = P(0) - 500" Z( O3 K0 M4 u: s! V" `
  19. pNew(1) = P(1) + 1405.8" M! L7 e' D+ x4 \2 M9 r
  20. pNew(2) = P(2)) o, ~% ~" s, a+ E
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    4 Y' n3 s+ m& W: J
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    4 g6 U: k2 W. C
  23. ThisDrawing.Regen acActiveViewport$ U: c0 d1 k# k- L2 g
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 # K7 Q, ^. B. ~9 Z2 b  t

5 h0 Y& |+ I8 u3 u* m+ I3# tataki ' s4 Y" T+ {: f% i
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
% z# w9 N2 s5 F+ f! sVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角% q1 W8 U! @5 r  e) R, ^8 J3 B
  2. Dim MaxPoint As Variant'右上角6 R1 e% L  P2 x1 F- I
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层
呵呵,漏看了一位数,罪过罪过啊!
0 q9 A6 C+ p; C原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
: M1 V# Y$ ~* R2 @) l) _+ v哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。/ m" b, i9 a9 Q2 R+ h

! J* z* T7 c# L4 h- y另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
. J7 S8 q5 c3 r* Q! B哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...( v5 ]7 e; P! J; q: v5 `6 E( _
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
$ o4 s) W! }9 W  S
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 )

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