QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。; u' ~! ]9 m7 k  f$ _# _$ ~& W0 o3 H
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
3 u' }1 n$ I; j( i$ M1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
3 g5 d8 n$ L2 }2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
; `3 n6 i1 F" f之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了7 L8 G9 }4 _2 x
版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    2 y/ `4 D5 N  c
  2. Dim ptInsert(2) As Double
    6 X8 n2 s5 M8 g* q  }
  3. Dim lastSel As AcadSelectionSet$ e8 o9 m8 A) O8 \( K: G
  4. Dim lastBlock As Variant
    0 _6 _6 K1 Z2 r6 @* S. i) a
  5. ptInsert(0) = 0+ S, v) K. O! X" N& D; W
  6. ptInsert(1) = 0
    7 B4 l, g* e0 C0 p0 V" W
  7. ptInsert(2) = 0
    . U+ R) Y. }  d: B$ \
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0; S) a/ ~% p  a' K% W% R6 J$ W

  9. ; [1 P2 Z3 R; B& _/ S% ]

  10. , x' {9 u" M( b. Y4 M3 _( z: w

  11. 8 T& U0 L4 M! X' r/ [/ @$ I
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '; @# [* T3 r. r8 A6 }
  13. lastSel.Select acSelectionSetLast& R9 d! b2 f, m- E' N* V
  14. ' Y3 B7 N& f' E& Z3 k% D$ F8 x# ?
  15. Dim B As AcadBlockReference '声明一个块参照变量
    ! U+ x$ S8 q& J9 ?+ P  `
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标1 C4 w/ _$ x. Y* r
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    7 j% N1 ?  ]! P% t: F
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    1 H% O: x& U# Q7 H4 p  Z
  19. - [- {) @% ^% D' [5 c, |
  20. lastSel.Delete '删除选择集. j* v: o7 f& y9 M, n7 n

  21. 8 j- I! c6 e0 [: l7 ~( q- V- l

  22. 2 j  J& w7 F9 h+ r
  23. ThisDrawing.Regen acActiveViewport8 f) H: @& ]" \5 M7 T

  24. / n0 M; m( G1 p1 Y
  25. & J& Y/ i3 U# g
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()+ s! R& C+ K9 ?0 u
  2. Dim ptInsert(2) As Double7 l/ G( ~; P3 J2 I  F
  3. 'Dim lastSel As AcadSelectionSet
    $ I4 L% `& K2 u0 \
  4. Dim lastBlock As Variant7 r$ |, g7 I& A1 @; s1 Z0 y1 ?, w
  5. ptInsert(0) = 0& h) u( [/ P1 p: ?" W$ q: F
  6. ptInsert(1) = 0
    - A+ E, N7 C8 T3 Q' S
  7. ptInsert(2) = 0
    $ k7 c+ B$ ?7 s$ O2 O7 h

  8. - ?$ j% t4 K* d7 q* s/ H( a' E$ A5 I

  9. 1 b! b( r) E1 D3 ?+ J. n
  10. & t# U0 `" j) z5 j" J2 ~9 r& X" A9 f
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    1 p6 S" [7 |- a4 e( p3 Z
  12. 'lastSel.Select acSelectionSetLast+ I& b! y, L, K/ T1 I0 k

  13. 2 j* q, C' A' l0 i# N3 U
  14. Dim B As AcadBlockReference '声明一个块参照变量
    ; G$ H9 |5 D' V9 ~7 s1 B7 l# m
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    4 M& y0 w! N# d5 P, B1 e! Q+ F
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    " M* ]8 A% P8 C/ Y: W
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组* j& ?% X1 C$ c5 N
  18. ( _0 ?- G) m6 r1 Z( x
  19. 'lastSel.Delete '删除选择集
    9 B! E: Y0 v9 A0 U( n4 O
  20. ) H& q, h: J4 z& ^) y4 L2 E  S' |
  21. + J0 m+ U7 N4 \
  22. ThisDrawing.Regen acActiveViewport5 @( [$ m* z; c3 g) }* J" g

  23. 5 z1 G! N/ W" Q
  24. # q) e6 y$ t$ R/ w
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
# z8 E( S- C% z) y. F
  z. _1 I7 h; F" G首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
" M" k; o% Z+ g/ ~, N3 m
  1. pNew(0) = P(0) - 500
      g; I1 r/ ^9 ~& H2 L
  2. pNew(1) = P(1) + 1405.8) [& W/ a: w( J
  3. pNew(2) = P(2)
复制代码
7 Z# B9 g! F. b2 Z: h. X" U% R3 ]
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?' y+ E7 M" W: [
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
( w+ M  z  ^2 l+ l# A谢谢版主) I' Z% h/ D& U

. {! _. Q( Z1 \& F  r# E! {
0 s- P2 n2 N. E' R* k
  1. Private Sub cmdInsert_Click()
    # k! [7 N* N& z
  2. Dim ptInsert(2) As Double
    6 e4 T! I% Z% H0 t+ t8 f
  3. Dim lastBlock As Variant
    $ i6 ]0 b; V. q( l9 i
  4. ptInsert(0) = 09 w( S( B. F4 W/ q' s2 T; p- i
  5. ptInsert(1) = 0
    & w* c5 ^8 q- [& D5 y4 S9 l
  6. ptInsert(2) = 0" e4 t0 j6 u5 c$ u
  7. % n8 |+ S1 K. U$ A1 F
  8. '----------插入块A 仅仅一个---------------------------------' m5 @' j7 e* r$ c8 c) y
  9. Dim B As AcadBlockReference '声明一个块参照变量7 x& X+ y8 U/ d: k
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标/ }9 ]: v1 R7 Y3 [) T
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)" [3 V0 l6 x5 T; Q) ]: }
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    2 D  P$ O& O( B$ G
  13. '----------插入块A 完成---------------------------------% d* {5 C  ^, M2 b& w; V$ D

  14. 5 X2 T$ \# z7 E6 b
  15. '----------插入块B---------------------------------5 `8 V+ u$ g5 x4 T# w7 a
  16. '第一个块,需要单独插入
    - t0 C7 R4 \) |' }) w) o, c" X
  17. Dim pNew(2) As Double2 s( W7 o1 @+ X! \  ^0 Y8 s; l
  18. pNew(0) = P(0) - 500
    / L% e/ z+ S; F) F
  19. pNew(1) = P(1) + 1405.8% g) l" A) M) A4 e* j6 W1 G1 g
  20. pNew(2) = P(2)2 P0 E0 u  E2 x
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
      Z) q' T; s2 D
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    7 S! ?7 R0 u- ]
  23. ThisDrawing.Regen acActiveViewport
    , Z, c1 `% E- ~* G! w1 ?
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 & p( n* r7 b  S3 R8 p% j: q4 K
8 e) \$ ^- _) N
3# tataki 9 a1 P& b- x4 @# L
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 0 Q' C: S' z  f5 z
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角0 @* K& G) C6 H3 K$ ?' m
  2. Dim MaxPoint As Variant'右上角
      y3 Q( E4 Y* }* w4 i$ s) J
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
7 r" z$ A9 ^1 D6 E原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
7 O2 ^% i# F, ~% d; A哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。  F( m- }5 @! ~1 [! {4 J2 E( \

" b: t& m0 g$ v3 V- T8 [7 W$ s另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
1 J  @# V: |6 B" q哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
8 K1 h. J" T7 y- S8 q  x9 d% ktataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

# z6 q" [) _; c# x; Elisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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