QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。. M, j# Q, R( ?3 |/ ~& x
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:
9 P& f- b8 p& N) d( S7 _: ]1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?5 m4 G5 M; T: C7 ?+ K
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
* g1 y- A+ {& n8 O% z0 A; b" S之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了; [6 |3 l0 P2 S: w) W
版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    5 u7 o/ n% {( ?# \/ h" s
  2. Dim ptInsert(2) As Double
    4 s' b3 e7 ^& h% x) ]) J. N
  3. Dim lastSel As AcadSelectionSet5 f4 d' _! E6 Z  u" i
  4. Dim lastBlock As Variant
      G3 x2 P5 j; b6 j5 y" j
  5. ptInsert(0) = 0( F! Y9 J' v0 L$ I, q8 ~/ I
  6. ptInsert(1) = 0
    ) [" i% P0 u: }! c5 q: F5 S. V- M
  7. ptInsert(2) = 0) j6 i/ }  X4 r2 }# y3 o& p) E1 n8 Y9 f, C
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0- X1 J4 G* u" n+ u) S
  9. " Q7 l( Q' F3 q+ P

  10. 5 M9 D# f6 |: x% O+ u9 V& e

  11. 9 U' r. S% @4 r/ O
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '; C: Q( C) }. [1 E& s  h
  13. lastSel.Select acSelectionSetLast
    4 @; u( ~4 {1 w: C! \9 K! l

  14. 1 o! C! ]6 E/ r$ ^5 o
  15. Dim B As AcadBlockReference '声明一个块参照变量8 p0 \# H' I8 {, z3 a# V! L  k; \
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    7 B4 E5 A4 X7 K: X7 B& ]; X
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量: C. b" G( u3 t/ T4 A& R  J" U
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    . d1 m& F1 ^% H1 \0 L8 \$ W
  19.   ]' b4 C" a$ [' l+ k! h
  20. lastSel.Delete '删除选择集5 ]8 R1 H, J7 Y7 G" |

  21. / p8 C# q4 m4 V- ?

  22. . h( V& V/ `; y  W  y) m
  23. ThisDrawing.Regen acActiveViewport% E+ M$ {( l8 _* Z

  24. & G2 Q2 B5 H+ {
  25. , z7 [. L5 E+ |4 ~9 W% N3 o
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()0 o9 P/ X4 M3 A0 ~# _6 b- A& z
  2. Dim ptInsert(2) As Double
    ( p) {& \# i* A' ^0 X2 `) y$ O
  3. 'Dim lastSel As AcadSelectionSet
    $ \, D$ |/ m) x, j
  4. Dim lastBlock As Variant
    . T; L0 [& E! s" |) T
  5. ptInsert(0) = 0
    6 e: ?; r1 ~9 Z! F" o' D+ l6 t
  6. ptInsert(1) = 0+ E1 s* N! x; y2 F# ^' {: c
  7. ptInsert(2) = 0! A; F6 L5 c  n6 s# Z% G2 ?. U7 w+ k. |
  8. / ^3 b8 Y6 Z. ~6 {0 m$ b
  9. 1 S& ]" y8 z' _* u8 k& p$ M

  10. 7 a+ Q5 {" M$ K( D" g* N9 j, g
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    1 W7 B: d7 [9 s+ A$ k8 v' m
  12. 'lastSel.Select acSelectionSetLast* ]4 E7 b1 x" F- |# {
  13. : H2 J; k" ]; [
  14. Dim B As AcadBlockReference '声明一个块参照变量+ T. N7 j7 B( t" M2 C
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    % H$ j# B. V) h$ c' Y& O% N
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    , P: T' l! W6 m, N
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组& _, v8 s1 S6 |$ @% S
  18. 1 A7 O) p' N  R4 M& L/ L
  19. 'lastSel.Delete '删除选择集
    , ~8 J9 P8 M3 Q" h5 j3 G

  20. ' s/ y" o, o9 N: L! p
  21. 1 d9 j. l/ z8 Z5 E$ _9 ]4 ~
  22. ThisDrawing.Regen acActiveViewport
    ) Z/ T% C$ Z6 s! R/ }
  23. # ?: P% E6 _9 }$ F

  24. " R4 M5 b" Q6 R6 F% c3 E
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
6 k8 d0 R: U) s' Z+ f* D6 f% V% Z" {  H$ J, U' Q: [, i
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
8 y. Y7 o2 w  a: m" p0 o% w7 j0 `
  1. pNew(0) = P(0) - 500) P$ E: ~: b( q4 j& Z. l) e# k3 g
  2. pNew(1) = P(1) + 1405.8' o% |' r, @# m, f
  3. pNew(2) = P(2)
