QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。% Y; v  }( {' }* R" q$ M
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:: E/ ^- w7 M5 K' t1 H2 U8 j
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?7 w& e& N, A/ X7 Z5 a5 ^/ X$ Z& T
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?5 o7 E6 h( y2 Y6 u: f
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
3 E, M# Y- `! J2 Q0 F版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    & M3 V6 \% d. U6 ?
  2. Dim ptInsert(2) As Double: h( n- P: B* Y! g+ E
  3. Dim lastSel As AcadSelectionSet/ E. z1 [' ^" v. s3 Q
  4. Dim lastBlock As Variant! A( d) @" c3 j% u
  5. ptInsert(0) = 08 \1 R( b- j* [% |" d7 f7 z
  6. ptInsert(1) = 08 f. ~# q7 A5 L  D5 s& E, E# ~
  7. ptInsert(2) = 0; f7 [) S  {4 A9 y2 m
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0. y* G3 d) }7 W% x

  9. % x8 x) @# u7 d

  10. 8 U* Z: D' q- E/ {# M
  11. # t8 ?8 Y) ~: `$ L- E" U
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '# h$ s  J% E) t. V
  13. lastSel.Select acSelectionSetLast4 `# q9 W; n8 O1 z
  14. 8 q' _) W8 I$ Z# x+ v% G' Z
  15. Dim B As AcadBlockReference '声明一个块参照变量
    0 O6 ]8 d# ]% C! N9 B  b1 {, F
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标, S; }4 g; l( H+ @# ]
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    . x! w. n0 F; q
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    & `: z$ o+ {3 G) i  C

  19. ) S6 l1 ]! u+ o; v0 j
  20. lastSel.Delete '删除选择集$ I# I" I: Q# h9 ]; B' U
  21. " N- Z9 a" u5 N3 @4 t  z9 W
  22. ; V  m$ r# P) A* B7 A7 D' d) }" P: ?1 s
  23. ThisDrawing.Regen acActiveViewport
    . j  ^: m$ I1 _3 }( b6 x9 p
  24. / _2 H" D2 Z7 P3 }; b2 ?' l+ g
  25. 5 u3 H+ }8 B# Q  h% h2 o7 C
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()' g4 n# x5 H$ P1 B" U
  2. Dim ptInsert(2) As Double4 \" {" [1 U7 ?( {5 w* D0 ?
  3. 'Dim lastSel As AcadSelectionSet0 Z' A6 f; A3 [3 O! J
  4. Dim lastBlock As Variant5 l9 Z8 ^3 }& T3 A' |) J; p
  5. ptInsert(0) = 0
    # g6 C& r, T1 `0 ~0 C: \7 G- n
  6. ptInsert(1) = 0/ W: R. |* g6 L% P( U8 C# {1 a
  7. ptInsert(2) = 03 E1 }  |3 L8 s8 U! B- A2 }$ X

  8. % @2 G8 Z' i. u1 N" u+ r! i

  9. ) r5 Z6 K0 r' c6 X. T
  10. - \& e" h* ~1 c2 a+ h( |
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    5 G% [$ G6 U3 I5 ~
  12. 'lastSel.Select acSelectionSetLast. p! X+ d1 M& U! _& t  f

  13. 2 i  B) f7 L; g) |
  14. Dim B As AcadBlockReference '声明一个块参照变量2 G+ t. I+ @) b9 J
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标6 Q, O% X$ e6 p* v/ H
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)# ^7 O; U- C  N' ]  k; n
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组0 I5 D7 ?2 o: i$ l! t6 w
  18. 7 }/ }8 i0 `1 @( I" [. \$ h/ X0 T
  19. 'lastSel.Delete '删除选择集
    9 M+ l9 [+ z' G2 X7 a

  20. 4 m" V% D, I6 N/ `  k
  21.   v  P+ q; E6 q% P- m5 d% p9 r
  22. ThisDrawing.Regen acActiveViewport1 o7 F5 M9 K3 p% t6 j8 J4 f3 F
  23. , u) J1 |) l# B5 i

  24. 4 {) N9 m2 X2 T* l4 V1 |( h
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 & w% [( A9 x/ y2 x+ G' O

2 Q( o' o* i' e5 K4 O3 F: L2 X, _* Z首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:2 q9 Y4 b3 O: Z+ _& U" d  ]
  1. pNew(0) = P(0) - 500
    # S/ `" s8 ^2 W3 D7 f$ F( j; L0 q0 k- A
  2. pNew(1) = P(1) + 1405.8
    ! v% v& b! t$ b1 }) N9 b
  3. pNew(2) = P(2)
复制代码
: @' x2 T& {+ q6 r; ]( U
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
, J% L! T9 x) T! e7 n* H6 y就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。& K6 H9 E  ?! {4 r/ ]
谢谢版主
" L* w% e' i2 d/ ^% ~% O- ^8 s* W) Q# x8 f/ M) C" }
, O; b1 p; B* j. ]# \, C
  1. Private Sub cmdInsert_Click()  F9 J6 c& [% h
  2. Dim ptInsert(2) As Double( P# F) K1 l" M5 G5 F0 o* ?* O4 c0 N5 v
  3. Dim lastBlock As Variant
    3 w- I- u" A4 r- G, o' N
  4. ptInsert(0) = 09 S0 F1 v2 D7 Z" \- w
  5. ptInsert(1) = 0& `5 C, z: B/ d" M8 O  s
  6. ptInsert(2) = 05 |2 o# ?% _% {' t: R
  7.   h% G6 W: |8 x8 b- Y5 B
  8. '----------插入块A 仅仅一个---------------------------------
    7 r- [+ ?; t& q
  9. Dim B As AcadBlockReference '声明一个块参照变量9 Z; R% v8 i: q' |9 t! X
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    2 A# s4 v8 {& z7 g. G( n" f8 b# U
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    0 V5 V, n) e& \
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组3 K% Z2 _/ G/ U# g3 p. D' U5 g% m
  13. '----------插入块A 完成---------------------------------+ s! j; T; j. V& {8 e7 k5 [
  14. ( ?& H$ I' D+ y: D
  15. '----------插入块B---------------------------------4 C5 L7 }% u; Q3 s! p, i+ |
  16. '第一个块,需要单独插入+ c+ j, e6 a; K* C
  17. Dim pNew(2) As Double; S/ X& T3 P0 R0 M0 w' Q
  18. pNew(0) = P(0) - 500
    ( E+ `1 f) D# a8 F$ ?: B
  19. pNew(1) = P(1) + 1405.8) e9 Q# q$ y2 K
  20. pNew(2) = P(2)
    * H- V1 K' I. [
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)7 c% D6 O$ q  r, b, ]
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    - z9 a5 P) f& t. Q, C
  23. ThisDrawing.Regen acActiveViewport" q) P) y. f- ]0 e
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 2 p0 |' r8 v7 g4 f4 P* S  Y
9 ]- v7 x6 {/ S" ?+ }
3# tataki
5 _/ i* T6 k" T0 B: K& Q! U, {$ D看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 3 j, F5 ^9 Y: {0 h3 E/ d
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角3 s* D. v9 B4 }7 W: `* Z
  2. Dim MaxPoint As Variant'右上角
    ! n2 _7 ]4 P& f
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
9 U3 X2 e# R1 @9 f原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..  R  N4 q& H7 d. V
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
) Z9 A) r+ I  a8 m4 P, V3 O+ P2 U( ]4 u6 d! ]7 |% F
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..4 ]; f7 W" S$ V1 W; H2 V
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
' B) ^$ E/ l/ v' z" [  F* ftataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

' k* ~& L; `  I1 s3 I3 \  alisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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