作者:marsarden                                                       转载请注明

在对solidworks原有功能进行改善的过程中,有效地利用solidworks提供给我们的应用编程接口(API)来编写提高我们工作效率的程序是其中手段之一。本文在于总结作者进行此类开发的经验,给大家提供一些经验性建议。

目录

第1章       概述... 2

1.1      内容简介... 2

1.2      名词解释... 2

1.3      预备知识... 3

第2章       录制、编辑、运行宏... 3

2.1      录制、编辑、运行宏基本步骤:... 3

2.2      一些基本的建议:... 3

第3章       代码格式及帮助信息... 5

3.1      代码格式:... 5

3.2      获得帮助:... 6

第4章       常用对象模型... 7

4.1      综述:... 7

4.2      SldWorks.SldWorks : 8

4.3      SldWorks.ModelDoc2:... 8

4.4      SldWorks.PartDoc、SldWorks.AssemblyDoc、SldWorks.DrawingDoc:... 9

4.5     SldWorks.feature、SldWorks.Sketch :... 9

第5章       零件 PartDoc. 9

5.1      综述:... 9

5.2      选择对象的话题:... 10

5.3      访问并修改特征: 12

5.4      草图的话题:... 17

第6章       装配体... 18

6.1      综述:... 18

6.2      组件的话题:插入零部件到装配体... 19

6.3      配合的话题:在装配体中添加配合... 22

6.4      由于说到参考,顺便讨论一下配合参考:... 26

第7章       工程图... 28

7.1      综述:... 28

7.2      注释的话题:<script language="JavaScript" type="text/javascript"> document.title="Solidworks二次开发—12—工程图的note - "+document.title </script>... 29

7.3      生成图纸的话题:并讨论如何解决实际问题... 30

第8章       总结:... 40

第1章        概述

1.1         内容简介

Solidworks在提供了强大的三维建模功能的同时,也为使用者提供了开放的应用程序编程接口(API),通过调用这些API,我们可以将solidworks中一些重复单调或者规则明确的操作使用程序语言描述,通过简单的人机交互,让计算机自己来完成此类工作。掌握了此类本领,可以在以后的工作中,开阔自己的视野,更加深入的了解软件本身工作的原理,并且,改善自己的工作,提高工作效率和质量。

本文旨在总结作者工作中获得的经验,专注于solidworks软件本身特点,文章中示例的代码基本上使用了vb语言描述,选择vb语言是因为其语法简单易懂,并且和应用程序间有很明朗的接口不需要再学习其它技术(如果使用c++,可能需要读者拥有COM知识)。

Solidworks提供了极其丰富的API,并且有很完善的帮助系统。我们可以使用 Microsoft VBA编写SolidWorks Macros或者使用其他编程环境编写Standalone and Add-in Applications。(使用visual studio到.NET都可以)在SW的API帮助中我们可以很明了的查看API调用语法及相关的示例代码。本文不可能对每一个API进行细致的解释,在后面章节主要指导大家如何使用软件提供的帮助来在需要时得到有用信息的手段。

本文所有API和代码都以solidworks2005 sp0.0 版本为准。

1.2         名词解释

API :应用编程接口Application Programming Interface

对象:即计算机抽象出来的一种事物,在面向对象的程序设计中它表示由数据和与该数据关联的操作组成的类的具体实现。

属性:对象所具有的属性,识别及说明对象的特性。

方法:对象可以使用的对数据的操作。

1.3         预备知识

首先我们的读者应该有简单的VB经验。当然如果没有也可以临时抱佛脚(VB语句是直观易懂的),边看代码边学习。很好的掌握SW中宏的录制功能多阅读API帮助中的示例代码,是自学的最佳途径(虽然SW的宏录制功能相比EXCEl来说代码不是很清晰)。

其次solidworks软件应该非常熟练,读者应该有使用solidworks实际建模的经验,,这是能够写出良好代码的基础。否则看到一些对象名称也不能了解它对应了软件的那个功能。

如果英文不够好,请准备及时词典,如金山词霸等。Solidworks提供的API帮助是纯英文的,solidworks汉化的还不错,不明白为什么不顺便把API帮助也翻过来。

准备好,我们可以开始了.

第2章        录制、编辑、运行宏

2.1         录制、编辑、运行宏基本步骤:

开始solidworks编程的最快方式就是录制宏。宏可以记录用户的操作将其记录为一系列solidworksAPI的调用。在solidworks“工具”菜单“宏”中有运行、录制、新建、编辑等选项。

我们选择“录制”来开始记录用户操作,选择“停止”来结束宏的录制。结束后会提示保存宏文件,其后缀名为.swp。(估计是solidworks program的意思吧)。录制到停止间对solidworks进行的操作都将记录到宏文件中。但是直接录制的宏程序的可用性很差,我们需要对它进行一些合理的优化,清理多余的语句,所以在录制完成宏之后需要编辑它。

编辑宏的时候,选择“工具”菜单“宏”中的“编辑”,此时提示你选择要编辑的宏文件(swp文件)。选择后进入编辑界面(其实就是VBA的编辑器,叫集成环境也行)。

需要说明的是,如果之前你在excel、word等软件中录制过宏程序,那么可能solidworks录制宏中的垃圾数据要更多些。

2.2         一些基本的建议:

Solidworks在帮助中也有一个大体的介绍,在编辑一个新录制的宏时可以需要删除下面的多余代码(Delete extra lines of code):

1、The following variables are declared automatically in a SolidWorks macro. Delete any variables not used in the macro. SolidWorks对象的声明是自动产生的,可以将没用到的删除

2、Delete all lines of code that change the view. 删除切换视图的代码

arden says:像这样的 Part.ActiveView().RotateAboutCenter 0.0662574, 0.0346621 无情的删掉吧

3、Delete all ModelDocExtension::SelectByID2 calls appearing immediately before ModelDoc2::ClearSelection2 calls. However, do not delete ModelDocExtension::SelectByID2 calls appearing immediately after ModelDoc2::ClearSelection2 calls. Delete all ModelDoc2::ClearSelection2 calls appearing immediately before ModelDocExtension::SelectByID2.

删除所有紧挨ModelDoc2::ClearSelection2之前的ModelDocExtension::SelectByID2调用,不要删除紧挨ModelDoc2::ClearSelection2调用后的ModelDocExtension::SelectByID2。删除所有紧挨ModelDocExtension::SelectByID2之前的ModelDoc2::ClearSelection2。

下图为VBA的集成编辑环境:

编辑完成后,按照程序的要求来运行宏,在VBA编辑器中点“运行”开始执行程序,需要注意,有些宏程序的运行有前提条件,比如需要事先选择好一个特征等。第一次运行不一定成功,这时候就要对宏代码进行调整,反复一个编辑代码、测试运行的循环,最后得到比较满意的结果。

加载宏到solidworks有很多种方法我们只介绍最简单的三种:快捷键、菜单、工具栏按钮。可以参考文档《SW技术文档-2005041402-加载宏到solidworks的三种方法.doc》

第3章       代码格式及帮助信息

3.1         代码格式:

这章中,我们给出一段完成简单功能的代码,并讨论如何从帮助中获得有用信息。

首先,打开soliworks,选择“工具”、“宏”、“新建”,给新的宏文件起名字为“openprt.swp”。清空vba编辑器中的内容,拷贝或者输入下面的代码,保存。

'---------------------------------

' Preconditions: None

' Postconditions: Specified document is opened.

'---------------------------------

Option Explicit

Dim swApp       As SldWorks.SldWorks

Dim fileerror   As Long

Dim filewarning As Long

Sub main()

Set swApp = Application.SldWorks

swApp.Visible = True

swApp.OpenDoc6 "d:/samples/hotrod.sldprt", swDocPART, swOpenDocOptions_Silent, "", fileerror, filewarning

End Sub

上面的代码来自solidworksAPI帮助,它打开d:/samples/目录下的零件文件hotrod.sldprt。我们来分别解释一下上面代码的内容:

'---------------------------------

' Preconditions: None

' Postconditions: Specified document is opened.

'---------------------------------

注释:注释块说明了程序运行的上下文:前提条件(Preconditions)为:无 NONE ;运行结果为:打开指定的文件。API帮助中的示例都有这样的格式,需要大家在使用时注意其上下文约束条件。

Option Explicit

Dim swApp       As SldWorks.SldWorks

Dim fileerror   As Long

Dim filewarning As Long

声明变量和对象:swapp为一个solidworks应用程序对象。其它两个为long型整数,用来保存错误和警告id。

Sub main()        这是主过程,以main为名称。

Set swApp = Application.SldWorks   刚才的DIM语句只是声明了对象swapp,现在使用SET定义对象

swApp.Visible = True        设置应用程序可见

swApp.OpenDoc6 "d:/samples/hotrod.sldprt", swDocPART, swOpenDocOptions_Silent, "", fileerror, filewarning

