QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
6天前
查看: 9217|回复: 8
收起左侧

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。' B0 _/ w  Q3 p- {) i$ R% h3 `8 ~' y
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:& h$ @/ [6 ~% q  r, }9 g( f: t- V
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?3 T  I; H0 y1 H) y" x. Y6 Y$ B9 T& o
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
  b- B/ o1 F6 B- H9 w; w之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了% {. p# T. F+ ]/ G7 |* s5 o  a/ Y) _
版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    - b* M/ X9 R/ I4 s4 B
  2. Dim ptInsert(2) As Double
    9 d; S# `; T; `, J- x  Z
  3. Dim lastSel As AcadSelectionSet
    / k- J( \4 p: I1 [
  4. Dim lastBlock As Variant
    , R. Z2 U4 L# _/ _# l( B5 s
  5. ptInsert(0) = 0* ?! v  {7 d8 e/ c9 Q+ k, _( M3 V
  6. ptInsert(1) = 0
    3 {' A' E: \: [4 N1 D
  7. ptInsert(2) = 0
    . X6 K! `5 @0 N; V, N# \
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0# @3 E, L& T: J; b8 X0 J

  9. ! r; H! u: D2 {
  10. # e* K" G7 E, i
  11. ! \  L0 Y8 X+ q! V) V
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '3 ]) ^+ M) w/ Y& ^0 b
  13. lastSel.Select acSelectionSetLast
    ! i5 }7 @: X2 f
  14. # R( G* m) t0 V4 ~4 T2 V- V
  15. Dim B As AcadBlockReference '声明一个块参照变量
    8 w2 m2 P( c3 K7 ~, N6 B$ z, \/ |, e
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    ( P8 W  ?* |) d8 P( |% z
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量* a9 _+ B! ?& E! u7 T/ A
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    , q" ~/ a7 [: b0 w1 V/ M
  19. 6 \" _- ]- T* a* D' I
  20. lastSel.Delete '删除选择集4 ^( f8 f5 `. r: H8 o* r+ V

  21. $ K, d( x4 r5 t* g) f- p5 L
  22. 7 I8 f7 X6 I% F. W4 W; k* u
  23. ThisDrawing.Regen acActiveViewport$ d# i$ ~5 L. \. Z" b0 f

  24. 8 Z9 Z- r( ]& X# m4 I. o( j' Z
  25. ' `4 E% l$ M& M' m- g$ \  c
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()
    + m* O+ C! B6 h6 M' S1 i2 ?
  2. Dim ptInsert(2) As Double* X7 S; `: J2 Z2 G. R0 J& N6 c
  3. 'Dim lastSel As AcadSelectionSet
    ; ?( G) C& X! j7 w. p
  4. Dim lastBlock As Variant
    : O7 ]5 j: ?8 ]" ]: Q
  5. ptInsert(0) = 01 j/ R1 F9 o2 a0 q7 y
  6. ptInsert(1) = 0
    ' G' P2 F! n; e
  7. ptInsert(2) = 0
    5 {* D* V+ U5 a
  8. + R1 _2 u$ @2 A- [

  9. ( Z7 l4 M% j* D7 E; V3 m! y) z8 |

  10. . k% ^! i. G. c1 k: }& V
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    % H) F! L  j% n( `3 q8 Z
  12. 'lastSel.Select acSelectionSetLast
    ' e% z; o; a7 e

  13. 3 H4 c9 n8 k/ ]2 e' E7 Z! ^# B) C
  14. Dim B As AcadBlockReference '声明一个块参照变量$ k2 y' O9 p5 ^1 u
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标  z  @+ ?! a, G( {5 x( D
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    5 D0 U  V8 F9 V3 }! T0 l
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组. `( T- g# `- n
  18. . O3 @( ~. l: X1 l! P5 R
  19. 'lastSel.Delete '删除选择集
      W1 U% ?0 Z* P! l4 t
  20. + {2 W7 ~( C" x, b; t
  21. 8 `" S; Z% [5 L* J% y; L/ [
  22. ThisDrawing.Regen acActiveViewport, p6 ]% r! f7 ~

  23. - S* M7 Q* H) W: y4 _# p2 A) O

  24. 4 K- n! I' G$ c8 q
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑
" E" f+ E$ ?0 Y1 {% G
- P1 T8 f+ P" u: T) \+ G首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:6 A1 A) _( c; D7 M3 |: j  D
  1. pNew(0) = P(0) - 500- n8 x2 w' |7 ^6 j! d9 I5 c
  2. pNew(1) = P(1) + 1405.84 |: r. }# w6 n/ D" u% V( k6 Q
  3. pNew(2) = P(2)
复制代码

6 i0 L7 f4 H$ G, ?: N1 @  r我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?8 o$ d* l) c- _
就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
+ |3 Z! _" D" t' c1 }2 l谢谢版主
# L' q* r5 X' }5 S
7 N* |2 N; g; ^' b' v5 k! f: b2 n& y% o' Y* Z3 R+ u3 f* w2 N( s0 W, Z
  1. Private Sub cmdInsert_Click()
    1 `0 p9 Y3 Y' L; N6 f) y* r
  2. Dim ptInsert(2) As Double
    8 X1 }' @  z5 l: a4 c) i9 x/ q1 t/ h
  3. Dim lastBlock As Variant
    3 H" a0 W/ Q: C  W* U0 ?
  4. ptInsert(0) = 0
    ) I+ X. ?! _3 U/ a+ p
  5. ptInsert(1) = 0
    0 x# I, `: u# {& r% Z/ s6 F- k. K
  6. ptInsert(2) = 01 H. `8 n/ h+ B* {; s6 \& m

  7. $ X" N5 o* L" y+ H8 @
  8. '----------插入块A 仅仅一个---------------------------------
    + r9 i) \- W% u5 q. Q
  9. Dim B As AcadBlockReference '声明一个块参照变量
    0 A: x! R2 ~2 v; k# j0 Z2 }
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
      W' O! s$ F2 g8 G$ p/ H+ {
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)$ t/ E  j/ w- U! x
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组4 o  Q* c% w, a% A
  13. '----------插入块A 完成---------------------------------/ `' h+ E( Y6 k8 }
  14. + Z1 x: ^5 l* R7 k- [% n. V4 {
  15. '----------插入块B---------------------------------  h0 E  P1 z/ y) ^* c/ o( U  W
  16. '第一个块,需要单独插入
    $ Z* _4 `/ R* J$ a: |6 v
  17. Dim pNew(2) As Double+ z4 b9 i" r, @
  18. pNew(0) = P(0) - 500
    ' v+ n  m/ y# U8 k% v
  19. pNew(1) = P(1) + 1405.8
    3 u! j- |! k7 o7 R: m& w
  20. pNew(2) = P(2)
    $ x6 b* t4 `+ p% U# P
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    0 a8 v+ c; Z1 a8 l
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组7 ~- m" B" E, a0 E
  23. ThisDrawing.Regen acActiveViewport
    ' g. ?' ~8 }7 u, o. d! m
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
* \, ^6 z$ a5 l# Z4 E7 m& W( O3 Y* _8 y4 y; T+ D! _
3# tataki ; m) ^% B6 O1 J" F0 @3 K% y/ M  l
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵
0 N6 x4 D% e1 Z* J: ZVBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    3 E9 F( x3 A: y" ?$ n
  2. Dim MaxPoint As Variant'右上角
    ! M0 k$ h! ~/ V  |1 I4 M7 Q" f
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!6 k1 ^8 w5 O. y% d8 ]' g; L1 R
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..) ^- }+ M! p! d5 i" `
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。: u+ s" s6 ^# }) U
( m$ ^* B" a1 Q5 t3 F7 x$ ?; |! e
另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
1 ^: i" s* I4 P% X# D, \$ o哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
. o8 z8 g1 g8 y' ttataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

3 j0 G5 Y% C" Ylisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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