QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
5天前
查看: 9214|回复: 8
收起左侧

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。0 i; i, r! }; x9 ^" p/ Y
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
# n8 H& K  x1 S6 [  t5 b1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?( z. o; D  a& Y$ [1 K
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?7 H5 h* A! I+ j- k+ W' K
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
2 C8 b$ E, z1 w版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    $ ^9 e" P' t- l' c/ f$ k2 m
  2. Dim ptInsert(2) As Double) }" Q  `  ~) U4 g, ~0 n7 [  `9 l
  3. Dim lastSel As AcadSelectionSet
    8 K4 H9 g% X4 z
  4. Dim lastBlock As Variant
      W) D* \) B! u
  5. ptInsert(0) = 09 i( S  m* q0 S. D
  6. ptInsert(1) = 0& q4 y3 b/ D% Q  u! H+ _+ |
  7. ptInsert(2) = 0
    - ^1 @5 N! b. L, V/ R- F1 U
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0; r3 Z& v6 e7 O9 `0 D4 `0 b* q
  9. ) K; n+ p" b3 q

  10. 9 z+ t  a: V. k
  11. 5 {1 R3 Q  U# K& o- o
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    1 L5 E- o4 x$ k+ A4 N
  13. lastSel.Select acSelectionSetLast
    ( n; ~0 ^$ Z1 J9 ~8 H3 K% ?
  14. 9 O" i2 _  J; ~
  15. Dim B As AcadBlockReference '声明一个块参照变量5 O% |) q2 X/ t5 ]9 ]8 s
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    , E+ H, w4 i" Y
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量, j0 s$ ?+ Z# n4 F/ @+ s( ~1 r
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    % c7 u% s0 |- \6 g& R4 d. B: H& ?, @

  19. ! P# L" p+ ^0 [9 Y8 N  L/ P  w
  20. lastSel.Delete '删除选择集
      f: _% u, E/ n) ^. H: `5 c

  21. ( G! _6 D( w8 s7 D$ s
  22. ( C0 i3 E3 Q! G# U# I6 {( k( U; e
  23. ThisDrawing.Regen acActiveViewport. z( w: n1 A7 h: h

  24. 2 E6 R$ U$ o& F' p) s5 S5 U

  25. ) Z! y9 p3 B8 {* L
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()( ]/ z' M# `% _5 b7 W8 c
  2. Dim ptInsert(2) As Double! W) _- S- r$ U0 v9 D
  3. 'Dim lastSel As AcadSelectionSet
    , r* L4 J% @$ u7 Q3 X
  4. Dim lastBlock As Variant7 J7 o* f1 P1 c+ k4 q' o' \
  5. ptInsert(0) = 0
    # k! D# q, V  m! B- X& h
  6. ptInsert(1) = 0
    7 n" e8 C+ P* q
  7. ptInsert(2) = 0
    # s/ V$ d9 x: ?! ?: R" \* D; ^' _
  8. ' Z8 p- f4 F2 |# h. k1 p
  9. / _0 g& O; s: E7 l: g+ F& u9 u2 c, m

  10. ( a. I; _3 t% @9 |
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    : D# w7 p& Q' I" X- t
  12. 'lastSel.Select acSelectionSetLast
    0 c8 T" V" ~$ `3 ^* A

  13. 3 s. v7 R/ r3 r
  14. Dim B As AcadBlockReference '声明一个块参照变量
    - M8 h7 B. U, U# n& H
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    0 }# `+ k$ K# O" ?
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    # w' m. [3 |3 D* }9 d" E. h3 a% I
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ! @8 ?% k& e3 P1 I
  18. 0 M- {  E' {7 e; J4 ~2 i) e
  19. 'lastSel.Delete '删除选择集  f1 x& }  w3 e

  20. 6 y+ ]0 J* P  X8 L, R3 [& `

  21. , @3 I  l0 C7 f; J7 Y+ u3 `4 b. j
  22. ThisDrawing.Regen acActiveViewport- ^' {/ \# k+ p/ i

  23. - ~$ y1 r9 w: H1 r/ K- |7 F2 j

  24. 0 `: U: `3 E: ~9 b# |% e7 ?
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 4 @; i6 S. P9 U$ g9 W
% Z" N! p' R' u% g% X2 y
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
; H$ X3 b% x+ q( ~
  1. pNew(0) = P(0) - 500
    1 Q: O9 A' x- u; O. {; |
  2. pNew(1) = P(1) + 1405.84 m! M1 z/ V, t
  3. pNew(2) = P(2)
复制代码
; J- e' V9 [% A* ?+ @
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?0 f! k& t+ j, p+ ^
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
% o, z0 i% m# V5 x谢谢版主" ~. n" B5 Y8 o: y% _: U" Z$ s6 ]' t

) }2 }4 ^/ @9 M  M1 y" j
: i2 u# X5 E! i  F; B' Q
  1. Private Sub cmdInsert_Click()
    3 o, n& ^( m6 \
  2. Dim ptInsert(2) As Double
    ' Q5 G, w! r! c6 O$ p( N' C7 o
  3. Dim lastBlock As Variant3 t# ^# \+ T& ~$ p' I- R* Y
  4. ptInsert(0) = 0  W/ f$ ^& N+ S' o
  5. ptInsert(1) = 0
    " j% X* M# I' h; y
  6. ptInsert(2) = 0
    " i$ K; p' }5 [% Y" H- h2 f' f

  7. . `; P% D+ g4 l# n& Y
  8. '----------插入块A 仅仅一个---------------------------------2 A4 M5 d7 z# Q
  9. Dim B As AcadBlockReference '声明一个块参照变量
    - Z$ J4 R5 A  a" d3 n4 ~1 S' d4 G" W
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标( K2 E8 T" [' U3 W
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    / Y. {) m- p" j2 f% A* S
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组% B6 s* U5 L  y5 U2 }! B
  13. '----------插入块A 完成---------------------------------4 Z+ p7 y; x. A& ^
  14. 1 r5 I6 v' r8 S4 Q& R6 N
  15. '----------插入块B---------------------------------
    0 n/ T! x" A0 |4 Q$ z
  16. '第一个块,需要单独插入
    , n. h7 x  l5 b
  17. Dim pNew(2) As Double
    1 c5 T! ]9 ^/ U; D
  18. pNew(0) = P(0) - 500
    ! O8 A2 ?7 x' P+ A) C' }
  19. pNew(1) = P(1) + 1405.8
    - ~, R+ J; U4 _9 I  P, e
  20. pNew(2) = P(2); E- M/ w" E6 V( o- ^  @( E" y
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    - m6 a, y7 K: T+ s" ]5 p
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    $ z) E+ K3 N0 z5 g4 k2 j' o
  23. ThisDrawing.Regen acActiveViewport
    ; K$ P: m3 t/ {9 \0 X
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 5 [* @& P' W1 \" q  }' ?7 I6 g

4 q) i6 U3 m6 W% D3# tataki 7 `6 @& c+ O2 t2 {, N$ |. e; ~
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
% x: P5 O3 |, vVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角( k6 q0 M) O$ J+ r
  2. Dim MaxPoint As Variant'右上角; z/ B+ C. p; H3 N2 b, S
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
: _6 Y% C' ]. K6 G! p2 M' M- s; }原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..- c  @; Z" y2 O3 u
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。, ^  z/ J2 |8 x6 T( p$ t
3 O& `5 a. ~% |9 {4 c7 p
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
: c. r  A7 O3 d: j) D1 {哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
6 _0 l) g$ }4 _+ Z- @) n2 Ctataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
- l" I& D5 K+ U1 C* G
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 )

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