打开文件d:/samples/hotrod.sldprt 。

End Sub

3.2         获得帮助:

当我们想从这个示例代码中了解打开一个文件的细节时,我们需要OpenDoc6函数的参考,可以在索引或者搜索中查找OpenDoc6,得到如下信息(汉字为我的注释):

Description:描述此API完成的功能

This method opens an existing document and returns a pointer to the document object. It also allows control over whether or not to:此方法打开一个已经存在的文档并返回指向此文档对象的指针。它在打开文档时允许做下面控制:

  • Suppress displaying dialog boxes 禁止对话窗口
  • Open the document read-only     只读打开
  • Open the document view-only     只看打开
  • Convert a drawing to a detached drawing   将工程图转换为断开的工程图

Syntax (OLE Automation) 语法:

retval = SldWorks.OpenDoc6 ( filename, type, options, configuration, &Errors, &Warnings )

Input:

(BSTR) Filename

Document name or full path if not in current directory, including extension文件全路径

Input:

(long) Type

Document type as defined in swDocumentTypes_e 文档类型

Input:

(long) Options

Mode in which to open the document as defined in swOpenDocOptions_e 打开选项

Input:

输入

(BSTR) Configuration

Model configuration in which to open this document 配置设置

  • Applies to parts and assemblies, not drawings 只在零件和装配体适用
  • If this argument is empty or the specified configuration is not present in the model, the model is opened in the last-used configuration. 如果未指定任何配置将使用最后一次打开的配置。

Output:输出

(long) Errors

Load errors as defined in swFileLoadError_e 打开错误

Output:

(long) Warnings

Warnings or extra information generated during the open operation as defined in swFileLoadWarning_e 打开警告

Return:返回

(LPDISPATCH) retval

Pointer to a Dispatch object, the newly loaded ModelDoc2, or NULL if failed to open

Remarks备注:

When opening a parent document (assembly, drawing, and so on):

  • SolidWorks also opens any additional documents that are referenced in the parent document (parts, subassemblies, and so on).
  • SolidWorks follows certain rules in trying to locate its referenced documents. If explicit Search Folders have not been set using Tools, Options, System Options, ExternalReferences, then the first place SolidWorks looks for the referenced documents is in the current working directory. If SolidWorks finds the referenced file in the current working directory, then it is loaded from that directory. … …

我们应该具备的素质就是,可以按照上面的参考内容明白API的使用方法和规则。而我们常常需要注意的焦点是语法(Syntax)知道需要输入什么参数返回什么对象就基本OK了,不要被前面一片英文所迷惑。

最后我们介绍一下API帮助的目录:

Solidworks 2005 API Release Notes :此文档树下为sw2005版本的新特性:新对象新函数等

Programmer’s Guide :此文档树目录下为sw编程向导,提供了开始编程的向导、sw对象模型总揽和实际编程中的注意事项等内容。

Examples  :此文档树目录下为sw所有示例工程,分为c++和VB两中语言大类。我们经常需要访问的地方。

APIs  :sw提供的所有API定义及参考。

Obsolete APIs :sw已过时的API。

第4章       常用对象模型

4.1         综述:

学会录制宏代码,并从帮助中得到代码中API使用方法后,我们介绍一些常用的对象模型,并给出一些使用方法。这些对象是sw最基本的对象,几乎所有程序都会使用其中的几种,也是我们可以很直观想象到的对象模型:

4.2         SldWorks.SldWorks :

此对象代表solidworks应用程序。我们可以使用此对象进行应用程序层面的操作:打开、保存、关闭文档;设置用户界面的状态等等。一般来说我们的sw程序总是首先定义此对象才能进行其他的操作:

声明和定义示例:

Dim swApp   As SldWorks.SldWorks

Set swApp = Application.SldWorks

或者

Dim swApp   As SldWorks.SldWorks

Set swApp = CreateObject("SldWorks.Application")

调用属性或方法示例:

swApp.Visible = True

swApp.OpenDoc6 "d:/samples/hotrod.sldprt", swDocPART, swOpenDocOptions_Silent, "", fileerror, filewarning

4.3         SldWorks.ModelDoc2:

此对象代表solidworks的文档。Solidworks有三种最基本的文件格式:零件、装配体、工程图。它们各自都有自己特定的对象来表示,但是solidworks设定了一些通用的方法和属性来操作这些对象。ModelDoc2对象可以直接对这三类文件进行操作。

声明和定义示例:

Dim swmodel   As SldWorks.modeldoc2

Set swmodel = swapp.OpenDoc6 "d:/samples/hotrod.sldprt", swDocPART, swOpenDocOptions_Silent, "", fileerror, filewarning   ‘打开文档

或者

Dim swmodel   As SldWorks.modeldoc2

Set swmodel = swapp.activedoc  ‘得到当前文档

调用属性或方法示例:

swmodel.GetPathName   得到模型的路径

4.4         SldWorks.PartDoc、SldWorks.AssemblyDoc、SldWorks.DrawingDoc:

上面三个对象分别代表solidworks三种文件格式。使用它们来操作相应类型的文件。

声明和定义示例:

Dim swpart      As SldWorks.PartDoc

Dim swasm       As SldWorks.AssemblyDoc

Dim swdraw      As SldWorks.DrawingDoc

Set swpart=swmodel

Set swasm = swapp.OpenDoc6 "d:/samples/hotrod.sldasm", swDocPART, swOpenDocOptions_Silent, "", fileerror, filewarning

Set swdraw =swapp.activedoc

调用属性或方法示例:

swpart.MirrorFeature  镜像特征

swasm.AddMate2    添加配合

swdraw.NewSheet3  插入新图纸

4.5       SldWorks.feature、SldWorks.Sketch :

代表solidworks中的特征和草图对象。

还有很多对象在此就不再介绍,下面的三章将针对零件、装配体和工程图分别讨论。

第5章       零件 PartDoc

5.1         综述:

零件是sw基本文件类型之一,我们可以通过此对象创建新零件、得到零件的各种、信息控制零件中的特征属性等等。下面是PartDoc的对象模型:

我们知道特征是组成一个零件的基本对象。但是从上图我们可以看出来,特征对象并不是在零件对象下层的。察看API帮助我们知道,特征是在Modeldoc对象下。在Partdoc下只能对实体对象(Body2)进行操作。所以很多对零件进行的操作,我们需要使用Modeldoc对象。

5.2         选择对象的话题:

首先来学习两个API,这两个API完成选择对象和得到所选择对象的功能:

SelectByID2和GetSelectedObject5这两个函数,第一个通过给出对象的name选择对象。第二个通过启用程序前已经选择的索引得到对象。其中的SelectByID2基本上在sw录制宏时所作的选择操作都是用了这个API,但它的局限性在于,程序需要知道所要选择对象的名称、类型(在swSelectType_e中定义)并且函数并不返回所选择对象而是一个执行状态。如果想得到我们刚才选择的对象,则需要用到另一个函数GetSelectedObject5。

使用GetSelectedObject5之前需要介绍一下SelectionMgr对象:此对象允许你得到所选择对象的信息,对其进行一些操作。GetSelectedObject5就是SelectionMgr对象的一个方法。可以使用ModelDoc2.SelectionManager来得到一个SelectionMgr对象。并且需要注意的是sw将所选择的对象进行了索引,我们可能同时选中了多个对象,通过GetSelectedObject5(index)中得index值来得到不同的选择对象。

看下面程序,它使用SelectByID2将当前打开的模型文件中的特征“拉伸1”选中,如果选择成功的话再使用GetSelectedObject5得到此特征:

‘++++++++++++++++++++++++++++++++

‘Filename Selefeat.swp : Select feature”拉伸 1”

‘++++++++++++++++++++++++++++++++

Option Explicit

Dim swApp As SldWorks.SldWorks

Dim Model As ModelDoc2

Dim feature As feature   ‘定义一个特征对象

Dim boolstatus As Variant ‘定义api返回值

Sub main()

Set swApp = Application.SldWorks

Set Model = swApp.ActiveDoc   ‘前面已经介绍,上面两句话基本上是固定模式

' 选择叫"拉伸1"的特征

boolstatus = Model.Extension.SelectByID2("拉伸1", "BODYFEATURE", 0, 0, 0, False, 0, Nothing, swSelectOptionDefault)

'主要就是这一句话,在写Option Explicit后函数的最后一个参数swSelectOptionDefault可以使用0来代替

If boolstatus = True Then  '如果有“拉伸 1”这个特征下面的代码将其选中

Dim SelMgr As SelectionMgr  ‘ 声明一个selectionmgr 对象

Set SelMgr = Model.SelectionManager  ‘得到当前模型的选择对象

Set feature = SelMgr.GetSelectedObject5(1)   '此处使用一个索引来得到特征

Debug.Print feature.Name   ‘ 在立即窗口 打印 特征的name属性

Else

Debug.Print "Error"

End If

End Sub

