QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。
; a9 q/ T0 q# d" x/ N其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:1 ~) v6 x+ W. P5 J/ \$ t
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
8 E, S8 H/ F7 \5 W7 D) G2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?5 A' A$ M2 ?0 w. b# P$ O
之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
6 ^# a- ]& t' I版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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(). F' Y. V+ [) m9 c7 w) W2 `
  2. Dim ptInsert(2) As Double
    . z) ^9 F( T( g4 D
  3. Dim lastSel As AcadSelectionSet# P% m3 @3 @4 O& W5 l
  4. Dim lastBlock As Variant' o9 k, f* S( i; l7 g7 \2 v0 n5 D
  5. ptInsert(0) = 0) ^& i# R* T9 F& [# N
  6. ptInsert(1) = 0
    , v9 W4 `+ H. I5 t/ v) x! k
  7. ptInsert(2) = 0. ^& u' e! t5 @0 `: J" v. @$ S
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 0+ I$ z6 h# _) y/ F

  9. $ w) G3 y. G) J9 ?
  10. 7 v# O# z+ q- \% M& E. ]# u

  11. $ f* Y* m8 @+ [: A6 ?( W: |
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    5 J! ^$ t; H: ~5 H5 H+ z8 i  x
  13. lastSel.Select acSelectionSetLast
    # G: r7 H" A! J7 w3 g. `

  14. ) A, O: Q0 l  P/ S2 J! F
  15. Dim B As AcadBlockReference '声明一个块参照变量. O, f, i/ Q- V5 b3 M5 y
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标- n! Q( w8 y& R- P
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    # k) H: k+ g6 A- z7 i6 ^: K& H
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    # ~1 c4 D; W8 q! u3 [5 e' m- q7 f
  19. 2 I- |; w/ n( k* E+ B! u9 K0 r6 v2 {
  20. lastSel.Delete '删除选择集6 T- w9 x+ ?6 \2 Q% g

  21. , O. N' r: Y5 L/ D
  22. 0 r, |+ k4 ]7 w% r* ^. n: A
  23. ThisDrawing.Regen acActiveViewport3 f8 d) j5 e1 i: q6 {/ T2 A

  24. : `# R9 {* D# D9 }, O4 J% x7 e

  25. + f( i; @. @6 p# g* p' o; x
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()* W9 p$ L6 T5 q8 B
  2. Dim ptInsert(2) As Double
    ' U  i5 V4 {5 \7 @& ?- W; P
  3. 'Dim lastSel As AcadSelectionSet  n; J- _! ?+ I# i
  4. Dim lastBlock As Variant$ b) w* ~5 e# [5 E
  5. ptInsert(0) = 0
    : s! I( w# a3 a$ ~
  6. ptInsert(1) = 0
    ' R6 I% T2 q" C% W0 S5 D- b& D' c2 z* i
  7. ptInsert(2) = 0
    ) m( y0 m0 a2 R; l
  8. - G) ]! X. }+ |$ v' U

  9. * n& M% g& F) {! A3 a7 Q3 u

  10. 3 k0 @5 u3 ]- K8 \& o3 L* G3 ?
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '
    * C# `. @. T- u; H
  12. 'lastSel.Select acSelectionSetLast
    # r/ [8 D0 D8 o( {- u2 I9 m3 \

  13. ! U. c, V+ _; M) x: r) n, f* P$ s. g
  14. Dim B As AcadBlockReference '声明一个块参照变量
    ( g, o5 Q! z$ Y
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    % |5 S( t1 U. |. r% q) H' H6 \: `
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    ( U. j8 _9 d* Z
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ( F4 B* y$ Z7 b0 h$ R, f# G% F
  18. 9 P- y& e2 k8 y) T; J2 z0 p- e3 f
  19. 'lastSel.Delete '删除选择集
    1 ~' z' E: W$ Y. b8 l) k. M
  20. ( m  s7 a  \9 W" v) i1 {' k
  21. & @1 M1 `3 J' @3 L. z  `
  22. ThisDrawing.Regen acActiveViewport& C6 {) e' i! V
  23. ! S( p/ @7 x# _+ a! Y- F4 m3 L5 c

  24. ! f2 B) H. E0 @  }. [
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 1 Z" J! ~- S# ?4 m
, `5 }/ V& L1 N* o, s; t  K
首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
; Q+ C7 A3 m% ^" Y
  1. pNew(0) = P(0) - 500
    - P1 Q; X: [$ P( y( r, V
  2. pNew(1) = P(1) + 1405.8& C0 x5 m2 p$ M, E) @- `' U0 D
  3. pNew(2) = P(2)
复制代码
3 H) f0 j; F5 U# M, T; ^" L( ]9 y
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
# C0 `4 P  J% @& s  |0 l; g1 Q- b就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。
# {% X9 C* g( {' C$ d+ @9 G2 |谢谢版主* G" H) u) i! p9 ~( T  M
! R2 R; K0 H( L! V: @

% h& x* r3 K+ J) V
  1. Private Sub cmdInsert_Click()
    7 @5 u: B4 r* Z7 i  H# B% x! u) E6 E
  2. Dim ptInsert(2) As Double
    1 u4 P" r- B! ^# V, l3 L, A2 u
  3. Dim lastBlock As Variant
    7 u4 e* f( ]0 _8 E
  4. ptInsert(0) = 0
    . I# g- L* E2 s6 h9 w0 T# j: B
  5. ptInsert(1) = 0
    ! }8 O: c, U/ f. G
  6. ptInsert(2) = 0/ I. x! G# B! m* A3 }
  7. 9 C5 d) b7 Q& B
  8. '----------插入块A 仅仅一个---------------------------------
    . ^: Q% v4 J' A$ E% e- B+ Z. C# L
  9. Dim B As AcadBlockReference '声明一个块参照变量
    " N. R3 U; G0 o3 ^" _2 O% g$ _
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    + {0 G/ q% G# M/ b3 i: h8 H
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)# t' o* j* L" t1 W! s5 J. F0 z
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组& M# O2 D$ f6 p  q  C2 k
  13. '----------插入块A 完成---------------------------------( u5 l5 v. R7 o

  14. * l7 w9 B5 p" |: r. A4 Q5 m& T
  15. '----------插入块B---------------------------------
    # k$ ?% n4 _& f8 X  E: Q% d9 w: D
  16. '第一个块,需要单独插入
    " T+ _* F9 z0 J1 K) ?! I
  17. Dim pNew(2) As Double" W0 x7 P# f8 q" }9 @
  18. pNew(0) = P(0) - 500
    ! }9 u+ d& v; `, A
  19. pNew(1) = P(1) + 1405.8  \2 P2 S- L9 I
  20. pNew(2) = P(2)
    % Q- g" k3 s) M8 b) l1 l
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)5 B4 Y7 h- o0 y& k3 @3 `
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组; ]' T1 p# \/ f+ ~$ o
  23. ThisDrawing.Regen acActiveViewport
    7 a1 @! p% C9 M( R* X) s
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑   `: `% G9 x( k7 b0 ?
* @' ~! n! b! C, Z- {& R1 M. e( r
3# tataki
3 X: X5 v; }; z2 q5 y- Q( b看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 3 M2 L  p1 t+ L4 P5 Q' A
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角
    3 c5 o7 x9 E  g: p. ^, B# C
  2. Dim MaxPoint As Variant'右上角  v" d7 O0 f9 L$ J+ w
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!
3 e2 p! u2 I4 F& t# G% ?+ v5 w7 R原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着... |, o- V: Z  I/ K3 \5 [
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。3 ^! E& }* b, Y$ B1 [

2 p, p) c: v* [2 N  w另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..  T6 D' K9 P6 v
哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...* s% j. a" G  M# J  ]
tataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

% a' [  e1 ]+ Q; x3 Glisp一头雾水还能设置捕捉,牛啊!说得大家一头雾水~~
发表于 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 )

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