Random Thoughts |
Very funny Scotty, now beam me down my clothes... -Kirk
|
言語 |
|
|
|
フォーラムニュース: 質問、相談カテゴリに「SolidWorks操作方法」に関するフォーラムを追加しました。(2003/11/27) |
いらっしゃい、 ゲストさん. まずはこちら→ ログイン または 登録. 2024/11/23 - 02:27:12 |
|
|
|
著者
|
トピック: アセンブリデザインツリーの整理 (閲覧数 13108 回) |
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
アセンブリデザインツリーの整理
« 投稿日: 2013/11/29 - 10:54:44 » |
|
------------------------------ Windows7 64Bit SolidWorks2011 SP5 x64 EnterprisePDM 2011 SP3.1 VisualBasic2008 Express Edition ------------------------------ お世話になっております、QWERです。
現在、アセンブリデザインツリーの構成部品(コンポーネント)を、 条件により所定のフォルダに振り分けるプログラムを作成しております。
ここで、「FeatureManager.MoveToFolder」を使用することで、構成部品の移動が可能かと考えておりますが上手く行きません。
以下、コードです。(アセンブリを開いて実行します。) -----Code-----
Dim SwModelDoc As SldWorks.ModelDoc2 Dim SwAssembly As SldWorks.AssemblyDoc Dim SwComponent As SldWorks.Component2 Dim Components As Object Dim SingleComponent As Object
Dim SwSelMgr As SldWorks.SelectionMgr Dim SwFeatMgr As SldWorks.FeatureManager Dim SwFeature As SldWorks.Feature
Dim Append As Boolean
Try
'ドキュメントを取得 SwModelDoc = SwApp.ActiveDoc
If System.IO.Path.GetExtension(SwModelDoc.GetPathName).ToLower <> ".sldasm" Then MessageBox.Show("Non Assy", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If
SwAssembly = SwModelDoc SwSelMgr = SwModelDoc.SelectionManager
'-----既存フォルダの確認 Dim FlgAssyFolder As Boolean = False Dim FlgPartFolder As Boolean = False
SwFeature = SwModelDoc.FirstFeature While Not SwFeature Is Nothing If SwFeature.GetTypeName2 = "FtrFolder" Then Dim Name As String = SwFeature.Name Select Case Name Case "Assy" : FlgAssyFolder = True Case "Part" : FlgPartFolder = True End Select End If SwFeature = SwFeature.GetNextFeature() End While
'コンポーネントの取得(トップレベルのみ) Components = SwAssembly.GetComponents(True)
'-----フォルダの作成 SwFeatMgr = SwModelDoc.FeatureManager 'コンポーネントを1つ選択(フォルダ作成のため) SwComponent = Components(0) SwComponent.Select(Append) If FlgAssyFolder = False Then SwFeature = SwFeatMgr.InsertFeatureTreeFolder2(SwConst.swFeatureTreeFolderType_e.swFeatureTreeFolder_EmptyBefore) If Not SwFeature Is Nothing Then SwFeature.Name = "Assy" End If End If If FlgPartFolder = False Then SwFeature = SwFeatMgr.InsertFeatureTreeFolder2(SwConst.swFeatureTreeFolderType_e.swFeatureTreeFolder_EmptyBefore) If Not SwFeature Is Nothing Then SwFeature.Name = "Part" End If End If
'構成部品の振り分け For Each SingleComponent In Components SwComponent = SingleComponent Dim FilePath As String = SwComponent.GetPathName() Dim Name As String = SwComponent.Name2
If System.IO.Path.GetExtension(FilePath).ToLower = ".sldasm" Then 'Assyフォルダに振り分け SwComponent.Select(Append) SwFeatMgr = SwComponent.GetModelDoc2 SwFeatMgr.MoveToFolder("Assy", Name, True) ElseIf System.IO.Path.GetExtension(FilePath).ToLower = ".sldprt" Then 'Partフォルダに振り分け SwComponent.Select(Append) SwFeatMgr = SwComponent.GetModelDoc2 SwFeatMgr.MoveToFolder("Part", Name, True) End If Next
SwModelDoc.ClearSelection2(True)
Catch ex As Exception MessageBox.Show(ex.Message) End Try
-----Code-----
上記のコードでは、拡張子によってAssyとPartを分類しているだけですが、もっと細かな分類を行う予定です。 なお、対象はトップレベルの構成部品とし、サブフォルダーを作成する予定はありません。
所定のフォルダに構成部品を移動する方法をご存じの方がいらっしゃいましたら、ご教示願います。
P.S. SwApplicationのAPIを組むのは久々なので、その他、問題のある箇所や、 プログラムの構成に関してもご指摘頂けると幸いです(・∀・;)
よろしくお願い致します。
|
|
|
|
hisa
カタマリの王様!?
オフライン
投稿: 507
PANDA-Z!!
|
|
Re:アセンブリデザインツリーの整理
« 返信 #1 投稿日: 2013/11/29 - 13:03:21 » |
|
QWERさん、こんにちは
MoveToFolderは、ソリッドボディのフォルダーにしか使えないメソッドの様です
構成部品をフォルダーに移動する場合は、AssemblyDoc::ReorderComponents を使うことで実現できますよ
|
|
|
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
Re:アセンブリデザインツリーの整理
« 返信 #2 投稿日: 2013/12/02 - 10:08:53 » |
|
>hisaさん
お世話になっております、QWERです。 レスありがとうございます!
>MoveToFolderは、ソリッドボディのフォルダーにしか使えないメソッドの様です ...そうだったのですか(・_・;
>構成部品をフォルダーに移動する場合は、AssemblyDoc::ReorderComponents を使うことで実現できますよ ご教示頂き有難うございます! 他の業務が入ってしまった為、しばらくテスト出来ませんが、取り急ぎお礼まで申し上げます。 テストでき次第、また報告致します!
|
|
|
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
Re:アセンブリデザインツリーの整理
« 返信 #3 投稿日: 2013/12/02 - 16:59:05 » |
|
>hisaさん
すみません... API Helpにて「AssemblyDoc::ReorderComponents」を調べてみたのですが、引数に指定すべきObject型の値の取得方法が理解できません(;_;) もし宜しければ「AssemblyDoc::ReorderComponents」の使い方をご教示頂けると幸いです。
よろしくお願い致します。
|
|
|
|
Makoron
カタマリの王様!?
オフライン
投稿: 1277
SW2011SP5.0
|
|
Re:アセンブリデザインツリーの整理
« 返信 #4 投稿日: 2013/12/02 - 18:01:50 » |
|
とりあえず、ソリッドワークスジャパンが公開していたSW2008APIヘルプ日本語版から抜粋してみました! これでわかりますか? -------------- Retval = AssemblyDoc.ReorderComponents ( Source, Target, Where)
入力: (VARIANT) Source 移動する構成部品の SafeArray型のVARIANTを返します。 入力: (LPDISPATCH) Target ターゲット構成部品あるいは構成部品の移動先のフォルダーへのディスパッチポインタ 入力: (long) Where swReorderComponentsWhere_eに定義されるように、構成部品の移動先 出力: (VARIANT_BOOL) Retval 構成部品が移動されたならばTRUE、そうでなければFALSE -------------------
|
|
|
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
Re:アセンブリデザインツリーの整理
« 返信 #5 投稿日: 2013/12/03 - 10:28:54 » |
|
>Makaronさん レス有難うございます! API Helpに載っているサンプルコードを参考に、改造を行っておりますが、なかなか上手く行きません。 「DispatchWrapperという型(?)に変換しなければならない」というのはなんとなく分かったのですが... エラーは出ませんが、フォルダに移動できません。
以下、作成中のコードです。
-----Code-----
Sub Test()
Dim SwModelDoc As SldWorks.ModelDoc2 Dim SwAssembly As SldWorks.AssemblyDoc Dim SwComponent As SldWorks.Component2 Dim Components As Object Dim SingleComponent As Object
Dim SwSelMgr As SldWorks.SelectionMgr Dim SwFeatMgr As SldWorks.FeatureManager Dim SwFeature As SldWorks.Feature
Dim Append As Boolean
Try
'ドキュメントを取得 SwModelDoc = SwApp.ActiveDoc
If System.IO.Path.GetExtension(SwModelDoc.GetPathName).ToLower <> ".sldasm" Then MessageBox.Show("Not Assy", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If
SwAssembly = SwModelDoc SwSelMgr = SwAssembly.SelectionManager
'-----既存フォルダの確認 Dim FlgAssyFolder As Boolean = False Dim FlgPartFolder As Boolean = False
SwFeature = SwModelDoc.FirstFeature While Not SwFeature Is Nothing If SwFeature.GetTypeName2 = "FtrFolder" Then Dim Name As String = SwFeature.Name Select Case Name Case "Assy" : FlgAssyFolder = True Case "Part" : FlgPartFolder = True End Select End If SwFeature = SwFeature.GetNextFeature() End While
'コンポーネントの取得(トップレベルのみ) Components = SwAssembly.GetComponents(True)
'-----フォルダの作成 SwFeatMgr = SwModelDoc.FeatureManager 'コンポーネントを1つ選択(フォルダ作成のため) SwComponent = Components(0) SwComponent.Select(Append) Dim SwAssyFolder As SldWorks.Feature 'Assy格納用フォルダ Dim SwPartFolder As SldWorks.Feature 'Part格納用フォルダ If FlgAssyFolder = False Then SwAssyFolder = SwFeatMgr.InsertFeatureTreeFolder2(SwConst.swFeatureTreeFolderType_e.swFeatureTreeFolder_EmptyBefore) If Not SwAssyFolder Is Nothing Then SwAssyFolder.Name = "Assy" End If End If If FlgPartFolder = False Then SwPartFolder = SwFeatMgr.InsertFeatureTreeFolder2(SwConst.swFeatureTreeFolderType_e.swFeatureTreeFolder_EmptyBefore) If Not SwPartFolder Is Nothing Then SwPartFolder.Name = "Part" End If End If
'構成部品の振り分け Dim CompsToMove As System.Runtime.InteropServices.DispatchWrapper() For Each SingleComponent In Components SwComponent = SingleComponent Dim FilePath As String = SwComponent.GetPathName() Dim Name As String = SwComponent.Name2 If System.IO.Path.GetExtension(FilePath).ToLower = ".sldasm" Then 'Assyフォルダに振り分け SwComponent.Select(Append) CompsToMove = ObjectArrayToDispatchWrapperArray(SwComponent) SwAssembly.ReorderComponents(CompsToMove, SwAssyFolder, SwConst.swReorderComponentsWhere_e.swReorderComponents_LastInFolder) ElseIf System.IO.Path.GetExtension(FilePath).ToLower = ".sldprt" Then 'Partフォルダに振り分け SwComponent.Select(Append) CompsToMove = ObjectArrayToDispatchWrapperArray(SwComponent) SwAssembly.ReorderComponents(CompsToMove, SwPartFolder, SwConst.swReorderComponentsWhere_e.swReorderComponents_LastInFolder) End If Next
SwModelDoc.ClearSelection2(True)
Catch ex As Exception MessageBox.Show(ex.Message) End Try
End Sub
Public Function ObjectArrayToDispatchWrapperArray(ByVal mySwObject As Object) As System.Runtime.InteropServices.DispatchWrapper() 'SwObjectをDispatchWrapperに変換(?)
Dim ArraySize As Integer Dim ArrayIndex As Integer Dim DispatchWrapper As System.Runtime.InteropServices.DispatchWrapper() = New System.Runtime.InteropServices.DispatchWrapper(ArraySize) {}
For ArrayIndex = 0 To ArraySize DispatchWrapper(ArrayIndex) = New System.Runtime.InteropServices.DispatchWrapper(mySwObject) Next
Return DispatchWrapper
End Function
-----Code-----
アドバイス頂けると幸いです。m(u_u)m
|
|
|
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
Re:アセンブリデザインツリーの整理
« 返信 #6 投稿日: 2013/12/03 - 11:13:01 » |
|
すみません!恐らく解決しました!!
Dim SwAssyFolder As SldWorks.Feature 'Assy格納用フォルダ Dim SwPartFolder As SldWorks.Feature 'Part格納用フォルダ
を
Dim SwAssyFolder As SldWorks.Feature = SwModelDoc.FirstFeature 'Assy格納用フォルダ Dim SwPartFolder As SldWorks.Feature = SwModelDoc.FirstFeature 'Part格納用フォルダ
に修正したところ、フォルダに格納されました。 これから、詳細なデバックを行いますが、取り急ぎ報告まで。
その他、プログラム上の不備がありましたら、ご指摘頂けると幸いです。
|
|
|
|
hisa
カタマリの王様!?
オフライン
投稿: 507
PANDA-Z!!
|
|
Re:アセンブリデザインツリーの整理
« 返信 #7 投稿日: 2013/12/03 - 17:29:06 » |
|
QWERさん
.NETだと、SafeArray型のVariantが〜の場合にDispatchWrapperが〜といった情報がありましたね… しかし、ReorderComponentsに関して言えば、配列にしなくてもComponent2オブジェクト単体をSourceに渡しても正常に動作する気がしています。
試にVSTA(.NETマクロ)で以下コードを実行してみたところ、一応正常に動きました。
Code: Public Sub main()
Dim swModel As ModelDoc2 = Nothing Dim swSelMgr As SelectionMgr = Nothing Dim swAssy As AssemblyDoc = Nothing Dim swFeature As Feature = Nothing Dim swComp As Component2 = Nothing Dim boolstatus As Boolean = False
Try swModel = CType(swApp.ActiveDoc, ModelDoc2) If swModel.GetType = swDocumentTypes_e.swDocASSEMBLY Then swAssy = CType(swModel, AssemblyDoc) swSelMgr = CType(swModel.SelectionManager, SelectionMgr)
swFeature = swAssy.FeatureByName("Part") If swFeature Is Nothing Then boolstatus = swModel.Extension.SelectByID2("Part1-1@Assem1", "COMPONENT", 0, 0, 0, False, 0, Nothing, 0)
swFeature = swModel.FeatureManager.InsertFeatureTreeFolder2(swFeatureTreeFolderType_e.swFeatureTreeFolder_Containing) swFeature.Name = "Part" End If
boolstatus = swModel.Extension.SelectByID2("Part2-1@Assem1", "COMPONENT", 0, 0, 0, False, 0, Nothing, 0) swComp = swSelMgr.GetSelectedObjectsComponent3(1, 0) boolstatus = swAssy.ReorderComponents(swComp, swFeature, swReorderComponentsWhere_e.swReorderComponents_LastInFolder) End If Catch e As Exception MsgBox(e.Message) Finally swComp = Nothing swFeature = Nothing swAssy = Nothing swSelMgr = Nothing swModel = Nothing End Try
End Sub |
もしかしたら、.NETのお作法に反するかも知れませんが… ちなみに、既存のフォルダーがあるかチェックするには、FeatureByNameでフィーチャー名指定でフォルダの取得を試みて、結果がNothingであった場合にフォルダーを作成する方法があります
以上、ご参考まで。
|
|
|
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
Re:アセンブリデザインツリーの整理
« 返信 #8 投稿日: 2013/12/04 - 08:34:41 » |
|
>hisaさん
>.NETだと、SafeArray型のVariantが〜の場合にDispatchWrapperが〜といった情報がありましたね… >しかし、ReorderComponentsに関して言えば、配列にしなくてもComponent2オブジェクト単体をSourceに渡しても正常に動作する気がしています。
作成中のコードで試してみたところ、ご指摘の通り、DispatchWrapperを使用せずとも動作しました! アドバイス有難うございます!
>ちなみに、既存のフォルダーがあるかチェックするには、FeatureByNameでフィーチャー名指定でフォルダの取得を試みて、結果がNothingであった場合にフォルダーを作成する方法があります
プログラムとしては以下のような感じでしょうか? ちなみに、「既存フォルダがある場合に、そのフォルダフィーチャーを取得しておく」という処理を追加しております。(2回目の振り分けに対応)
-----Code-----
If SwAssembly.FeatureByName("Assy") IsNot Nothing Then FlgAssyFolder = True SwAssyFolder = SwAssembly.FeatureByName("Assy") End If
If SwAssembly.FeatureByName("Part") IsNot Nothing Then FlgPartFolder = True SwPartFolder = SwAssembly.FeatureByName("Part") End If
-----Code-----
もし、ご存知でしたらご教示頂きたのですが、 現在のプログラムだと、既にフォルダに格納されている構成部品も、フォルダ移動の対象となってしまいます。 フォルダに格納済みの構成部品は、移動の対象外にしたいのですが、これを判別する方法はありますでしょうか? (Helpにて、AssemblyDoc / Feature / Component2 / SelectionMgrあたりは確認したのですが、見当たりませんでした...)
よろしくお願い致します。
|
|
|
|
hisa
カタマリの王様!?
オフライン
投稿: 507
PANDA-Z!!
|
|
Re:アセンブリデザインツリーの整理
« 返信 #9 投稿日: 2013/12/05 - 13:34:30 » |
|
既存フォルダーのチェックは、先のサンプルコードの下記の部分を参考にしてみて下さい。
Code:swFeature = swAssy.FeatureByName("Part") If swFeature Is Nothing Then boolstatus = swModel.Extension.SelectByID2("Part1-1@Assem1", "COMPONENT", 0, 0, 0, False, 0, Nothing, 0) swFeature = swModel.FeatureManager.InsertFeatureTreeFolder2(swFeatureTreeFolderType_e.swFeatureTreeFolder_Containing) swFeature.Name = "Part" End If |
swFeature = swAssy.FeatureByName("Part")でフィーチャーが取得出来ていれば、"Part"フォルダーが存在する事に成ります。 swFeatureがNothingのままであれば、フォルダーが存在しないので、新しく作ります。 FeatureByNameを使えば、全フィーチャーからフォルダーを探す必要が無い上に、存在チェック用のフラグが必要なくなります。 "Part","Assy"以外のフォルダーの存在をチェックする必要がある場合は、全フィーチャーから探す必要がありますが…
あと、既にフォルダーに格納済みの構成部品の判別ですが、直接判別させる方法は無さそうですね… やるとしたら、予め全フィーチャーからフォルダーフィーチャーを取得し、Feature::GetSpecificFeature2でFeatureFolderオブジェクトを取得→FeatureFolder::GetFeaturesで格納されている構成部品を取得した上で、構成部品の名前をArrayListなどを用いて保管。 構成部品を移動する前に、保管した構成部品名に存在(Contains)するか調べて、無ければ移動するといった感じで、対応出来ると思います
|
|
|
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
Re:アセンブリデザインツリーの整理
« 返信 #10 投稿日: 2013/12/05 - 14:30:59 » |
|
>hisaさん
>既存フォルダーのチェックは、先のサンプルコードの下記の部分を参考にしてみて下さい。 コードを記載頂き、有難うございます! アドバイス頂いた内容を、プログラムに反映したいと思いますm(u_u)m
>あと、既にフォルダーに格納済みの構成部品の判別ですが、直接判別させる方法は無さそうですね… やるとしたら、予め全フィーチャーからフォルダーフィーチャーを取得し、Feature::GetSpecificFeature2でFeatureFolderオブジェクトを取得→FeatureFolder::GetFeaturesで格納されている構成部品を取得した上で、構成部品の名前をArrayListなどを用いて保管。 構成部品を移動する前に、保管した構成部品名に存在(Contains)するか調べて、無ければ移動するといった感じで、対応出来ると思います なるほど... 一発では判別できないのですね(・〜・;) 取得する方法のご教示、有難うございます! オプション機能として、用意しておきたい処理ですので、 実装を検討したいと思います。
ありがとうございました。
|
|
|
|
QWER
カタマリの王様!?
オフライン
投稿: 164
SolidWorks2011 SP5 x64
|
|
Re:アセンブリデザインツリーの整理
« 返信 #11 投稿日: 2013/12/06 - 10:21:25 » |
|
QWERです。
hisaさんにご教示頂いた「フォルダ格納済みフィーチャーの取得方法」をコード化しましたので、参考までに記載致します。 (ほぼ、「Get Contents of FeatureFolder」のサンプルコードそのままですが...(・∀・;))
-----Code-----
Sub SwAppGetStoredFeatures(ByVal mySwModelDoc As SldWorks.ModelDoc2, ByRef myStoredFeatures As ArrayList) '既存フォルダ内のフィーチャーを取得
Dim SwFeature As SldWorks.Feature Dim SwInFeature As SldWorks.Feature Dim Features As Object
myStoredFeatures = New ArrayList
Try
SwFeature = mySwModelDoc.FirstFeature While Not SwFeature Is Nothing If SwFeature.GetTypeName2 = "FtrFolder" Then Dim Name As String = SwFeature.Name Select Case Name Case "Assy" Case "Part" Case Else Dim SwFeatureFolder As SldWorks.FeatureFolder = SwFeature.GetSpecificFeature2 Features = SwFeatureFolder.GetFeatures For I As Integer = 0 To (SwFeatureFolder.GetFeatureCount - 1) SwInFeature = Features(I) myStoredFeatures.Add(SwInFeature.Name) Next End Select End If SwFeature = SwFeature.GetNextFeature() End While
Catch ex As Exception MessageBox.Show(ex.Message) End Finally SwFeature = Nothing End Try
End Sub
-----Code-----
振分け時は If StoredFeatures.Contains(ComponentName) = False Then <省略> End If
といった具合に判定しています。 (変数名の英語が変でも、大目に見て下さい(--;))
これで当初、目的としていた動作をさせることが出来ました。 アドバイス頂きました、hisaさん、Makaronさんには、改めてお礼申し上げますm(u_u)m ありがとうございました!
|
|
|
|
hiropon
Sr. メンバー
オフライン
投稿: 84
I'm a llama!
|
|
Re:アセンブリデザインツリーの整理
« 返信 #12 投稿日: 2015/01/25 - 12:06:23 » |
|
こんにちは hiroponです
こちらのご投稿と同じようなことをやろうとして困ったことに なっております
普通にコーディングする分には動作が確認できているのですが QWERさんのサンプルコーディングでいう
swAssy
を レイトバインディングすると 途端に動作不良になってしまいます。(具体的には dim swAssy as object とすると swAssy.ReorderComponents の返り値は 常にFalseとなりフォルダ にコンポーネントが移動してくれません)
これは SolidworksVBAでもExcelVBAやVB.NETでも 全て共通しているので 直接的な問題はやはり レイトバインディングが原因しているはずです
どうしても 社内のタイプラリのVerが異なることに対応するEXEを 作成するために レイトバインディングで コーディングする必要 がある(あると思っている )のですが どなたか 解決方法を ご存知のかた いらっしゃいませんでしょうか?
(なにやらググると 海外のフォーラムでも同じようなことを 言っている方がいらっしゃいますが投稿がその後途切れていて 解決には至っていないようです・・・ https://forum.solidworks.com/thread/18454)
社内のタイプライブラリが共通Verであれば アーリーバインディングでも良いとは思うのですが・・・・
|
|
|
|
|
|
|
|