两个函数的VB语法表述如下,具体请参考API帮助:

ModelDocExtension::SelectByID2

Syntax (OLE Automation)

retval = ModelDocExtension.SelectByID2 ( Name, Type, X, Y, Z, Append, Mark, Callout. SelectOption )

SelectionMgr::GetSelectedObject5

Syntax (OLE Automation)

retval = SelectionMgr.GetSelectedObject5 ( AtIndex )

在选择对象这个话题中我们还要讨论几个API:

ModelDoc2::ClearSelection2 此API清空SW的选择列表,即取消所有选择。

还有activate系列:

retval = SldWorks.ActivateDoc2 ( name, silent, &errors )  ‘激活文档

retval = DrawingDoc.ActivateSheet( SheetName )                     ‘激活工程图纸

retval = DrawingDoc.ActivateView ( viewName)                  ‘激活视图

void ModelDoc2.ActivateSelectedFeature ()                       ‘激活选中特征

选择的话题就到这里结束。

上面有一处关于swSelectOptionDefault的注释大家可能会有疑惑,这里附加上对solidworks API中定义Enum的介绍。为了让API的参数更直观,swAPI中有很多类似的enum定义,它将一系列小整数和字符串描述符对应,在api的语法参考中都描述了相应的代表对象。具体实现细节需要参考VB的语法,这里我们需要明白,如果你在程序前面定义了Option Explicit(强制声明)选项,那你需要在使用这些enum时候定义它或使用不直观的整数作为参数。

Public enum swDocumentTypes_e  ‘这是一个sw文档类型的列举项

swDocNONE=0                  ‘什么也不是

swDocPART=1                   ‘零件类型 在做为参数时 使用1和使用swDocPART效果是相同的,只是swDocPART意义更加明显

swDocASSEMBLY=2         ‘装配体类型

swDocDRAWING=3          ‘工程图类型

End Enum

5.3         访问并修改特征:

    我们已经学习了如何选中一个对象,下面我们针对特征来讨论如何得到选中特征对象的属性并修改它。getchoosed.swp得到所选择特征的一些属性信息:

‘+++++++++++++++++++++++++++++++++
'filename : getchoosed.swp
'date  : 2005-03-22
'used to get the simple hole infomation dep & dia
'+++++++++++++++++++++++++++++++++++

Option Explicit
Dim swApp As SldWorks.SldWorks
Dim Model As ModelDoc2
Dim curfeature As feature
Dim boolstatus As Boolean
Dim featdata As SimpleHoleFeatureData2       '声明一个简单直孔特征数据对象
Dim component As Component2                       ‘声明一个组件对象
Dim dep As Double                                                 ‘孔深
Dim dia As Double                                                  ‘孔径
Dim SelMgr As SelectionMgr                                 ‘选择管理器
Dim ncount As Integer

Sub getselected()

Set swApp = Application.SldWorks

Set Model = swApp.ActiveDoc

Set SelMgr = Model.SelectionManager

Set curfeature = SelMgr.GetSelectedObject5(1)        '得到当前选中的第一个特征

Debug.print  curfeature.Name
Set featdata = curfeature.GetDefinition                       '得到特征的定义

boolstatus = featdata.AccessSelections(Model, component) ' 可以对数据进行访问了

ncount = featdata.GetFeatureScopeBodiesCount

‘此方法得到拉伸特征在多实体零件中所作用的实体数

Debug.print ncount

dep = featdata.Depth               ‘访问属性depth 和 diameter
dia = featdata.Diameter

Debug.print dia & "*" & dep

‘Debug.print "error arden"          '在solidworks中可以使用swAPP.sendmsgtouser2 替代msgbox
featdata.ReleaseSelectionAccess  ‘取消特征数据访问
Model.Save                         
Model.EditRebuild                                        ‘重建模型
End Sub

上面程序运行前,假设你选择了一个简单直孔特征。然后得到这个孔的一些参数:孔深、直径。最初做上面程序的时候,我想象中用Set curfeature = SelMgr.GetSelectedObject5(1) 选中特征以后就可以直接curfeature. Depth了。在参考了API帮助后,我才了解到特征的数据需要先AccessSelections后才能访问。总结一下,要访问一个特征,需要经历这样的步骤:

定义一个特征对象及特征数据对象: dim....as ...

选中这个特征 :比如使用GetSelectedObject5 还有SelectebyID等...

得到特征的定义:GetDefinition

进行访问:AccessSelections

上面的程序没有if选择的容错机制,实际编码中,每个可能出现错误的地方都应该使用if来控制,如下面这句话boolstatus =featdata.AccessSelections(Model, component)。我们就需要通过boolstatus的值来判断上面这个语句运行的是否正确,这里的boolstatus很明显是一个布尔型变量:

If not boolstatus then

‘上面语句运行不成功,写错误报告或退出代码

Endif

已经可以访问特征的各参数了,现在我们来修改它:

要修改前面的步骤不能少,当我们已经可以读取一些特征时,我们就可以给他设定一些值。当然有时需要调用特定的参数。solidworks是ole和com的,所以要习惯这样。

在修改完特征后需要调用函数modifydefinition()来实现变化。

我们给一个例子,这个例子比前面的都要全面,它有很好的容错引导机制,可以直接拿来成为一个稳定的宏程序。

‘+++++++++++++++++++++++++++++++++
'filename : doubleBE.swp
'date  : 2005-03-22
' This example doubles the length of the base extrude.这个例子将拉伸凸台的长度增加一倍
'+++++++++++++++++++++++++++++++++++

Dim swApp As SldWorks.SldWorks

Dim Model As ModelDoc2

Dim Component As Component2

Dim CurFeature As feature

Dim isGood As Boolean

Dim FeatData As Object                    '先声明为object,后面自动匹配为 ExtrudeFeatureData 对象

Dim Depth As Double

Dim SelMgr As SelectionMgr

Sub doubleBE()

Set swApp = CreateObject("sldWorks.application")

Set Model = swApp.ActiveDoc

'确定model是零件或正配体,不是就退出。在这里swDocPART 和swDocASSEMBLY如果不能通过编译则参考

’上面的enum介绍,换为1和2

If Model.GetType <> swDocPART And Model.GetType <> swDocASSEMBLY Then

Msg = "Only Allowed on Parts or Assemblies" ' Define message

Style = vbOKOnly ' OK Button only

Title = "Error" ' Define title

Call MsgBox(Msg, Style, Title) ' Display error message

Exit Sub ' Exit this program

End If

' 得到 Selection Manager

Set SelMgr = Model.SelectionManager

' 得到所选的第一个对象

Set CurFeature = SelMgr.GetSelectedObject3(1)

If CurFeature Is Nothing Then

' 什么都没有选中

swApp.SendMsgToUser2 "Please select the Base-Extrude", swMbWarning, swMbOk

Exit Sub

End If

' Check the feature's type name

' Make sure it is an extrusion

If Not CurFeature.GetTypeName = swTnExtrusion Then

’在这里使用swTnExtrusion我的环境没有通过,改成了Extrusion才ok,参考BodyFeatures_e的定义

swApp.SendMsgToUser2 "请选择拉伸基体特征", swMbWarning, swMbOk

Exit Sub

End If

' 得到特征数据

Set FeatData = CurFeature.GetDefinition

' Get the access selections for the feature data

' 注意: 访问单独零件时参数Component 为 NULL。如果我们在装配体中使用AccessSelections,将访问最高级文档此时我们的component参数需要制定component来得到其他零件。

isGood = FeatData.AccessSelections(Model, Component)

' Inform the user of an error

If Not isGood Then

swApp.SendMsgToUser2 "Unable to obtain access selections", swMbWarning, swMbOk

Exit Sub

End If

' 确认用户选择的是基体拉伸特征

If Not FeatData.IsBaseExtrude Then

swApp.SendMsgToUser2 "Please select the Base-Extrude", swMbWarning, swMbOk

FeatData.ReleaseSelectionAccess

Exit Sub

End If

' 得到深度并增加到2倍

Depth = FeatData.GetDepth(True)

FeatData.SetDepth True, Depth * 2

' 执行修改

isGood = CurFeature.ModifyDefinition(FeatData, Model, Component)

' 改变步成功

If Not isGood Then

swApp.SendMsgToUser2 "无法修改特征数据", swMbWarning, swMbOk

' 取消对数据的访问

FeatData.ReleaseSelectionAccess

End If

End Sub

TIPs:

如果出现特征出现“退回”状态,只能在代码执行到最后调用

Model.Save
                  Model.Rebuild

这两个函数来自动更新。

上面的程序中使用了新的没有介绍的API,只作了简单注释性介绍,如果不理解读者可以到API帮助中查看它的细节。这里只看其中一个API,它可能会经常使用:<script language="JavaScript" type="text/javascript"> document.title="Solidworks二次开发—08--判断是什么特征 - "+document.title </script>

如果我们定义了一个特征对象:

