QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
我定义了4个块,想通过输入每个块的数量达到左边的效果,就是块能自动在我需要的点插入,不用手动选择。3 m% W2 n9 A2 W
其中blockA作为基本块,我指定插入点是原点,当要插入2个blockB时,我是想这么实现:先获取上一个创建对象,也就是blockA的坐标,但是有两个问题:6 i- E# M3 O, A* |0 F! P' _
1.我知道有acSelectionSetLast的方法,但是不会用,怎么把选择的上一个创建对象赋给某个变量然后提取需要的信息呢?
# v( p' b0 K" k1 B& |2.我想获得的坐标是blockA的插入点坐标,这个怎么实现呢?
& Z8 }9 o! m) E之后blockB的插入点就根据blockA的插入点通过计算后插入就行,现在卡在那两个问题那里了
  [! b! N& u' u版主和高位高手们支个招啊。我把图形和程序(论坛不支持,我做成压缩包了)都上传上来了。谢谢
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()
    0 v7 t" L; g& u) n$ _( b
  2. Dim ptInsert(2) As Double$ m6 b) Z+ S8 L7 m; T
  3. Dim lastSel As AcadSelectionSet7 g- l5 Y. X# l+ |; m
  4. Dim lastBlock As Variant, z! ^- {5 b$ f; C
  5. ptInsert(0) = 06 g  F) F/ B5 \9 P, O
  6. ptInsert(1) = 0) l4 w8 b" w+ H9 j+ _
  7. ptInsert(2) = 00 o0 r4 E. S7 N' K- w+ i/ ~
  8. ThisDrawing.ModelSpace.InsertBlock ptInsert, blkAName.Text, 1, 1, 1, 06 Y9 h: h1 W  K) G0 ~
  9. 6 m# |; F2 X" k- M
  10. $ U' ~2 d: s: |. y; n' G

  11. 5 `7 F  \4 I1 t7 _& y, j7 e
  12. Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '1 X2 V; U2 `( T/ }
  13. lastSel.Select acSelectionSetLast
    % ?5 Z: r* @, J* `

  14. 5 f! e# h2 c% _5 F) {
  15. Dim B As AcadBlockReference '声明一个块参照变量
    1 R$ I. o9 P/ l1 `7 o; w
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    1 A! y: W3 ^  W9 ^' }
  17. Set B = lastSel(0) '把选择集中的第一个(也是唯一一个)元素(最后创建的对象,即上一步在图形中插入的块参照)赋值给变量
    1 E4 O0 |; b5 y4 W7 b- i
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组; p& s! {8 z. z6 T' ^+ P
  19. , ^) ]; P2 f; I9 j: W
  20. lastSel.Delete '删除选择集. j' n* e2 J2 b8 y: d7 F
  21. : Q4 c. A0 F) t5 V2 e# m, y
  22. 6 h) I8 }0 U* Y. ]% D3 |4 s9 L
  23. ThisDrawing.Regen acActiveViewport2 `. H, `6 D) K; }) K8 _, {9 h
  24. 1 `$ p0 D  u3 f4 _1 M6 n9 i( F* D. A

  25. * w7 N8 _' b9 ]( c# Q- S% `
  26. End Sub
复制代码
不过,对于本例,完全可以不用选择集,直接使用前一个对象的返回值.如方法二:
  1. Private Sub cmdInsert_Click()6 a( h3 C. y/ ?; z$ _! h5 g/ W
  2. Dim ptInsert(2) As Double+ {% X6 c$ ^; N- ?: _% Q( W6 y
  3. 'Dim lastSel As AcadSelectionSet
    8 A! l' S( Y: C+ P3 X' ?" |; I4 [. y
  4. Dim lastBlock As Variant+ t& b' [1 c6 J/ U/ O- L# g
  5. ptInsert(0) = 0
    ! T4 ]+ l! x5 N) }: K2 m; @
  6. ptInsert(1) = 05 L7 \! w. j3 L, b( |7 o% V1 I
  7. ptInsert(2) = 0) L: p) t( [! t/ h6 ?% f% V! F( o; y

  8. 0 R; s0 H% t7 E/ a# F

  9. 1 ], Q+ V6 X* {7 Q

  10. ; W" o2 v# k6 n0 ~5 y7 q5 m$ r2 \
  11. 'Set lastSel = ThisDrawing.SelectionSets.Add("SSet3") '. i' a) Z2 [; I9 O% E
  12. 'lastSel.Select acSelectionSetLast' ?% N) p  `- M  y# J, G4 ~5 Y, v
  13. 1 l9 D" [4 q/ j: b+ P" R
  14. Dim B As AcadBlockReference '声明一个块参照变量
    + |& i! n( e6 q( `4 Z3 J0 w2 \, l
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标+ w. Z+ W' z% n% ~- A. |* R
  16. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)& d) u: c) A  W+ H
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    - X) a3 J  K3 h4 r

  18. 0 J+ K* U  k% j+ T3 B) S+ h
  19. 'lastSel.Delete '删除选择集
    + i! ^/ t6 j7 \! I  R; y  A/ c$ u4 i
  20. # e# c# e, n9 Z
  21. ; N! Q( o) o% D( Z
  22. ThisDrawing.Regen acActiveViewport
    6 L! u) c* h$ O7 e! i3 T8 H
  23. " ?4 H- \: D& @. c
  24. ) u3 @) H/ w' {! M$ ~0 T. ?: ]) ^
  25. End Sub
复制代码

评分

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

