QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。- K4 a* @+ Q, ^2 Y) v' B
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:' y: |& [- ^0 C2 g# y
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
8 A$ a, ]0 W9 F9 [! E7 s2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?6 Q$ j. u/ N2 n8 [+ F
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
# R6 k/ v0 ]' D" L  {/ r版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()( ~! w" L' x& v" N& F) T, {0 H( ]- \- Q
  2. Dim ptInsert(2) As Double
    1 W7 g$ d. p. V6 ^& s- U' ^
  3. Dim lastSel As AcadSelectionSet
    . t. o# k% W! S
  4. Dim lastBlock As Variant9 }  ~: M  v2 {* O( r8 M
  5. ptInsert(0) = 0
    5 Q; H$ q; {& F% ~+ @
  6. ptInsert(1) = 01 S& u: F# W( {% i/ X. Y
  7. ptInsert(2) = 0$ B0 V0 E4 c' ?* b7 s! e+ o
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    ) F, A5 [0 b: |1 f+ G. f

  9. : z# t9 m) C3 r! q
  10. ) y+ P- P3 _! v2 r( E& z
  11. 8 Z1 D9 y) K* C+ ?) v. n; S  i, \
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    ! v+ V0 c8 w  }9 A, L8 B; ~. O
  13. lastSel.Select acSelectionSetLast
    3 P! C9 l+ g1 G  s9 ?" L, B7 x# d
  14. 0 H$ {+ o$ V( i' k6 }, Y! M' q
  15. Dim B As AcadBlockReference '声明一个块参照变量
    3 c1 m4 U1 ^9 q5 m
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    # F; s1 \% {2 U3 g
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量; B5 u) [# }: d( L" u- f1 T
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    * ^+ g6 q' Y% u  q  l
  19. ! F- o3 m/ A3 ~/ P7 k0 y6 I) a
  20. lastSel.Delete '删除选择集
    9 e; Q3 _, W: r- \: K* Y3 h' Q, Q& E
  21. ( ?2 h: A0 w( Q. s$ l

  22. ; Y$ I/ d8 _. K& f3 \1 F
  23. ThisDrawing.Regen acActiveViewport5 z2 T/ }) h0 v

  24. & \/ z8 \) [' B4 j4 m

  25. & G" q. Z  `+ G8 r5 g+ C4 Z8 Y
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    8 t+ O* [' K$ c2 C4 E; r' N0 R
  2. Dim ptInsert(2) As Double: V' F( `. L: c/ ~2 Z
  3. 'Dim lastSel As AcadSelectionSet, t! T; }$ Y' P0 Y6 x
  4. Dim lastBlock As Variant
    5 f$ ~8 H  P5 E4 n
  5. ptInsert(0) = 0- r; h0 t7 ^- z8 D. V, \0 k
  6. ptInsert(1) = 0
      ^/ \9 A, c0 r/ L/ C3 }; y8 U
  7. ptInsert(2) = 0, V6 _0 V! t. g" V
  8. # [0 D7 N+ w0 h3 P* r) L

  9. $ |8 G. B: i, l  R" x, h, j2 f7 A  ~0 W
  10. . M6 p  M* |6 Q% L8 K
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '* {& [: R2 L2 i% a
  12. 'lastSel.Select acSelectionSetLast
    1 i+ p+ g9 T% T3 W
  13. 5 L9 g6 l) R: B/ j5 b! s
  14. Dim B As AcadBlockReference '声明一个块参照变量# {2 n6 A+ B9 o' m. h! |$ y7 h
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    % K2 Y+ g5 m$ V: V1 K3 t' U
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ; }( r" m2 {8 s* M2 R
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    % q. j& x. w  U7 a2 D
  18. % [& a7 [+ |& u6 W8 {
  19. 'lastSel.Delete '删除选择集% y2 N5 [. u  l, U+ X
  20. 1 h* X7 I8 G; @
  21. * P+ ^6 j9 z% b0 y5 j2 u, N/ \
  22. ThisDrawing.Regen acActiveViewport
    9 G* j* H8 Z! o  k; w

  23. : Q: L6 H% t9 ~! G2 F
  24. % [$ n8 f$ \& @5 z
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
, t( {0 A* Z  o6 g* z
+ [9 Z; }# _* W% r/ Y1 S5 r首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:( v0 ]5 E0 x0 T- o" }
  1. pNew(0) = P(0) - 500
    8 [# t1 |% Y4 }& \
  2. pNew(1) = P(1) + 1405.8& j# z/ x& w/ I8 N6 s) O. S1 x
  3. pNew(2) = P(2)
复制代码
1 D4 G4 b- _7 Q& j, M
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?3 W  g5 Q* P9 z4 A* A  p" z
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
2 g0 ]2 }# Z; ~1 ~5 k5 E谢谢版主( e1 B: n% X) \

8 ~7 R7 Q8 O! [) v" ~! H6 p: y
, u" E7 e0 V- `, x) c+ G
  1. Private Sub cmdInsert_Click(), L  q% L3 j" k4 q7 I+ A) Y
  2. Dim ptInsert(2) As Double
    . k8 W' S4 ^  l
  3. Dim lastBlock As Variant
      A& S) ~) i! E3 k
  4. ptInsert(0) = 0
    3 V  z3 U( t! K, R7 y9 r9 l) _
  5. ptInsert(1) = 00 F) j6 H  u2 R2 ^. Z& L1 U, ]7 F
  6. ptInsert(2) = 0: q+ P+ O  `0 _8 v; B1 x

  7. + T. y' n# `. O) B: f
  8. '----------插入块A 仅仅一个---------------------------------, L9 L2 |! h( ~4 I4 W2 {# b
  9. Dim B As AcadBlockReference '声明一个块参照变量- f3 a3 t5 J# V! O
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    6 {  Y2 |0 X0 h& X
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)! N0 {# E  ?8 I
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组& m4 H5 r: f0 e5 k& b1 _! l
  13. '----------插入块A 完成---------------------------------
    3 U* @0 Y+ i4 i  j
  14. , k9 ^! s. }  [, @4 _
  15. '----------插入块B---------------------------------
    ; j# e1 L7 M9 I
  16. '第一个块,需要单独插入  E" w8 H4 g1 m1 ^6 S
  17. Dim pNew(2) As Double
    9 s' @8 d8 _3 e  r8 r8 I
  18. pNew(0) = P(0) - 500
    3 F" D$ ^2 e: J0 ~" n& [
  19. pNew(1) = P(1) + 1405.8
    & r8 k- v* E& D, c3 ?
  20. pNew(2) = P(2)3 U. E! W3 I0 s6 b) J2 B
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)' \: R) a( }1 S
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    $ R& Q$ k/ g2 @! S5 f: j; L
  23. ThisDrawing.Regen acActiveViewport
    : o$ P- C+ [9 q6 B9 c. `6 e% t
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
, J7 ^  h( o0 j8 Y. J4 [( I" e- s& B* R, t+ S
3# tataki
% g4 D, \6 @; ~+ |看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵   V- T( H% h1 c' _, j. c; t2 A
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    # I. H8 g* x1 j: I- w
  2. Dim MaxPoint As Variant'右上角' ]1 o: V7 X# W
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!& V5 `) w: _/ W2 b. _5 y0 I7 c+ A
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..( @  S0 ^0 o  K' w* j) d
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。8 F4 U* g0 X! L$ r
$ P2 }( Y  J% q0 V( w
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..) b) Y2 s. U  G, `2 Z3 I
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...8 K; p; I1 N2 s/ T4 c
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

. N8 L8 F3 L) }6 F' 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 )

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