dim curfeature as sldworks.feature

又通过SelectMgr得到了这个特征,然后可以使用feature.GetTypeName来判断是那种:

Select Case curfeature.GetTypeName

Case "Cut"       '一个拉伸切除特征

do sth.

Case "HoleWzd"  '一个异型孔特征

do sth.

Case Else

End Select

end select

这是语法:

Syntax (OLE Automation)

retval = Feature.GetTypeName ()

它会返回一个 (BSTR) retval Feature type as defined in BodyFeatures_e 

其中BodyFeatures_e 内容比较多,在这里都列出来也没什么用,大家可以参考solidworks API帮助。

5.4         草图的话题:

Solidwork中对草图的控制,下面的例子很详细。特征下的草图在solidwork中其实是特征的子特征,我们可以对特征进行GetFirstSubFeature、及GetNextSubFeature得到。

下面是插入新草图的示例:InsertSketch2插入一个新草图,CreateLine2画一条线。

This example shows how to open a sketch, sketch a line, and close the sketch.

'------------------------------------------

' Preconditions:

'     (1) Model document is open.

'     (2) Planar face or a sketch is selected.

' Postconditions: A sketch is opened, a line is sketched, and the sketch is closed.

'------------------------------------------

Option Explicit

Sub main()

Dim swApp                   As SldWorks.SldWorks

Dim swModel                 As SldWorks.ModelDoc2

Dim swSkSeg                 As SldWorks.SketchSegment

Dim swSkLine                As SldWorks.SketchLine

Set swApp = Application.SldWorks

Set swModel = swApp.ActiveDoc

' A sketch on the selected planar face or the selected sketch is opened

swModel.InsertSketch2 True

' A line is sketched