查看全部评分

 楼主| 发表于 2012-4-4 09:33:50 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-4-4 11:17 编辑 3 p5 b; |9 Y- s5 }6 S* w+ f

  [8 S# y7 b+ G# B5 W: P6 j9 T首先感谢斑斑大人一大早的悉心解答,你说的第二个思路很好,不用选择集,直接使用块的insertPoint属性获取插入点坐标。我又学到了一招,呵呵。我修改了一下代码,现在可以按照坐标计算后来取得blockB的插入坐标,但是存在一个问题,换算后的坐标实际上和blockA的左上顶点坐标有出入(y方向出入0.72,虽然很小,但是显得不够严谨),因为我是用下面这个坐标换算得出的blockB插入点的:
/ B6 p. i9 p! X& j* e' y
  1. pNew(0) = P(0) - 500
    3 [# C- ?0 S! }  L
  2. pNew(1) = P(1) + 1405.82 _$ j5 g& l% b
  3. pNew(2) = P(2)
复制代码
5 t, V* N1 J8 ?' p; T
我知道出现问题的原因可能是精度问题,所以再请问斑斑大人,可不可以让程序实现在插入blockB的时候,系统通过捕捉blockA左上角顶点来实现呢?
  T3 U' m: _% R+ X9 l* ^) N, o就是Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)这一句中,pNEW如果能是系统通过顶点捕捉后自动产生的坐标数据,而不要是我通过换算后的坐标。: [1 z6 W* K5 `- w% D
谢谢版主
' w& `$ t' T1 `6 u2 e; @; v# z# K* S8 m; g# L, I2 C
  c2 Q$ u9 j; G5 V; J
  1. Private Sub cmdInsert_Click()
    % M1 d/ f9 O+ |$ t" P
  2. Dim ptInsert(2) As Double( _; ?9 S$ s  |, a0 l. i
  3. Dim lastBlock As Variant
    ' |! V  A8 \: J! g) {
  4. ptInsert(0) = 0+ P: R, ^) I* L: i7 a/ U9 p
  5. ptInsert(1) = 0
    ) ~+ ^8 c9 m; @) L3 }% |! e0 V
  6. ptInsert(2) = 0/ x7 q8 D  w! @/ m3 s
  7. * e( C) i+ M9 b8 z0 a1 l* v
  8. '----------插入块A 仅仅一个---------------------------------
    ( m) X+ X: R: D
  9. Dim B As AcadBlockReference '声明一个块参照变量7 j% K2 g! x; ?6 o" M, T% l7 f, G
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标( G1 i" e1 r1 u3 P* |
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    + h( b- r" m6 N$ u+ F5 ]& v
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    6 G' Y: c/ z. E0 e/ p
  13. '----------插入块A 完成---------------------------------
    6 _8 p8 p' o5 I  O! _8 }& k

  14. , s0 b% F$ D& h1 G: `6 |+ j
  15. '----------插入块B---------------------------------# s/ X- H1 N& A& q+ ]$ o1 \" F+ s
  16. '第一个块,需要单独插入
    3 k  D$ j; @& g) t. j
  17. Dim pNew(2) As Double
    5 V4 P1 R/ w$ K4 ]" ]( }0 N/ _
  18. pNew(0) = P(0) - 500  V2 P1 A& q( z1 v0 I) z
  19. pNew(1) = P(1) + 1405.8
    $ f  n" j) J( j& Y1 |, R
  20. pNew(2) = P(2)
    - G/ f% ^4 c0 K
  21. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)6 Q- l$ e: O1 T( n
  22. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    2 P8 N! p* {% S$ e8 G  U# K$ y
  23. ThisDrawing.Regen acActiveViewport
    9 P) E4 O. Z. p- Z
  24. End Sub
复制代码
发表于 2012-4-4 11:27:05 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-4-4 11:30 编辑
/ w7 a9 K: \4 G- T  H; H
. c, D0 g  _0 g$ n, B3 ?- D: m7 A3# tataki $ r" s  r+ \2 Z2 z
看了一下你的图,blockA的高度是1405.08,而你在代码中却是
  1. pNew(1) = P(1) + 1405.8
复制代码
当然相差0.72了,呵呵 + ^( l* t5 i0 v3 Y
VBA不能实现对象捕捉,但可以通过图形对象的GetBoundingBox方法获取图元对象边框的最大和最小点,即对象在图形界面所占矩形范围的右上角和左下角点.角点是以 WCS 坐标值返回,且矩形边与WCS的X, Y, Z 轴平行。方法是
  1. Dim MinPoint As Variant'左下角" B7 t" }. \! \( g. W
  2. Dim MaxPoint As Variant'右上角. f1 x% C" l; f8 B9 j
  3. object.GetBoundingBox MinPoint, MaxPoint
复制代码
然后再通过这两个点坐标结合对象的其它属性进行相应的计算
 楼主| 发表于 2012-4-4 11:52:18 | 显示全部楼层 来自: 中国广东珠海
呵呵,漏看了一位数,罪过罪过啊!) `# W# @" R2 m1 J% T1 l
原来在VBA里不能实现对象捕捉,这一点真是没想到,在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
# V9 h! B4 L3 o# n1 i7 \7 b0 i哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各有千秋。% `# w  q6 I! x& B3 G4 o% `8 }: P

3 h9 r$ S8 a4 J另外,GetBoundingBox这个方法我知道,以前发过一个帖子问过,当时也是斑斑给回复的,呵呵,印象深刻
发表于 2012-4-4 23:04:16 | 显示全部楼层 来自: 中国江苏无锡
在lisp里我记的可以通过设置好捕捉模式去捕捉点来着..
/ K, c; |; s; P2 ]( `6 K哎,可惜lisp的语法常常搞得我一头雾水,也慢慢放弃了,转投vba,两者各 ...
& A0 t0 G: z( I9 P  C0 H) z& rtataki 发表于 2012-4-4 11:52 http://www.3dportal.cn/discuz/images/common/back.gif

. J, R7 i$ Q7 Y' e( }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 )

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