QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。- [1 q9 E9 U( s# o6 m. ~
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:: @7 V+ u  Y9 I4 w
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
  ]& Y' V2 D: Y6 d0 k; l; G2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
0 P. t# f4 y9 W! V/ a之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
0 T2 V- s: t# Y- |, a版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()  s% G! [. R. f
  2. Dim ptInsert(2) As Double
    & z/ r7 K2 Y( m' p% ~7 \# e8 D
  3. Dim lastSel As AcadSelectionSet
    ! B- E* y4 y1 \7 T: p. s' c
  4. Dim lastBlock As Variant% }$ c. d3 w$ W8 t, O
  5. ptInsert(0) = 0
    3 T' {" `' S. _! _& I- ?0 \% r
  6. ptInsert(1) = 08 D$ y& l( X' z4 D+ F+ N
  7. ptInsert(2) = 0
    5 I6 g$ }7 l5 `
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0
    1 N9 e9 e& p2 G7 u$ y2 m
  9. - l+ z( ]1 H+ k: d
  10. 3 u% h; y3 I- K! d+ x

  11. , j/ R7 S' W6 S3 _( \
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    5 ~7 B3 u) ~- g+ [+ Q% e
  13. lastSel.Select acSelectionSetLast7 w5 |) ^7 N$ M. R

  14. - y& A: i7 @( s& t
  15. Dim B As AcadBlockReference '声明一个块参照变量2 f2 g) N' r: K) b9 d
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
      ~& T: P- I. H- E% D1 r, o
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    2 h8 N* v  @2 ~% F& F
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组4 ?2 R$ k! z: |9 b

  19. 8 L, S2 Y9 `0 F
  20. lastSel.Delete '删除选择集
    ) J4 Z9 D! E( Y& ^. r* h
  21. 7 T0 A1 ?6 Y$ z/ q

  22. ; V, t. O, K1 c( c% ?1 Y6 x
  23. ThisDrawing.Regen acActiveViewport
    ( l, h7 Y- U+ B! E' v2 p
  24. + H  g% y/ X+ u4 y6 Z8 [  o/ F
  25. : g$ ]" ?4 i" p! B( r) r
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    5 v, ?' L- f! O9 z: m5 w
  2. Dim ptInsert(2) As Double* y, r7 \% X: r, N5 ]
  3. 'Dim lastSel As AcadSelectionSet
    6 x1 N' U6 m3 i& m
  4. Dim lastBlock As Variant) I6 y/ L+ w7 V& F8 ?0 t/ w
  5. ptInsert(0) = 0. a3 k+ G9 w, x3 T. \3 z
  6. ptInsert(1) = 0. S/ y$ |+ P- `8 l. M" |
  7. ptInsert(2) = 0
    * P  O$ v3 y. t1 }9 [

  8. 5 N2 u+ M- h  d8 Z9 y
  9. ; N: k3 C: B. w# i# ]  D. }3 R1 I- ^- p

  10. : ]  N7 u2 ]) y  p" i8 t- ~9 T
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    ! ]$ E' i. }" a# O$ y- {$ Z
  12. 'lastSel.Select acSelectionSetLast
    & }! D, m# B  _' F

  13. * A: w) b$ l( c; b; k( T
  14. Dim B As AcadBlockReference '声明一个块参照变量
    2 }, \7 `! V" B* s% T
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    7 ?+ B. Z2 [9 k  |. C
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ) v) S! x: t# [0 n2 Z
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ; [" i7 [( J. |) n  c

  18. ' h" k, i; ~# I5 b/ W
  19. 'lastSel.Delete '删除选择集
    ; H: {4 _2 e; X( N6 |/ s
  20. 0 W2 A1 D3 l( z# h" l: i8 R( }
  21. / J/ X6 e3 P; {6 c: n
  22. ThisDrawing.Regen acActiveViewport: J/ e8 L0 b# u3 V" X
  23. 9 v) h0 `: i& N& u
  24.   b# B' G/ m; C6 ?! F% \
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 0 z8 |3 {% ~$ k/ E

7 a, L1 B% s' c1 L0 W1 L! D- s首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
: m+ W9 k6 ~4 e: v( D
  1. pNew(0) = P(0) - 500
    * B9 p+ b. y5 ]/ D* {/ ^) W: y
  2. pNew(1) = P(1) + 1405.8# W  `9 k- h5 F+ U. F: ?
  3. pNew(2) = P(2)
复制代码

/ A5 Y5 H% f* ~+ H6 _! d, {我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?, u7 e7 X2 y1 G2 a! F3 d
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。  ^0 k+ C5 o# p+ U
谢谢版主
9 H( U9 o/ ?" S" n7 D8 F0 r' L" P* q3 t4 S& _0 j, C
+ a3 u9 V% N5 j8 G: m
  1. Private Sub cmdInsert_Click()* G& h& x" N( l1 y+ J
  2. Dim ptInsert(2) As Double
    ! o5 O, d( i' f
  3. Dim lastBlock As Variant
    7 ?% \/ c) R! s  E: ^
  4. ptInsert(0) = 0
    $ t5 B7 d& j9 G8 e+ z' W! \+ E
  5. ptInsert(1) = 0! f8 b/ V9 j: N! T7 f# c7 J
  6. ptInsert(2) = 0& Q) B" T: ?4 b/ e$ W% K
  7.   W4 u; M7 L5 _* @
  8. '----------插入块A 仅仅一个---------------------------------& @, h  v, E* Z. M+ Z2 F
  9. Dim B As AcadBlockReference '声明一个块参照变量( y/ a4 n7 u% o
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标7 h# D! V. o+ V; @
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    6 O! q5 I8 ]2 e) H& f: O  b
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ) l2 R8 P% O0 ^$ n
  13. '----------插入块A 完成---------------------------------0 V2 _/ A6 [! ~, N4 H5 F: ~4 {
  14. 2 I6 o( \3 `; O% [7 b1 G/ u" e
  15. '----------插入块B---------------------------------. {9 ]" V% z" M: B
  16. '第一个块,需要单独插入2 Q7 H8 V* C. m  `% l. ^
  17. Dim pNew(2) As Double5 y% C: n3 _, _. Z+ N) v/ J5 x
  18. pNew(0) = P(0) - 500
    , d$ D' F1 {5 P1 H4 q; h
  19. pNew(1) = P(1) + 1405.8
    0 N0 e8 W& P6 K1 @8 b9 Z5 f
  20. pNew(2) = P(2)
    ' O; T1 H3 P) F6 ]- }# ^7 }, f0 T
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)* `7 `2 V4 c) U3 z
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    & n/ E2 s, n' d2 t0 C0 Q/ I
  23. ThisDrawing.Regen acActiveViewport$ ~+ }" R$ R2 |' V1 n
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 % }2 U0 \0 U0 N, l( s) b$ Z) C
4 L; J! z# j/ l2 U2 \) n' I
3# tataki # i. W. ^7 l. S, E" @6 S
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
# T: I5 G& y" W9 G/ d- }) `  F% P% AVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角) |4 q6 r. U' M1 T  W2 Y# _' t
  2. Dim MaxPoint As Variant'右上角
    : `# T3 L9 R! X
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!9 i9 h3 @! R4 l3 Y. }3 }2 ^
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
3 S* W' J. c8 y5 @4 }哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。. R7 v* ]; f- j8 Y7 |
+ {/ u& }+ c2 Q* r) L4 n
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..) \$ k* v! k2 i) I4 D% E0 }
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...* N: E6 E9 w& y; ]& H( n: u. m
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

' m& c$ F2 U( Mlisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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