QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。1 d+ u" \* k/ V" ?
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:- W/ f: J+ `. i( a$ P# V% D' x- B' f
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
2 @; J$ M) Y: ]5 L* O- v2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
: ~" s5 u: s+ e5 T/ c之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
! `& B6 s1 q/ r2 T版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
2012-4-3 19-29-23.jpg

块自动插入.dwg

42.84 KB, 下载次数: 10

InsertBlock.rar

7.03 KB, 下载次数: 7

发表于 2012-4-4 08:29:21 | 显示全部楼层 来自: 中国辽宁
方法一:按照楼主的思路使用选择集
  1. Private Sub cmdInsert_Click()+ }: F  ]$ `, Q) U) I
  2. Dim ptInsert(2) As Double. ^8 j( u0 v# x3 e: I5 i8 G3 f
  3. Dim lastSel As AcadSelectionSet$ |9 V$ B- k2 }* ~9 [8 t/ m
  4. Dim lastBlock As Variant  G. r) ^, U, ?' S
  5. ptInsert(0) = 0) W* w% B& }; u+ c( S
  6. ptInsert(1) = 07 m3 q7 l3 A/ U9 E
  7. ptInsert(2) = 0
    3 T! h( c+ T% |$ G3 j
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    # A( Y6 q* J: P6 q- D/ a9 K4 a

  9. 5 J3 H: H' K1 @# h, K$ A, ^$ l3 x

  10. , ]  [- l% q3 d& y  Y3 M+ L& L

  11. # U- W( h8 {+ H6 a5 W
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '  P' }4 d. o4 Z7 i: F; y9 {" g6 T4 @
  13. lastSel.Select acSelectionSetLast
    , T2 T; k6 x  q: ?, u5 m/ J
  14. 2 T2 h1 w+ O; d0 Q% J0 p
  15. Dim B As AcadBlockReference '声明一个块参照变量
    9 e. o, c9 v1 U  t' f
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标; `, _$ m( ~9 k
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    " G, I' u8 l: H2 D
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    2 C- p( t% C" \
  19. ' H* K8 W- I" X  q
  20. lastSel.Delete '删除选择集
    - y7 r+ y6 F# I: h: m
  21. # M* u' N/ ?9 l# L5 ~/ z' k1 X7 O
  22. 6 a* p. V9 E3 d8 S& h0 m8 o
  23. ThisDrawing.Regen acActiveViewport
    & R. J8 ^3 o3 K+ X9 a1 z- f" i8 f
  24. 1 [8 L2 c1 K/ _. y4 C6 C# \- N

  25. 6 }7 G* I1 }; P7 n$ V" g
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    ) x- n  b3 z6 N  c+ n- S
  2. Dim ptInsert(2) As Double
    & x# ^: q! l6 K" d0 `! L
  3. 'Dim lastSel As AcadSelectionSet9 c7 T; b' [/ a6 u2 V3 X
  4. Dim lastBlock As Variant) Q, S/ W7 O0 n! G6 s
  5. ptInsert(0) = 0' R. G- ^+ W: M! {. ?. u
  6. ptInsert(1) = 0
    ( U7 p, K" n/ g& f
  7. ptInsert(2) = 09 o8 ^; u' C% m# i

  8. * P8 q7 n4 L+ N6 e- }" \

  9. - b' E2 M9 r/ ^
  10. . v, M- z% ?9 W/ S5 y) G+ d( Q  R
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    1 m' l4 A  K9 f' N
  12. 'lastSel.Select acSelectionSetLast; ]4 k' ]( G3 E. h
  13. : J6 A; V, o3 p7 T1 p
  14. Dim B As AcadBlockReference '声明一个块参照变量  N+ R  d. t0 @. U& J
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    " [4 o# b& I2 z( a
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
      ^) J8 m# `9 P& V' ?) i
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    " n% {3 K! X9 p  ^$ X

  18. " J. C2 ^4 t  Q$ c5 R& d
  19. 'lastSel.Delete '删除选择集& L5 s5 a0 d$ y3 N& U. b5 C" M

  20. 8 t- k. E9 I! `4 v  b
  21. 0 m$ ^" ?8 ~- z2 E  Z% C1 R
  22. ThisDrawing.Regen acActiveViewport
    5 D1 P- c. X& c2 Y4 m6 N
  23. $ {$ ^& g! R. z5 U9 s
  24. 8 `$ V5 q/ x0 C8 U0 e- e
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
1 k, x8 t& F9 [7 ^9 p. w# L1 X+ w8 _- g3 I, [
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:7 d4 M; s2 ^" N8 t1 r; R3 J% l, w
  1. pNew(0) = P(0) - 500
    / N+ K; u' T) f; O3 U) e/ X
  2. pNew(1) = P(1) + 1405.8
    . S# e: [- z& v  A" n
  3. pNew(2) = P(2)
复制代码

0 N5 s5 g% R  [. ?我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
/ b* X7 ?+ \3 V. _7 G就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。2 X* Q: t: Q4 V, k: x. @
谢谢版主
; ]: `) S' i; b6 G+ F6 @9 J2 L/ O* O2 F

& U5 j7 w" U6 d8 f8 Y
  1. Private Sub cmdInsert_Click()# D5 L; ~' H8 }3 X/ H* Y
  2. Dim ptInsert(2) As Double
    ) a4 x0 ]. V! x! Z6 }
  3. Dim lastBlock As Variant
    6 Y  E$ Z* ~- }
  4. ptInsert(0) = 0
      X' e6 Z" b, d! D, N% y8 V0 D, l
  5. ptInsert(1) = 0
    $ J  D) i7 A9 m7 \' M( x( n
  6. ptInsert(2) = 0# M4 Z- z. s9 B9 u8 ~

  7. . w0 f, N: N% T5 [9 U
  8. '----------插入块A 仅仅一个---------------------------------
    , ]- n6 s* g5 Y  j9 L' j
  9. Dim B As AcadBlockReference '声明一个块参照变量8 ^  W$ @7 q' r& i8 f# @
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标) f/ E' q, K; t+ M3 X: t/ T8 z
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
      a! U+ B* D  W/ v9 x, B8 A) L" [
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    8 I( R' j; p+ }# V1 S8 h* q
  13. '----------插入块A 完成---------------------------------
    0 X. I8 S! R  g

  14. 9 t9 P3 \4 v* v+ p7 h
  15. '----------插入块B---------------------------------! j! W$ J& M! a0 r. w2 R
  16. '第一个块,需要单独插入
    8 ~8 ?( w5 I3 v5 `3 W* c# V
  17. Dim pNew(2) As Double
    6 p/ q; A1 [$ F4 U$ k# ?
  18. pNew(0) = P(0) - 500& N# u- r$ R7 ]& U5 Z1 U  z' {
  19. pNew(1) = P(1) + 1405.88 |1 ?4 R9 @! X. N$ c) @
  20. pNew(2) = P(2)
    % r; s  d3 S" d: ]' ^& w2 L8 h
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0); @2 d5 Q3 T: Z: R5 t
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组, X  f7 c- `! O- v
  23. ThisDrawing.Regen acActiveViewport  b! }9 |. Z2 B1 [% ?
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 / M" t6 o' `; i2 x% Z) `6 f
# i: V- ]5 N1 u9 G+ |, X, T
3# tataki
" z( |" }* X8 p8 ^看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
7 L7 z; t. ~0 KVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    7 h! H/ @9 n! G  o& Z7 U# T0 u" T
  2. Dim MaxPoint As Variant'右上角  U4 R: x9 T, K/ p# K; s
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
3 t1 A! w& q6 N) g2 a原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..$ H5 u, U& u" u5 n8 j1 b0 k
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。- E9 J$ u& @3 j3 J6 U( M- M
, z1 b- T: N! A& e1 ~
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..  ]& V9 R: x! Q& E. J
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...4 f' E4 N0 L2 L: L: U& m& j
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
# x: U% C. z; G6 v1 R5 O: g8 r
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 )

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