QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。4 [3 A( S' G7 c7 `8 {; n
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
' d1 r6 q+ V& X; A! o% r% {1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?: U, d5 N+ X8 k* E. w9 Q* D1 l/ @4 F- m
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?8 R* Y. i! b1 n0 h2 v- T
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了* X# X$ D" j4 D1 J/ H% B
版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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(). L2 H9 }: W5 p$ L3 K) F& q
  2. Dim ptInsert(2) As Double
    ' \" s5 I: ?, ^4 A6 c9 ^: E
  3. Dim lastSel As AcadSelectionSet+ n1 H; j3 N( R, @. w8 [3 f1 N
  4. Dim lastBlock As Variant
    ! z8 i. R/ S' G7 d( n
  5. ptInsert(0) = 0
    ; i  a* [$ [/ N* h" v& {' P. d
  6. ptInsert(1) = 0
    " d0 q! }. S" P% r1 |! p
  7. ptInsert(2) = 0/ {  B' s- Y; R! N
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    8 Z$ X% [' n' \

  9. , N: ]/ r! n1 F" e. G/ F+ `/ f8 a
  10. ' p+ V: C2 Y! c1 x! K- o

  11. $ O" a8 k0 l* ^6 f+ Z. B+ b
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '' O# [' G/ g: w2 x, p/ `6 q& |4 b
  13. lastSel.Select acSelectionSetLast) N5 \8 I% C2 K1 Z. W/ M

  14. $ {9 L, s) [2 r$ W- c
  15. Dim B As AcadBlockReference '声明一个块参照变量& o# Q* [! E5 Z5 Q0 |% }4 c
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    , M5 p: D7 U# `1 ~
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量% B6 |- H( u! [+ A' r+ o( S
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组/ G, c, o. Q+ n4 }
  19. . X/ A: h+ I. l/ G5 V! v/ ?9 H; n
  20. lastSel.Delete '删除选择集
    4 p8 c# f9 [0 g# }! q, S3 b( t

  21.   ]0 T. i) _1 d$ O# `

  22. . |6 Z3 \7 e5 _: Z
  23. ThisDrawing.Regen acActiveViewport$ l) o# n3 C+ s! V

  24. * N, C% r, U9 }- b: M  q

  25. , B1 `6 k5 _" b+ ^; `) b* R3 F
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()9 D# N0 t  s7 W2 f  [. q- Y+ _
  2. Dim ptInsert(2) As Double) \; N/ `( S* a" ?
  3. 'Dim lastSel As AcadSelectionSet
    ' u& T6 i; m: E( U$ i& P
  4. Dim lastBlock As Variant
    & T: t' z7 x  C7 F2 V% N
  5. ptInsert(0) = 02 p$ c1 d& y( }) G2 d$ K4 T8 Y. K
  6. ptInsert(1) = 0
    , n- `* Z/ F2 V; f# F
  7. ptInsert(2) = 0
    $ ^% t: F; R2 ?/ p6 K
  8. 2 c. E: k2 [8 @0 |' W! @3 Y
  9. 8 y0 c, e$ w6 ^: w" u

  10. 0 G5 q& K+ s' i: C# R
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    . z$ G5 k- w4 k( M
  12. 'lastSel.Select acSelectionSetLast
    1 c- E5 I' H: K9 F# W+ ?

  13. 9 f9 m) f4 z9 N2 c/ v
  14. Dim B As AcadBlockReference '声明一个块参照变量
    ' Q" x! I# Q0 m  N
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标. g. q& @( ~+ }; w' P
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    # T! Z4 M6 Y5 G3 t
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组+ j- Y4 j4 p( [, v+ q
  18. : A2 f  f' s1 p" y
  19. 'lastSel.Delete '删除选择集0 j5 ]* I- t0 J: D* u" V* F2 I
  20. * y( `2 y' B  g  s$ V4 U3 A: X
  21. " j/ J6 A- \# u4 G$ H: K) e
  22. ThisDrawing.Regen acActiveViewport0 {1 y8 x2 j; k% Q2 D* a  ?* z
  23. " r  m+ a- _" P+ w

  24. - y- ], H* f1 j  O$ U
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
+ I; T/ }9 ^7 ~2 j& {# Q* G3 u. ^" D& B0 f
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:5 d5 S" X5 k; Q! I) h4 w$ a
  1. pNew(0) = P(0) - 500
    : p* Q6 h) B  z1 i7 J
  2. pNew(1) = P(1) + 1405.8
    7 T5 K# g  S& z: h
  3. pNew(2) = P(2)
复制代码

  v4 N- e  \$ N# _( D7 R0 s我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
4 T. i$ Z0 X3 y8 D+ E$ ^5 V就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
5 A& n: S- Z  V谢谢版主4 S5 f6 L0 S" n( h: ?% i

8 ]! }% q' w  z9 s1 q# G/ I/ e$ Y6 w9 F. A1 J& z
  1. Private Sub cmdInsert_Click()
    $ {9 `% N& L$ y6 E
  2. Dim ptInsert(2) As Double' A% @+ I3 c8 F9 \  [
  3. Dim lastBlock As Variant
    5 I; o9 K# m& p' u
  4. ptInsert(0) = 0
    & ~/ {3 W4 Y& _. M
  5. ptInsert(1) = 0! d$ |! @: H2 a- a3 ^8 K% E
  6. ptInsert(2) = 0$ v3 x  |. n+ J; @9 a

  7. - l% B/ g) Y& q1 ]9 N
  8. '----------插入块A 仅仅一个---------------------------------& l$ y* o# Z1 n3 G
  9. Dim B As AcadBlockReference '声明一个块参照变量3 J3 W1 p6 q( C) g* ~2 N6 A3 q" M- f% S
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标; {0 b  U9 X+ v* k9 v2 D1 K
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ; q- h# S) k4 a8 t6 I- C# j! h. [
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    + k+ _; [% s  @
  13. '----------插入块A 完成---------------------------------- N1 b+ r5 }2 p7 m* m' }2 U

  14. + L% G" h% G! z, [, i" B
  15. '----------插入块B---------------------------------
    4 A5 i+ ?9 c' D5 l6 ~3 I4 J/ d
  16. '第一个块,需要单独插入
    4 r/ t# q! m" @8 @- n
  17. Dim pNew(2) As Double
    ! m$ u3 \  a' Q4 Q( _* `
  18. pNew(0) = P(0) - 500
    ; n) J$ s3 k: b; T9 k, G. g1 p
  19. pNew(1) = P(1) + 1405.8
    ! c* T, U0 R# {. z
  20. pNew(2) = P(2)
    $ q/ l- r+ Q5 ~* o$ J& b. R
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)/ ^* l0 D' B5 C( a' h
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组% @" X( N4 J3 E$ @
  23. ThisDrawing.Regen acActiveViewport
    / F- I/ F5 G$ O' ]- G/ m
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 8 _. h( c/ C% Q6 L$ z* S

9 M$ j7 B( `9 M1 @; n3# tataki
  l  |0 L4 J7 `8 _# Z看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵   c3 Z$ O+ b. i- r$ {' ~1 _1 I
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    , V+ \1 E3 p% r
  2. Dim MaxPoint As Variant'右上角
    $ x- J( w2 G6 z
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层
呵呵,漏看了一位数,罪过罪过啊!' C2 Q, L: v$ Q/ d: e; c
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..0 X- `! v4 J% X/ _
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。& o2 ^, i+ l9 S0 e2 u( s: I

4 [! q) R& Y( f8 O. {8 _  Z另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..% _" F# l' y1 E4 b8 p) {" L
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...) d1 s& S0 l' `/ S: n1 s6 R
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

% X$ B5 A& v" {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 )

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