QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
7 B& H% m2 k" L7 y! v% u其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:) Q& {7 F- p0 F1 n* w7 j
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?8 q1 [$ k( T& o' {! V9 b
2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?- R/ S. F$ [. ~# \$ o6 e% t+ \
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
0 l& p4 Q; G$ }( ]; A版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    % J/ I$ S3 c2 C* [
  2. Dim ptInsert(2) As Double/ s: l3 m5 \% K: p+ ?5 x
  3. Dim lastSel As AcadSelectionSet
    2 s3 l1 }  T) y4 W) f& t
  4. Dim lastBlock As Variant! s: e' f7 t* D5 H2 H8 a' B: {+ C
  5. ptInsert(0) = 0
    . J% ?' C% A' z3 \9 E7 l4 r- ]: Z
  6. ptInsert(1) = 03 D6 v/ w" P9 b* k6 w
  7. ptInsert(2) = 0& D  ~4 ?+ V3 e$ a+ S8 g$ R- D
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0# a9 [$ k. H1 B; V/ J$ V

  9. $ n* l  p5 }2 Y! E
  10. + Y) C/ S. G/ i9 L% E0 g7 Y
  11. * L( i6 U0 G% b8 P9 B
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    % |. t/ u, ^6 c( W. B
  13. lastSel.Select acSelectionSetLast& o9 e5 [3 J( M* q# e
  14. 2 U- _) `4 b4 K, ]( b& U  S
  15. Dim B As AcadBlockReference '声明一个块参照变量
    & p7 X7 i4 I# a" W4 Q0 j4 q
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    5 M* o# m: n8 {5 X. ^& w2 J
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    ! c: [% Y# F8 c- x
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组9 v/ `7 m1 V7 ]/ u# I% I5 t
  19. , l' p, ?5 L$ V! [7 N
  20. lastSel.Delete '删除选择集
    . D% U) ?1 j. w* ^1 v( c2 Y
  21. " d" O1 B2 E$ z3 ?
  22. # t  q$ \; D! L
  23. ThisDrawing.Regen acActiveViewport$ u: p2 [& O( V% S% |

  24. , S; \/ c9 ~$ k* t- ~% g
  25. 3 _% }( y- H$ b) r! l, q4 |2 z
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()( b) _: h6 _2 t. R6 M( M. M
  2. Dim ptInsert(2) As Double& `, K, `( g& a1 g2 @* y$ u. p
  3. 'Dim lastSel As AcadSelectionSet- T4 [4 w7 C7 a, Y2 f; j$ A
  4. Dim lastBlock As Variant% Y9 [2 k0 ^+ U* a! h' ~
  5. ptInsert(0) = 0- i2 j+ P& _+ O4 K+ o- f( Z
  6. ptInsert(1) = 0
    4 ]9 n+ o- _% D; l! h* t* D
  7. ptInsert(2) = 00 ?  b2 R" n7 t# M9 y

  8. , @6 _1 {  ]! M6 C1 A

  9. # I6 L  p& T: ~  t9 A. d: N$ H- C1 `

  10. 9 B! V8 L; N8 t4 G+ a8 w* l
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '1 |9 M6 A4 x- A% s' q
  12. 'lastSel.Select acSelectionSetLast
    2 S# {# v5 S3 Z1 l7 p
  13. 0 [% E5 L% ~  y; c
  14. Dim B As AcadBlockReference '声明一个块参照变量/ ?# p3 R! l. B. Y4 P
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标+ @3 E/ V8 c! u( u
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)  M! m: u: j2 }1 ]) u* ?5 C7 ?
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    % d6 i7 c: J) ~' D6 r/ c( T

  18. ' a/ p  W& u% o9 m) m7 T
  19. 'lastSel.Delete '删除选择集$ h4 X: n' h8 _4 Z$ _) `
  20. . R) p" M+ [- {2 C, ^# M) H
  21. $ ^; Z3 H& F6 ]- K6 y
  22. ThisDrawing.Regen acActiveViewport+ L& E" K3 T, q1 l: m
  23. 7 O: z2 g4 U0 D& [  }( C
  24. 1 V) J3 u# |) `
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 , v( D: M; B! x+ q
2 D, G: k+ _; t4 C
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
& s3 m+ c+ _4 m# U: S2 U
  1. pNew(0) = P(0) - 500
    / f$ t9 l2 n- z% W
  2. pNew(1) = P(1) + 1405.8
    0 y* U$ ^: y1 B+ Q8 I" m7 P$ X, C/ v
  3. pNew(2) = P(2)
复制代码
4 N6 M' n% L8 x4 O
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
, ^# m5 l3 T* N就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。* Z6 K8 d+ h  V( O- _8 ^+ i
谢谢版主1 e& Y/ W2 \8 O7 X2 n9 Q! C2 T

6 U4 B0 C$ I: q& {( m) y" U
0 [/ Y' _. X% W/ Q) n( M
  1. Private Sub cmdInsert_Click()
    ; m/ ~, j3 p! q- L& P3 }9 M
  2. Dim ptInsert(2) As Double+ ?5 [. p% }9 y2 n& g, n
  3. Dim lastBlock As Variant1 u: ?# V6 q% A1 [
  4. ptInsert(0) = 0
    4 F' Z) F/ I7 J5 L" d2 b# O% n& E
  5. ptInsert(1) = 0
    7 L: ^& H9 Q& o6 m* g9 u3 e# \& I
  6. ptInsert(2) = 0' d- I* F2 j* C: c, E' O/ v" E

  7.   Y6 @3 K; G$ h% ]; \- w. f: W/ H
  8. '----------插入块A 仅仅一个---------------------------------
    / f3 r! g/ p. r3 ?: I' ^# v/ b! r
  9. Dim B As AcadBlockReference '声明一个块参照变量) @" T* f1 ]( Q2 [1 a1 {
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标# t' `+ e1 O' f% A
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)  Y( R+ A/ y# J* L# |0 L1 P
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组" L1 m, Z( a1 I% ]' A' K
  13. '----------插入块A 完成---------------------------------
    . S4 @8 b9 @- O' v2 b6 U. W' e  z0 e. X
  14. 3 j/ s! H) B+ L5 B/ z
  15. '----------插入块B---------------------------------
    8 J5 o; \  t) }6 X, q+ b- G
  16. '第一个块,需要单独插入
    & m  _9 a( h3 x) j, F
  17. Dim pNew(2) As Double- @+ H4 X# Z' s' s. e, b) X* k
  18. pNew(0) = P(0) - 500
    4 N4 N  d- j# I9 l% z9 m- n% g
  19. pNew(1) = P(1) + 1405.8: H4 S" q5 A( a; {6 [. I5 I
  20. pNew(2) = P(2)+ S( ?/ i! `9 ]6 `- f
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    ' a- W/ Y7 Z. u, ]% C- d
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    / G3 U; w# j8 A0 ~) H" J
  23. ThisDrawing.Regen acActiveViewport' [# X& {# B1 K; K, j- c
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑   q0 p4 n0 h: e# U2 a
4 i1 J  j8 l/ _0 P- s0 \
3# tataki
# U- N6 y; _# }4 m5 }8 O1 ^3 R看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 $ B$ @! p& K3 g+ J
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角/ `1 g0 Y9 \, D/ X
  2. Dim MaxPoint As Variant'右上角
    ( L8 o6 K7 I0 E2 ]9 R* o0 ?3 a4 L
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
% C. T3 `5 V, P, e原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..4 J( K" o/ S: m2 }  d% ?
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。- Q1 |( ~7 D, \  v8 b

  ]. L0 T4 L% v" V% p1 H# |2 Z另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..& }0 f6 [7 L2 g9 a3 S4 |1 v
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
& }9 c; f4 _3 E7 c" w. ptataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif
; C9 R& x- m% x2 ?
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 )

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