QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。5 e0 q' z# J8 R- \
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:, [8 T  i2 w. _8 [$ [1 T7 j
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
! h' \. f% K; V9 U2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
* U6 J/ e8 ~! l0 v之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
# r1 \  I3 k- G4 S8 s版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()2 U) |# m3 R; H
  2. Dim ptInsert(2) As Double) U9 K5 M  i1 ?" Q  A
  3. Dim lastSel As AcadSelectionSet
    4 |- i3 i$ S( e2 W8 u0 M% X
  4. Dim lastBlock As Variant' @1 m, g" z9 a9 M, }
  5. ptInsert(0) = 04 w7 n3 \4 P+ O' z1 l
  6. ptInsert(1) = 0# r4 |2 Z9 W0 j# X
  7. ptInsert(2) = 0$ J# E) W0 S. Y+ v& Z( K- n
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 05 p# Z+ t+ x: `7 f
  9. * \9 p; I. P" g8 P

  10. 2 s. f( P' B; M/ f2 v

  11. / Y0 |! ~3 l* u6 F2 p. M3 b
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    $ ]# ~: I! t1 P$ D3 B. J9 c5 E
  13. lastSel.Select acSelectionSetLast  v  S9 N* A7 O- f

  14. * W# Q8 z: H# |0 D
  15. Dim B As AcadBlockReference '声明一个块参照变量# ]' f* s; O, a/ F6 i2 f- {
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标5 @1 `$ s; f% o* e
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量2 a. \0 }0 ]- v; v( ^  p
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ; V3 n. U3 `: U+ C5 a
  19. : \" Q6 i- P* M; q6 l6 t
  20. lastSel.Delete '删除选择集
    - O3 N0 d' ?- _2 R% H- _2 U9 ?3 C
  21. + H. I( j6 @& c: t
  22. * V, O2 W$ p& g0 ]
  23. ThisDrawing.Regen acActiveViewport
    + S$ P! q/ j: q( {' g

  24. ( Y! t& j: T3 u6 Z: \. c
  25. * O" F- J2 N# U! |8 {* _# m- F
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    / o4 _' t& K& z! E; s$ A' `% H# D
  2. Dim ptInsert(2) As Double2 x3 y/ x* n; f* Y  a6 f' R
  3. 'Dim lastSel As AcadSelectionSet5 a+ `6 R' [% ~
  4. Dim lastBlock As Variant( I6 M1 p9 \! ~! V
  5. ptInsert(0) = 0
    7 ^  R6 [/ {& D% X, b, |
  6. ptInsert(1) = 08 h: O& N3 G' F9 G' k+ f5 a
  7. ptInsert(2) = 00 P: O' y+ J3 G2 [

  8. ; Z/ F0 L# l  A2 |
  9. 8 l" \' O( Y4 D' V" Y
  10. : c6 ?9 e  E! ~
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    " h' w7 l0 s9 O
  12. 'lastSel.Select acSelectionSetLast
    : ~* t$ u+ H; D: n. H, C

  13. / Q- @8 p, r  G0 Q
  14. Dim B As AcadBlockReference '声明一个块参照变量
    . B& _# H3 I# s1 D6 d+ g( S4 T
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    2 D0 L. O4 q, M9 h$ }
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)" X- Y, ]+ W4 z. N9 Y  U1 I
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ! K) K+ v) b5 B+ \+ y% I2 P  ?' q1 Z

  18. * r: M8 u7 a8 o- v4 t1 t' u  J
  19. 'lastSel.Delete '删除选择集  q( Z0 V! |+ \8 q# P' A
  20. 7 N$ G% j9 }) b( @
  21. 1 F' h$ Y' l2 i- j) A
  22. ThisDrawing.Regen acActiveViewport
    0 Y; h7 l: l( ~
  23. 2 y$ T! F6 x. F7 X
  24. 1 |- k6 A  U) z2 S
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 7 V$ Z0 h, Q: q' ^& m  h

6 ^2 X9 x8 y+ X4 Q4 t( {4 P首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:/ m( R6 _- e( M' Q+ y, _  n- |
  1. pNew(0) = P(0) - 500
    & }' _4 }- y4 A
  2. pNew(1) = P(1) + 1405.8% I9 H6 r2 A: J$ Y
  3. pNew(2) = P(2)
复制代码

, P+ E' K0 S, @0 C' n# R8 i我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?7 W$ g# s: Z4 c0 x
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
6 K4 G* J7 S# q0 \谢谢版主0 C7 u( ~5 F4 E# r, X# I2 i

, }2 j8 A$ B3 l, P# z  p
4 K* N$ C7 m) _2 e
  1. Private Sub cmdInsert_Click()
    ' ?: v7 p$ R4 V
  2. Dim ptInsert(2) As Double3 y5 D; y* F2 m$ d, q
  3. Dim lastBlock As Variant
    ' N0 u1 s" d& a. }
  4. ptInsert(0) = 06 }' D9 n1 `6 F3 E; y: e5 R
  5. ptInsert(1) = 0
    & N, H. g* X- l7 O# E8 l
  6. ptInsert(2) = 01 z1 w# [, K  n% y+ A8 w

  7. 9 {" F7 r  ?6 F( ~! D0 r8 F. D) }5 r
  8. '----------插入块A 仅仅一个---------------------------------
    * |1 H& ^- f) Q
  9. Dim B As AcadBlockReference '声明一个块参照变量1 }7 a# `; K4 F' w6 u6 T. C
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    4 d9 F2 ?# s: l+ y4 P+ s& k
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0). a  a7 Y9 k+ O% W
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    1 h; d: ]4 K. \) R0 P
  13. '----------插入块A 完成---------------------------------( P* J7 Y4 f/ z% i

  14. , J# {* h3 ], ~
  15. '----------插入块B---------------------------------& i; A7 A+ ]4 I. j( i( D
  16. '第一个块,需要单独插入
    * o3 O+ O" N: z* Q
  17. Dim pNew(2) As Double( R4 ]4 B' ^( y
  18. pNew(0) = P(0) - 500
    . J. [1 P9 r8 z! |5 c
  19. pNew(1) = P(1) + 1405.8
    7 f* k$ @! }) J5 d
  20. pNew(2) = P(2)/ y, g; F& f9 x
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    ' b( i' [' W0 X  R) U4 x( Q
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    7 P! M7 K) ^5 `( o) p& `) t
  23. ThisDrawing.Regen acActiveViewport+ o! ?8 F: ]9 P! ]
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 5 P% N7 `) y- v% p; B# L
" a" k, e- R3 |' V/ r5 t# i
3# tataki
! o  U; D5 ^5 e) g0 ~/ g看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 ! `& ~. O' l/ S' B* M! I- W
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    # o" k( W  ?! W# A
  2. Dim MaxPoint As Variant'右上角
    ' z* w$ f- c% D4 O% C( ^* [: l
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
, |6 }% ?- {  V# n, v' q# l- i/ k原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..8 k5 _7 _/ {" w) }
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。6 R& q" [9 l7 S1 j: y# u

, d5 c0 ^( C7 a* ?2 p* c5 r另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..% O! A- ]1 y5 A% `5 {
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
' q+ w9 |3 j; }+ Ntataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
3 [$ F& n6 I" Q0 D/ T
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 )

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