复制代码

$ `' M: x0 ]; X; V6 Y- h2 Q我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
  {) Q9 Z. L* W就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
* I5 p; O. P2 I% H- l! O! A! f0 n谢谢版主
( D9 a+ M% D) Q! p+ ]
' [6 @  m0 ?1 K9 W8 |' S& c$ U) W+ p7 N' }
  1. Private Sub cmdInsert_Click()0 M5 U. a1 A; }6 L1 x: D
  2. Dim ptInsert(2) As Double" d4 \  c$ C0 C+ H1 y# h
  3. Dim lastBlock As Variant' B- v- N4 K. U: k1 x* j7 H
  4. ptInsert(0) = 0
    $ q! C3 b" A5 y4 @( Y8 g' k1 x$ B
  5. ptInsert(1) = 0
    1 @& Y" r2 Y+ j" h  t2 {
  6. ptInsert(2) = 0+ q# _! |' v& \* @; z
  7. % }1 K8 t3 L, a' J, k( g
  8. '----------插入块A 仅仅一个---------------------------------; \, p2 N; O* a& W$ n6 m5 p
  9. Dim B As AcadBlockReference '声明一个块参照变量" g& @3 Z. D* s* R' Y9 L. }) T6 U! E
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    - M0 W* F9 U3 n) v. a0 s7 e
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)  D& j3 ]/ w# V  e/ U2 {% B
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ; j9 F" v0 ^& {* N* D8 h
  13. '----------插入块A 完成---------------------------------6 G; \- V$ ^- Z6 n+ M( a1 G
  14. 2 m. C+ \  ^2 `- ]( E& Y* F
  15. '----------插入块B---------------------------------
      l4 H! F% M( y0 e8 o' }
  16. '第一个块,需要单独插入: ?7 u9 O) n# N; s/ T+ w- A
  17. Dim pNew(2) As Double
    ; a. n! `% S* D9 _
  18. pNew(0) = P(0) - 500
    1 h7 C; u, q; l" z9 _( _8 F2 b  i( }
  19. pNew(1) = P(1) + 1405.80 n( ^6 f1 D4 F* B; o
  20. pNew(2) = P(2)
    9 |0 z8 U# b( l' X. e$ P
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0); t; r! @7 Z( ]% r; [
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组0 N0 q$ h* H5 @( y) L
  23. ThisDrawing.Regen acActiveViewport
    - Z2 z5 X8 F, _
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑 " w" v4 k1 h* H& a+ E8 u6 N0 A

4 W/ U0 b4 D: S3# tataki
: D% C' k0 i5 X看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 2 I0 T6 h9 [8 L* t# r0 W) v2 j' T
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    / u! p, D0 |8 Y( P
  2. Dim MaxPoint As Variant'右上角
    8 Y8 i; l& {  N; O# o9 ~. _8 B
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!# }# e9 _1 y9 ]: s
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..4 z+ {8 \/ ]: w9 M3 M1 S
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。
0 d2 d, k: V* T% k0 S( o, n8 U' M8 D: s3 t0 O' b3 s' d- R6 [: N
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..& \, v) O% ]% b6 }9 ~8 J8 u1 ~
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...8 @0 v0 @; c8 ]; J" U$ s6 m4 P( Z
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
. N8 r4 _5 q+ p
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 )

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