Set swSkSeg = swModel.CreateLine2(0#, 0#, 0#, 0.1, 0.1, 0#)

Set swSkLine = swSkSeg   ‘注意此处的SketchLine和SketchSegment对象

' Sketch is exited

swModel.InsertSketch2 True

End Sub

下面是我从以前的工程中节选的一段代码,它访问特征中的草图数据:

Dim curfeature  As SldWorks.feature

Dim swsketchfeat As SldWorks.feature

Dim swSketch As SldWorks.Sketch                           ‘草图对象

Dim swsketchseg As SldWorks.SketchSegment      ‘草图段对象

Dim swsketcharc As SldWorks.SketchArc                            ‘圆弧对象

Dim swsegarr As Variant

Dim swseg As Variant

Dim swcenter As SldWorks.SketchPoint                     ‘草图点对象

Dim swend As SldWorks.SketchPoint                          ‘草图点对象

Set swsketchfeat = curfeature.GetFirstSubFeature   ‘得到特征的子特征

If swsketchfeat.GetTypeName = "ProfileFeature" Then      ‘如果是草图特征

Set swSketch = swsketchfeat.GetSpecificFeature     ‘得到草图特征

swsegarr = swSketch.GetSketchSegments               ‘得到此草图对象的草图段

For Each swseg In swsegarr

Set swsketchseg = swseg

If swsketchseg.GetType = 1 Then    ' 1 说明为arc,之前没有定义enum

Set swsketcharc = swsketchseg

dia = Fix(swsketcharc.GetRadius * 1000 * 2 + 0.5)  '得到直径

Else

MsgBox "不是圆的草图 "

Exit Sub

End If

Exit For

Next

End If

关于零件的讨论就到此为止,其中的细节太多,本手册只能做为一个编程的指南而不是整体的参考,更多的内容需要读者在实际工作中参考API帮助来完成。

第6章       装配体

6.1         综述:

装配体是由零件和子装配体组成的,其对象模型如下图。相比零件来说,它增加了配合mate2和组件component2两个对象。配合是零部件之间的几何关系,组件为组成此装配体的零部件,本文只对其组件和配合分两个主题来讨论。

6.2         组件的话题:插入零部件到装配体

在往装配体中插入零部件时,我们使用addcomponent 函数。如果需要选定零部件的配置,则需要使用addcomponent4。

先学习下语法:

addcomponent4:

retval = AssemblyDoc.AddComponent4 ( compName, configName, x, y, z)

Input:         (BSTR) compName                    Path name of a loaded part or assembly to add as a component

Input:         (BSTR) configName                   Name of the configuration from which to load the component

Input:        (double) x                                      X coordinate of the component center

Input:         (double) y                                      Y coordinate of the component center

Input:        (double) z                                      Z coordinate of the component center

Output:     (LPCOMPONENT2) retval          Pointer to the Component2 object

需要注意的是:参数1为文件的全名(包括路径);参数2为文件的配置名称;当函数执行成功购返回一个指向该零件的指针。

于是我们可以如下写一个小程序,用来给装配体中插零件:

‘++++++++++++++++++++++++++++++++

‘filename:insertPart.swp

‘write by arden 2005-4-4

‘函数在当前工作目录CurrentWorkingDirectory插入一个名为 “零件1.SLDPRT”的零件

‘前提条件为当前工作目录有名字为”零件1.sldprt”的零件

‘它有配置名为 “配置 1”

‘+++++++++++++++++++++++++++++++++

Dim swApp As SldWorks.SldWorks

Dim Model As ModelDoc2

Dim pth As String

Dim strpath As String

Sub insertPart()

Set swApp = Application.SldWorks

strpath = swApp.GetCurrentWorkingDirectory  ‘当前工作路径

Set Model = swApp.ActiveDoc

pth = strpath & "零件1.SLDPRT"             ‘得到文件的FULLPATH全名

Model.AddComponent4 pth, "配置1", 0, 0, 0   ‘添加零部件

End Sub

然而,这个程序比不是想象中那么好用。为什么呢??回头看addcomponent4的remark,上面这样写:

The specified file must be loaded in memory. A file is loaded into memory when you load the file in your

SolidWorks session (SldWorks::OpenDoc6) or open an assembly that already contains the file.

就是说你想指定的插入的文件必须在调用函数之前已经在内存中加载了。

不习惯,你就不能直接打开多简单,没办法,我还没有找到好的方法,只能按人家的来:

看看下面的函数Opendoc6,它打开一个文档:

Opendoc6:

retval = SldWorks.OpenDoc6 ( filename, type, options, configuration, &Errors, &Warnings )

Input:        (BSTR) Filename                       Document name or full path if not in current directory, including extension

Input:        (long) Type                                    Document type as defined in swDocumentTypes_e

Input:        (long) Options                              Mode in which to open the document as defined in swOpenDocOptions_e

Input:        (BSTR) Configuration                 Model configuration in which to open this document:

Applies to parts and assemblies, not drawings

If this argument is empty or the specified configuration is not present in the model,

the model is opened in the last-used configuration.

Output:     (long) Errors                                 Load errors as defined in swFileLoadError_e

Output:     (long) Warnings                           Warnings or extra information generated during the open operation as defined in swFileLoadWarning_e

Return:    (LPDISPATCH) retval                  Pointer to a Dispatch object, the newly loaded ModelDoc2, or NULL if failed to open

这个函数参数1就是文档的全名,参数2是要插入的类型描述,其中0123分别表示:

0       swDocNONE:不是sw文件

1       swDocPART:零件

2       swDocASSEMBLY:装配体

3       swDocDRAWING:工程图

如果想使用swDocNONE,需要定义:

Public Enum swDocumentTypes_e

swDocNONE = 0

swDocPART= 1

swDocASSEMBLY = 2

swDocDRAWING=3

End Enum

参数3是打开文档的模式,一般我们就选择swOpenDocOptions_Silent  用0 表示,当然还有只读、只看等选项

参数4是打开选项,一般置空

后面是两个OutPut,用来显示错误打开时的提示

函数返回一个指向打开文件的指针。

按照上面的要求我们在向装配体中插入一个零部件时,需要这样步骤:

1、得到装配体

2、使用opendoc6打开需要插入的零件

3、使用addcomponent4插入零件到装配体

我们上面的程序需要这样来修改一下,添加了一个打开文档的函数:

' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++

' insertpart 03/21/05 by arden

'插入零件1

'前提条件:在装配体所在文件夹中有零件“零件 1”存在,并且零件1有配置“配置 1”

' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Dim swApp As SldWorks.SldWorks

Dim Model As ModelDoc2

Dim YSBmodel As ModelDoc2

Dim pth As String

Dim strpath As String

Dim nErrors As Long

Dim nWarnings As Long

Sub insertpart()

Set swApp = Application.SldWorks

strpath = swApp.GetCurrentWorkingDirectory

Set Model = swApp.ActiveDoc

pth = strpath & "零件1.SLDPRT"

openYSB (pth)  ‘在添加零部件之前,先打开它

Model.AddComponent4 pth, "配置1", 0, 0, 0

End Sub

'这个函数打开零件1

Sub openpart(ByVal pth As String)

Dim path As String

Dim newswapp As SldWorks.SldWorks

Set newswapp = Application.SldWorks

path = pth

Set YSBmodel = newswapp.OpenDoc6(path, 1, swOpenDocOPtions_Silent, "", nErrors, nWarnings)

YSBmodel.Visible = False  ‘我不想看到零件1

End Sub

6.3         配合的话题:在装配体中添加配合

下面我们来在一个装配体中自动判断插入合适的零件,并添加配合。

在前面已经基本上说明了如何得到零部件的数据信息、如何插入零部件、如何得到已经选择的特征等。

下面只介绍怎样进行配合。在做配合时,需要经常选择到零件的面、线等,这是一个问题,还有就是介绍一下addmate2函数的使用:

一般进行配合我们按照下面的次序来进行:

1-ModelDoc.ClearSelection2  ‘取消所有选择

2-选择需要配合的实体(entity)

3-使用AddMate2函数进行配合

4-再次使用         ModelDoc.ClearSelection2  ‘取消所有选择

主要的问题在于如何选择合适的面:

由于面的命名没有什么规律,很多时候是程序自动来命名的,这样,不方便使用selectbyID来选择,我也不想使用坐标值来选择一个面,那样做更加糟糕。

在得到一个组件(component)或者一个特征(feature)时,我们有getfaces、getfirstface、getnextface等方法,我们可以使用这些方法遍历一个组件或特征等的各个面,来达到选择面的目的,看下面程序:

‘+++++++++++++++++++++++++++

‘selectface

‘+++++++++++++++++++++++++++

Private Function selectface(dcom As SldWorks.Component2, tp As Integer) As Boolean

Set swdowelbody = dcom.GetBody()

If swdowelbody Is Nothing Then   '错误处理

MsgBox "选择零件失败"

selectface = False

Exit Function

End If

Set swDCface = swdowelbody.GetFirstFace ‘得到第一个面

Do While Not swDCface Is Nothing              ‘遍历各个面

Set swDsurface = swDCface.GetSurface  ‘得到表面对象

If swDsurface.IsCylinder Then                     ‘如果是圆柱面

If tp = 0 Then   'means cylinder

Set swDEnt = swDCface

swDEnt.Select4 True, selDdata

selectface = True

Exit Function

End If

Else                        ‘如果是其它,当然实际中我们可能需要使用select来定义好多分支

If tp = 1 Then   'means plane

Set swDEnt = swDCface

swDEnt.Select4 True, selDdata

selectface = True

Exit Function

End If

End If

Set swDCface = swDCface.GetNextFace

Loop

End Function

此函数接受两个参数,第一个是一个component对象,第二个用来标识选择类型:0表示圆柱面,1表示平面。此函数运行完成后将选择指定组件的指定类型的一个面。需要注意的是我们需要在判断面类型时候需要转换到surface对象。而且选择需要定义一个entity对象,用来select4,达到选择的目的。可能这个过程有些复杂,大家按照这个顺序多测试几次,就明白了它的工作原理。

上面的函数写的并不好,是从我的工程中截取的一段。

下面介绍一下addmate2函数:

Syntax (OLE Automation) OLE语法:

pMateObjOut = AssemblyDoc.AddMate2 ( mateTypeFromEnum, alignFromEnum, flip, distance, distAbsUpperLimit, distAbsLowerLimit, gearRatioNumerator, gearRatioDenominator, angle, angleAbsUpperLimit, angleAbsLowerLimit, errorStatus )

参数:

Input:

(long) mateTypeFromEnum

Type of mate as defined in swMateType_e

配合类型

Input:

(long) alignFromEnum

Type of alignment as defined in swMateAlign_e

对齐选项

Input:

(VARIANT_BOOL) flip

TRUE to flip the component, FALSE otherwise

是否翻转

Input:

(double) distance

Distance value to use with distance or limit mates

距离

Input:

(double) distAbsUpperLimit

Absolute maximum distance value (see Remarks)

距离限制max

Input:

(double) distAbsLowerLimit

Absolute minimum distance value  (see Remarks)

距离限制min

Input:

(double) gearRatioNumerator

Gear ratio numerator value for gear mates

齿轮配合分子值

Input:

(double) gearRatioDenominator

Gear ratio denominator value for gear mates

齿轮配合分母值

Input:

(double) angle

Angle value to use with angle mates

角度

Input:

(double) angleAbsUpperLimit

Absolute maximum angle value

角度限制max

Input:

(double) angleAbsLowerLimit

Absolute minimum angle value

角度限制min

Output:

(long) errorStatus

Success or error as defined by swAddMateError_e

错误报告

Return:

(LPMATE2) pMateObjOut

Pointer to the Mate2 object

返回指向配合的指针

Remarks

To specify a distance mate without limits, set the distAbsUpperLimit and distAbsLowerLimit arguments equal to the distance argument's value.

指定一个没有限制的距离,设定距离限制的最大、最小值和距离值相等

If mateTypeFromEnum is swMateDISTANCE or swMateANGLE when the mate is applied to the closest position that meets the mate condition specified by distance or angle, then setting flip to TRUE moves the assembly to the other possible mate position.

如果是距离或角度配合,配合将从符合条件的最近端进行配合,我们可以设定flip为true,改变配合至另一个合适的位置

Use:使用配合的步骤

ModelDoc2::ClearSelection2(VARIANT_TRUE) before selecting entities to mate.

ModelDocExtension::SelectByID2 with Mark = 1 to select entities to mate.

ModelDoc2::ClearSelection2(VARIANT_TRUE) after the mate is created.

If mateTypeFromEnum is swMateCAMFOLLOWER, then use a selection mark of 8 for the cam-follower face.

如果配合类型为 凸轮,在表面标示8.  注:这个我也不太明白哈哈

If nothing is preselected, then errorStatus is swAddMateError_IncorrectSeletions and pMateObjOut is NULL/Nothing.

如果实现没有限定实体来配合,将会抱错swAddMateError_IncorrectSeletions,函数返回NULL或者Nothing

上面就是API帮助所说的话,下面给出一段示例程序,假设之前我们已经选择了两个半径一样的圆柱面,那么我们来定义一个同心配合:

Set swmatefeat = swassy.AddMate2(1, 0, False, 0, 0, 0, 0, 0, 0, 0, 0, nErrors)

其中的       Dim swassy As SldWorks.AssemblyDoc

Dim swmatefeat As Object

注:在编程中有时候不能实现确定一个对象的类型,我们可以声明一个Object对象,让VB自己去匹配。但这样做是影响了效率代码也不清晰。

要完成一个距离或者角度要麻烦一些,就像上面的remark中说明的:

Set swmatefeat = swassy.AddMate2(5, 1, True, 0.001, 0.001, 0.001, 0, 0, 0, 0, 0, nErrors)

在这里我们需要将min和max都设置成与距离值相等,要不然配合会认为我们设定了高级配合中的限制条件,会报错。并且第三个参数和第二个参数需要按实际情况来确定。

最后我们列出AddMate2的类型,里面的英文我认识的不多,大部分都是查字典和实验得到的所以列出来,你需要的时候不用实验和查字典了:

 swMateType_e

‘Specifies values for assembly-mate information.

swMateCOINCIDENT                 0       重合

swMateCONCENTRIC               1       同心

swMatePERPENDICULAR        2       垂直

swMatePARALLEL                      3       平行

swMateTANGENT                       4       相切

swMateDISTANCE                      5       距离

swMateANGLE                             6       角度

swMateUNKNOWN                     7       未知

swMateSYMMETRIC                  8       对称

swMateCAMFOLLOWER          9       凸轮

swMateGEAR                              10     齿轮

6.4         由于说到参考,顺便讨论一下配合参考:

下面的代码选择了零件的两个面,然后为此零件添加一个配合参考,先选择的面为配合参考的第一参考面。并且是同向、重合配合。第二个为反向、重合配合。

需要看Part.FeatureManager.InsertMateReference函数。第一个参数是配合参考的名称,后面三个为一组定义一个参考。第一个为选择的实体entity,然后是配合类型(整数索引),正反向(整数索引)。

Dim swApp As SldWorks.SldWorks
Dim Part As SldWorks.ModelDoc2
Dim selmgr As SldWorks.SelectionMgr
Dim Feature As SldWorks.Feature
Dim facefst As SldWorks.face2
Dim facesed As SldWorks.face2
Dim facefstent As SldWorks.Entity
Dim facesedent As SldWorks.Entity
Dim tempfeat As Object

Sub addcleatmateref()
Set swApp = Application.SldWorks
Set Part = swApp.ActiveDoc
Set selmgr = Part.SelectionManager

Set tempfeat = selmgr.GetSelectedObject5(1)
If tempfeat.GetType = 2 Then
Set facefst = tempfeat
Set facefstent = facefst
Else
MsgBox "请选择平面"
End If
Set tempfeat = selmgr.GetSelectedObject5(2)
If tempfeat.GetType = 2 Then
Set facesed = tempfeat
Set facesedent = facesed
Else
MsgBox "请选择平面"
End If
Set Feature = Part.FeatureManager.InsertMateReference("配合参考1", facefstent, 2, 1, facesedent, 2, 2, Nothing, 0, 0)
End Sub

在实际的代码中,我们经常需要遍历一个装配体,下面是遍历装配体的方法:

下面的例子完全照API帮助中搬来的,它用来显示当前装配体的所有零部件。程序使用了一个简单的递归方法遍历了装配体。

This example shows how to make all assembly components visible.

'---------------------------------------

' Preconditions: An assembly document is open.

' Postconditions: Any hidden assembly components are made visible.

'---------------------------------------

Option Explicit

Public Enum swComponentVisibilityState_e     ‘装配体中组件的显示状态:0隐藏 1显示

swComponentHidden = 0

swComponentVisible = 1

End Enum

Sub TraverseComponent _

( _

swComp As SldWorks.Component2, _

nLevel As Long _

)                                                             ‘递归函数

Dim vChildCompArr               As Variant

Dim vChildComp                  As Variant

Dim swChildComp                 As SldWorks.Component2

Dim swCompConfig                As SldWorks.Configuration    ‘组件配置

Dim sPadStr                     As String

Dim i                           As Long

For i = 0 To nLevel – 1                                                      ‘这个循环没什么实际作用,打印父子装配体的缩进

sPadStr = sPadStr + "  "

Next i

vChildCompArr = swComp.GetChildren                                              ‘得到装配体的子组件

For Each vChildComp In vChildCompArr                                   ‘对于每个子组件

Set swChildComp = vChildComp

Debug.Print sPadStr & swChildComp.Name2 & " <" & swChildComp.ReferencedConfiguration & ">"

If swComponentHidden = swChildComp.Visible Then      ‘如果他的状态是隐藏则给它显示

swChildComp.Visible = swComponentVisible

End If

TraverseComponent swChildComp, nLevel + 1                            ‘如果他也有子组件,进入递归

Next

End Sub

Sub main()

Dim swApp                       As SldWorks.SldWorks

Dim swModel                     As SldWorks.ModelDoc2

Dim swAssy                      As SldWorks.AssemblyDoc

Dim swConf                      As SldWorks.Configuration

Dim swRootComp                  As SldWorks.Component2

Dim bRet                        As Boolean

Set swApp = Application.SldWorks

Set swModel = swApp.ActiveDoc

Set swConf = swModel.GetActiveConfiguration

Set swRootComp = swConf.GetRootComponent

Debug.Print "File = " & swModel.GetPathName

TraverseComponent swRootComp, 1

End Sub

装配体的话题到此为止,回顾一下我们学习了怎样在装配体中插入组件,怎样添加一个配合,怎么样访问装配体中的每一个子组件,内容够丰富了。下面我们来讨论最后一个主题:工程图。

第7章       工程图

7.1         综述:

工程图中包含了两个独立的对象,图纸sheet和视图view。但是对使用者来说很容易将图纸对象架设在视图对象上方。因为给人直观感觉是一个工程图可能有多个sheet,每个sheet中又可以有多个view。

其实从右边的对象模型中可以看到,真正的内容还都在view对象中,而view并不受sheet限制,它们在DrawingDoc中是平行的。

我们主要通过两个话题来讨论工程图:一个是注释的问题,一个是生成图纸。

7.2        注释的话题:<script language="JavaScript" type="text/javascript"> document.title="Solidworks二次开发—12—工程图的note - "+document.title </script>

这里讨论的注释是工程图图纸格式的注释,即工程图中的说明部分的控制。下面的程序读取当前图纸的每一个note,并在debug中打印结果。

Option Explicit

Dim swname As String

Dim swtext As String

Sub main()

Dim swApp                       As SldWorks.SldWorks

Dim swModel                     As SldWorks.ModelDoc2

Dim swDraw                      As SldWorks.DrawingDoc      ‘工程图对象

Dim swView                      As SldWorks.View                       ‘视图对象

Dim swNote                      As SldWorks.note                        ‘注释对象

Dim swAnn                       As SldWorks.Annotation            ‘标注对象

Dim bRet                         As Boolean

Set swApp = CreateObject("SldWorks.Application")

Set swModel = swApp.ActiveDoc

Set swDraw = swModel

Set swView = swDraw.GetFirstView                      ‘得到第一个视图

Set swNote = swView.GetFirstNote                                ‘得到第一个注释

swModel.ClearSelection2 (True)

Debug.Print "File = " & swModel.GetPathName

Do While Not swNote Is Nothing

Set swAnn = swNote.GetAnnotation                      ‘得到标注

bRet = swAnn.Select2(True, 0)                               ‘高亮选中

Debug.Assert bRet

swname = swNote.GetName

swtext = swNote.GetText

Debug.Print "  名称:" & swNote.GetName; " *** 文本: " & swNote.GetText

Set swNote = swNote.GetNext          ‘下一个注释

Loop

End Sub

上面的程序只是对工程图的所有标注进行了一个遍历,打印出注释的名称和内容。我们能够了解一下drawdoc对象各个子对象的访问方法就可以了。

7.3         生成图纸的话题:并讨论如何解决实际问题

最后这个话题比较大,顺便我们也将讨论针对一个问题如何规划,何如进行模块化编程的问题。下面代码是工程图助手中的“生成工程图”模块内容。它按照我们的图纸存储规范,把一个产品的每个装配体都生成一个solidworks的工程图文件。

面对一个问题,我们在试图使用VBA来改善工作的时候,可以参考下面的思路来进行,当然,这也只是个人的一些经验之说,并不是最好的工作方式:

首先我们需要了解实际工作情况,发现问题所在:工艺人员在试图提高solidworks工作效率的时候提到了使用SolidWorks Task Scheduler来自动出图纸的方法(具体方法就不讨论了)。大家经过一段时间的使用后发现,使用SolidWorks Task Scheduler有一定的局限性,需要问题在于,它将每个solidworks文件—包括零件、装配体—都生成了一个工程图文件。然而这样得到的结果便是一个零部件稍多的产品,将会自动生成很多的工程图文件,不便于管理。我们的习惯是,按照装配体来出图纸,将一个装配体中的零部件在一个工程图文件中表示。这样表达清楚而且便于管理。恩,这就是现实的问题所在。

然后,我们要考虑可行性:思考了SolidWorks Task Scheduler的实现,发现使用VBA在技术方面可以实现此类功能,并且有一定的规律可以遵守而不需要太多的人为判断就可以达到要求。这里插一句,在使用SolidWorks Task Scheduler时我发现了一个选项:备份任务文件,而这个任务文件上所记录的正式一段使用VBA写的宏代码。

接下来,需要现场调研确定需求目标:在了解了solidworks使用相应的规范和工艺员在实际工作中的要求后我们对问题目标有了一个比较明确的概念。我们要做的项目需要完成这样的工作:它针对一个产品中的每个装配体生成一个工作图文件,每本工程图文件中需要一张装配体的三视图和其每个子零件的三视图图纸。并将它们存储在和“图纸”文件夹(存放solidworks模型)同级的目录下的“工程图”文件夹里。

做好了准备工作,我们可以开始写程序了。将需求的内容转化成软件问题描述,并描述其大致方法:1、得到产品文件的每个装配体:我们可以通过文件夹中文件的遍历,按照后缀名“.sldasm”来得到一个目录下所有的装配体;也可以通过遍历一个产品总装配体的组件来得到每一个子装配体模型。实际的编码中我们选择了后者,因为它虽然给编写代码结构带来了复杂度,但是正确性和稳定性都要好过前者。装配体的组件是一个树型结构,使用递归式是比较灵活的方法,前面章节也已经介绍过。2、生成工程图并插入零件的模型三视图:SolidWorks Task Scheduler使用预定义的模型视图来完成自动生成的功能,但是,一旦需要在原有的图纸上插入新图纸时,就不能够继承图纸模版的预定义试图了。所以需要使用CreateDrawViewFromModelView2和CreateUnfoldedViewAt3来替代。

一切准备完毕后就可以设计程序框架进行编码了:我们这里定义了三个过程,main、traverseasm、createdraw。它们的定义和完成的作用如下:

Main():模块主函数没有参数和返回值,它得到当前打开装配体的路径、设置“工程图文件夹路径”、运行traverseasm过程。

Traverseasm(filepath as string):此过程接受一个装配体的存储路径字符串参数,完成装配体的递归遍历工作,得到每一个装配体,并让每一个装配体都作为参数运行createdraw过程。

Createdraw(filepath as string): 此过程接受一个装配体的存储路径字符串参数,生成此装配体的工程图。

'/************************************************************

'drawcreator : 根据装配体生成工程图

'zjt   2005-10-12

'

'main:

'   get opened asm model infomation:

'       filepathname

'       drawpathname

'       make dir path is drawpathname

'       call  traverseasm with argument filepathname

'

'traverseasm:

'       for itself call createdraw with argument itself

'       traverse the asm model component

'       for each sub asm model:

'           call traverseasm

'

'createdraw:

'       create a drawdoc with given drawtemplate

'       insert each sub part model component a sheet

'

'************************************************************/

Option Explicit

'定义部分:

Dim swapp           As SldWorks.SldWorks

Dim drawpathname    As String

Dim file            As String

Dim nErrors         As Long

Dim nWarnings       As Long

Dim statofanno      As Boolean

Dim pos As Integer

'/***********************************************************

'sub main goes here:

'***********************************************************/

Sub main()

On Error Resume Next

Dim actmodel As SldWorks.ModelDoc2

Dim yesorno  As VbMsgBoxResult

Set swapp = CreateObject("SldWorks.Application")

Set actmodel = swapp.ActiveDoc

If actmodel Is Nothing Then

MsgBox "请先打开装配体"

End If

'得到装配体文件路径

file = actmodel.GetPathName

'得到工程图保存路径

drawpathname = Left(file, InStrRev(file, "/") - 1)

drawpathname = Left(drawpathname, InStrRev(drawpathname, "/"))

drawpathname = drawpathname + "工程图/"

'创建文件夹

MkDir (drawpathname)

'调试信息 :

''debug.print drawpathname

''debug.print file

'should i set all object nothing ?

Set actmodel = Nothing

Set swapp = Nothing

yesorno = MsgBox("需要自动在零件工程图中插入模型项目么?", vbOKCancel, "提示")

If yesorno = vbOK Then

statofanno = True

Else

statofanno = False

End If

swapp.Visible = False

'调用函数遍历装配体组件

traverseasm file

swapp.Visible = True

End Sub

'/**************************************************

'sub traverseasm goes here :

''**************************************************/

Sub traverseasm(filepath As String)

Dim swmodel2 As SldWorks.ModelDoc2

Dim swconf2 As SldWorks.Configuration

Dim swrootcomp2 As SldWorks.Component2

Dim swchildcomp2 As SldWorks.Component2

Dim vchildcomp2 As Variant

Dim filetype2 As String

Dim n As Long

Set swapp = CreateObject("SldWorks.Application")

If swapp Is Nothing Then

MsgBox "创建SW对象失败"

Exit Sub

End If

Set swmodel2 = swapp.OpenDoc6(filepath, 2, 0, "", nErrors, nWarnings)    'file open good

If swmodel2 Is Nothing Then

MsgBox "加载装配体失败"

Exit Sub

End If

Set swconf2 = swmodel2.GetActiveConfiguration 'need to change swmodel to traverse

Set swrootcomp2 = swconf2.GetRootComponent

vchildcomp2 = swrootcomp2.GetChildren

For n = 0 To UBound(vchildcomp2)

Set swchildcomp2 = vchildcomp2(n)

filetype2 = UCase(Right(swchildcomp2.GetPathName, 6))

If filetype2 = "SLDASM" Then

traverseasm swchildcomp2.GetPathName

End If

Next

''debug.print swmodel2.GetPathName

If Not Mid(swmodel2.GetTitle, 1, 2) = "镜向" Then

createdraw swmodel2.GetPathName

End If

End Sub

'/**************************************************

'sub createdraw goes here :

'**************************************************/

Sub createdraw(filepath As String)

Dim swmodel     As SldWorks.ModelDoc2

Dim swsave      As SldWorks.ModelDoc2

Dim swdraw      As SldWorks.DrawingDoc

Dim swchildcomp As SldWorks.Component2

Dim swchildcmp2 As SldWorks.Component2

Dim swconf      As SldWorks.Configuration

Dim swrootcomp  As SldWorks.Component2

Dim cursheet    As SldWorks.Sheet

Dim swview      As SldWorks.View

Dim vchildcomp  As Variant

Dim sheetarr    As String

Dim spadstr     As String

Dim asmfile     As String

Dim drawfile    As String

Dim drawdir     As String

Dim drawtemp    As String

Dim destring    As String

Dim tmpstring   As String

Dim stmpstr     As String

Dim filetype    As String

Dim sheetname   As String

Dim viewname    As String

Dim sfilename   As String

Dim file        As String

Dim i           As Long

Dim isok        As Boolean

Dim wgood       As Integer

asmfile = filepath

drawdir = drawpathname

'for easy to use i specified a template file

drawtemp = swapp.GetExecutablePath & "/lang/chinese-simplified/Tutorial/auto.DRWDOT"

sheetarr = "ardenmakeastupidwaybutrunsok"

Set swapp = CreateObject("SldWorks.Application")

If swapp Is Nothing Then

MsgBox "创建SW对象失败"

Exit Sub

End If

Set swmodel = swapp.OpenDoc6(asmfile, 2, 0, "", nErrors, nWarnings)

If swmodel Is Nothing Then

MsgBox "打开装配体失败"

Exit Sub

End If

swmodel.EditRebuild3

'创建drawdoc文档

Set swdraw = swapp.NewDocument(drawtemp, 2, 0.2, 0.4)

If swdraw Is Nothing Then

MsgBox "创建工程图失败"

Exit Sub

End If

Set cursheet = swdraw.GetCurrentSheet

'插入模型到预定义视图

isok = swdraw.InsertModelInPredefinedView(asmfile)

If isok = False Then

MsgBox "插入装配体三视图失败"

End If

destring = swmodel.GetTitle

tmpstring = Left(destring, InStrRev(destring, ".") - 1)

If InStrRev(tmpstring, " ", -1, vbTextCompare) <= 0 Then

destring = tmpstring

' notice : need to write more to modify it

Else

destring = Replace(tmpstring, Left(tmpstring, InStrRev(tmpstring, " ") - 1), "")

End If

'sheet名称设定规则:模型名称(不包括物料编码)+三视图

cursheet.SetName (destring + "三视图")

Set swview = swdraw.GetFirstView

swview.UseSheetScale = True '设置为图纸比例 does it works right?

''debug.print swview.UseSheetScale

'''debug.print "the sheet name is : " & destring + "三视图"

'save draw file but do not open it

wgood = swmodel.SaveAs2(drawdir + tmpstring + ".SLDDRW", 0, False, True)

'<<<-------------------------------

'''debug.print "save asm draw file state:" & wgood

'''debug.print drawdir & "/" & tmpstring & ".SLDDRW"

If wgood = 0 Then

MsgBox "保存三视图失败"

End If

'-------------------------------->>>

'怎样才能不覆盖保存?

'then traverse all part file next level insert sheet on this draw

'已经将装配体的三视图插入draw文件了

'要遍历装配体:part部分

'swapp.ActivateDoc2 swmodel.GetPathName, True, nErrors

Set swconf = swmodel.GetActiveConfiguration 'need to change swmodel to traverse

'''debug.print "activeconfiguration is :" & swconf.Name

Set swrootcomp = swconf.GetRootComponent

'''debug.print "rootcompoent is :" & swrootcomp.Name

vchildcomp = swrootcomp.GetChildren

'--------开始对装配体下一层组建进行遍历,忽略子装配体,只将本身和子零件出图-------

'--------------------------------------------------------------------------

'------------------------------begin loop-----------------------

'----------------------------

For i = 0 To UBound(vchildcomp)

'''debug.print "enter loop 0 to " & UBound(vchildcomp)

Set swchildcomp = vchildcomp(i)

'-------------------------------------

If i < UBound(vchildcomp) Then

Set swchildcmp2 = vchildcomp(i + 1)

Else

Set swchildcmp2 = vchildcomp(0)

End If

'--------------------------------------

'''debug.print "sub comp " & i & "  name is : " & swchildcomp.Name

filetype = UCase(Right(swchildcomp.GetPathName, 6))

If filetype = "SLDPRT" Then                                   ‘ 如果是零件,插入图纸

If swdraw Is Nothing Then

'''debug.print "swdraw is nothing"

Else

'''debug.print "swdraw has  :" & swdraw.GetSheetCount & "sheets"

End If

'//---------------- 得到图纸名称----------------------

stmpstr = swchildcomp.GetPathName

''debug.print "1: " & stmpstr

stmpstr = Left(stmpstr, InStrRev(stmpstr, ".") - 1)

''debug.print "2: " & stmpstr

stmpstr = Right(stmpstr, Len(stmpstr) - InStrRev(stmpstr, "/"))

''debug.print "3: " & stmpstr

If InStr(stmpstr, " ") <= 0 Then

sheetname = LTrim(stmpstr)

Else

sheetname = LTrim(Replace(stmpstr, Left(stmpstr, InStrRev(stmpstr, " ") - 1), ""))

End If

'---------------- 得到图纸名称----------------------//

Debug.Print "sheetname:" & sheetname

Debug.Print "sheetarr" & sheetarr

' 忽略镜像零部件

If Not Mid(sheetname, 1, 2) = "镜向" Then

'//-------------------------------------如果重复跳过---------------------------------------------------

If Not swchildcomp.GetPathName = swchildcmp2.GetPathName Then

'//------------------------也是判断有没有这个表------------------

If InStr(1, sheetarr, sheetname, vbTextCompare) = 0 Then

'            If Not InStrRev(1, sheetarr, sheetname, vbTextCompare) = 0 Then

swdraw.NewSheet3 sheetname, 12, 12, 1#, 10#, True, "美克A4横.slddrt", 2, 2, ""

sheetarr = sheetarr & sheetname

Debug.Print "add" & sheetarr

swdraw.ActivateSheet sheetname

Set cursheet = swdraw.GetCurrentSheet

cursheet.SheetFormatVisible = True

'cursheet.SetTemplateName drawtemp

'''debug.print "part fullname is :" & swchildcomp.GetPathName

'swdraw.InsertModelInPredefinedView swchildcomp.GetPathName

'//----------------------------------------- 创建三视图-----------------------------

Set swview = swdraw.CreateDrawViewFromModelView2(swchildcomp.GetPathName, "*前视", 0.07954434782609, 0.09376565217391, 0)

'''debug.print "viewname is :" & swview.Name

viewname = swview.Name

'''debug.print "swview name is :" & viewname

swdraw.Extension.SelectByID2 viewname, "DRAWINGVIEW", 0, 0, 0, False, 0, Nothing, 0

swdraw.ActivateView viewname

Set swview = swdraw.CreateUnfoldedViewAt3(0.2224917391304, 0.09376565217391, 0, 0) '上视

swdraw.ClearSelection2 True

swdraw.Extension.SelectByID2 viewname, "DRAWINGVIEW", 0, 0, 0, False, 0, Nothing, 0

Set swview = swdraw.CreateUnfoldedViewAt3(0.07954434782609, 0.1534239130435, 0, 0) '右视

swdraw.ClearSelection2 True

swdraw.Extension.SelectByID2 viewname, "DRAWINGVIEW", 0, 0, 0, False, 0, Nothing, 0

Set swview = swdraw.CreateUnfoldedViewAt3(0.1636082608696, 0.1778295652174, 0, 0)  '斜视

swdraw.ClearSelection2 True

'swdraw.ActivateView viewname

'swdraw.Extension.SelectByID2 swview.GetName2, "DRAWINGVIEW", 0, 0, 0, False, 0, Nothing, 0

If Not swview Is Nothing Then

''debug.print "swview name : " & swview.GetName2

swview.SetDisplayMode3 False, 3, False, True  ' 隐藏线可见

''debug.print "scale : " & swview.ScaleRatio(1)

Else

''debug.print "swview is nothing "

End If

If statofanno = True Then

'insert annotation

swdraw.InsertModelAnnotations3 0, 1605656, True, True, False, False '斜视图为带边线上色

Else

'donothing

End If

'------------------------------------------ 创建三视图------------------------//

End If

'//------------------也是判断有没有这个表------------------

End If

'//-----------------------------------------如果重复跳过-----------------------------------------

End If

End If

swdraw.ForceRebuild3 False

Next i

'------------------------------------------

'---------------------end loop--------------------

'----------------------------------------------------------

'------------------------------------------------------------------

swdraw.ForceRebuild3 False

Set swsave = swdraw

'isok = swsave.SaveAs4(swsave.GetTitle, 0, 0, nErrors, nWarnings)

sfilename = drawdir + tmpstring + ".SLDDRW"

isok = swsave.SaveAs2(sfilename, 0, False, True)

'''debug.print "save " & sfilename & " state : " & isok

If isok = False Then

''debug.print "保存" & sfilename & "失败"

End If

swapp.CloseDoc swsave.GetTitle

Set swdraw = Nothing

End Sub

第8章       总结:

文档所讨论的问题只是发挥了solidworks API的很少功能,让计算机帮助我们提高工作质量和效率一直是我追求的目标,我很希望何大家一起研究此类问题,不积跬步无以至千里,从点点滴滴的尝试中,我们才有可能进行更加革命性的创造。驾驭好计算机这个工具,可以助你一臂之力。

使用VBA进行solidworks开发指南相关推荐

  1. AutoCAD 开发文档,AutoLISP 教程,.Net AutoCAD开发教程,VB AutoCAD开发教程,ObjectARX 开发指南,VBA AutoCAD开发教程,ActiveX 开发指南

    AutoCAD 开发文档, CAD开发者社区 - AutoCAD二次开发文档,CAD二次开发,CAD插件开发,中文CAD文档 - 中文CAD开发文档,CAD二次开发问题交流,优秀插件分享 AutoLI ...

  2. 《Access 2007开发指南(修订版)》一一1.5 什么是数据库对象

    本节书摘来自异步社区出版社<Access 2007开发指南(修订版)>一书中的第1章,第1.5节,作者: [美]Alison Balter,更多章节内容可以访问云栖社区"异步社区 ...

  3. c语言outl函数,Outlook MAPI开发指南

    0x00 前言 Outlook MAPI提供了一组访问Outlook的接口,用来扩展Outlook应用程序的开发,本文将会介绍Outlook MAPI的基本用法,开源一份Outlook MAPI的实现 ...

  4. solidworks开发语言php,Solidworks开发语言对比及分析

    很多初学Solidworks二次开发的同学,也许都会纠结使用何种语言进行二次开发.对于Solidworks二次开发的语言,官方有VBA,VB.NET,C#以及C++,四种语言. 用户通常会有如下疑问, ...

  5. 最全面的Unity游戏开发指南视频教程 第2卷

    最全面的Unity游戏开发指南视频教程 第2卷 流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小 ...

  6. Linux 汇编语言开发指南

    Linux 汇编语言开发指南 肖文鹏 (xiaowp@263.net), 北京理工大学计算机系硕士研究生 本文作者 肖文鹏是北京理工大学计算机系的一名硕士研究生,主要从事操作系统和分布式计算环境的研究 ...

  7. 《Python和Pygame游戏开发指南》——2.16 pygame.display.update()函数

    本节书摘来自异步社区<Python和Pygame游戏开发指南>一书中的第2章,第2.16节,作者[美]Al Sweigart(斯维加特), 李强 译,更多章节内容可以访问云栖社区" ...

  8. 400 多行代码!超详细 Rasa 中文聊天机器人开发指南 | 原力计划

    作者 | 无名之辈FTER 责编 | 夕颜 出品 | 程序人生(ID:coder_life) 本文翻译自Rasa官方文档,并融合了自己的理解和项目实战,同时对文档中涉及到的技术点进行了一定程度的扩展, ...

  9. Knockout应用开发指南 第六章:加载或保存JSON数据

    原文:Knockout应用开发指南 第六章:加载或保存JSON数据 加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地 ...

最新文章

  1. integer比较_Java整数缓存Integer.valueOf(127)==Integer.valueOf(127)为True
  2. wifi测试相关(iwconfig,WPA Supplicant用法)
  3. JavaWeb -- Struts2 ResultType细化, 国际化
  4. CentOS 命令大全 (转)
  5. db2 语句包括不必要的列表_DB2 SQL0956C 数据库堆中没有足够的处理空间可用来处理此语句...
  6. MATLAB遇到问题:错误使用eval,未定义与‘struct‘类型的输入参数相对应的函数‘workspacefunc‘
  7. react native ScrollView
  8. 10分钟10行代码开发APP(delphi 应用案例)
  9. python中类的定义和使用_在Python中定义和使用类
  10. IP地址冲突导致网络故障如何排查问题?
  11. 2013年计算机考试题库,2013年计算机三级数据库上机冲刺试题一及答案
  12. 史上最详细的hadoop安装教程
  13. 视频教程-Protel99se电路设计速成-智能硬件
  14. 美洽在线客服系统使用指南
  15. ST芯片涨价后,你是如何做的?
  16. 干货 | Elasticsearch 索引设计实战指南
  17. 电视盒子系统是安卓还是yunOS,三招快速弄清
  18. org.elasticsearch.common.util.concurrent.EsRejectedExecutionException 查询超时异常处理记录---一定要用单例模式
  19. 利用马尔可夫模型分析游戏装备强化概率问题
  20. 使用idea构建父子类springboot项目教程,并教你启动子项目(构建项目集合)

热门文章

  1. feign组件的功能与实现原理
  2. 修复TortoiseGit文件夹和文件图标不显示
  3. 验证码这样做,瞬间高出一个逼格
  4. 信息奥赛一本通1233 接水问题
  5. html怎么绘制晶圆图,Excel制作WaferMap图
  6. 图像透视映射(PerspectiveMappings)
  7. STM32F103关于输入捕获以及控制超声波测距模块的笔记(2)
  8. linux ip addr命令,linux – 理解“ip addr change”和“ip addr replace”命令
  9. 小波分析中的尺度函数与小波函数
  10. Java使用Junit测试控制台输出