APIに詳しい方、ご協力お願いします。

API素人です。
Web検索や会員の方のブログなど参考にAPI作成し完成まであと一歩のところで、
壁にぶつかり悩んでます。APIにお詳しい方のお力添え頂きたく。解答よろしくお願いします。

アクティブモデル(Partsファイル、Assemblyファイル)のファイル名を
プロパティユーザー定義情報の組合せにより自動生成し指定保存するマクロになります。

「Parts保存」、「AssemblyをPartsとして保存」、「Assemblyのみ保存」は、問題なく出来ますが、
「Assembly保存+参照Partsを保存」が外部参照がはずれる関係で求めていることが出来ません。

外部参照が外れる原因は、参照部品の名前をコードで操作変更したときに外れるようで、
リネームなども試しましたが、AssemblyのFutureManager上では、名前リネームされますが、
外部参照が外れる関係で部品を開くとリネーム前の名前で部品が開きます。(外部参照設定もコードで有効にしてますが駄目です)

当方が求めている内容としては、下記になります。

①「Assembly保存+参照Partsを保存」を選択
②参照Partsは、自動生成したフォルダにプレフィックス追加し保存
※数個ある部品が正常に保存される時と1個しか保存されない時がある(不安定)
③Assemblyファイルは選択したフォルダに保存(参照は外さない)
※まともに②部品が保存できても参照が外れAssembly選択フォルダに名前変更前の部品ファイルが保存される。

すでに数日悩んでますが、どうしたら正常実行可能か分かりません。。
どなたか解決頂けると非常に助かります。

悩んでいるコード抜粋します。

'Assemblyの構成部品を指定フォルダに保存
Dim swAssy As SldWorks.AssemblyDoc
Dim swConfig As SldWorks.Configuration
Dim swRootComp As SldWorks.Component
Dim Children As Variant
Dim swChild As SldWorks.Component
Dim ChildCount As Integer
Dim OldName As String
Dim NewName As String
Dim bOldSetting As Boolean
Dim bRet As Boolean
Dim i As Long
Dim i1 As Long

Set swApp = CreateObject("SldWorks.Application")
Set swAssy = swApp.ActiveDoc
Set swConfig = swAssy.GetActiveConfiguration
Set swRootComp = swConfig.GetRootComponent

bOldSetting = swApp.GetUserPreferenceToggle(swExtRefUpdateCompNames)
swApp.SetUserPreferenceToggle swExtRefUpdateCompNames, False

Children = swRootComp.GetChildren
ChildCount = UBound(Children)

i = 0
i1 = 1

For i = 0 To ChildCount

Set swChild = Children(i)

bRet = swChild.Select(False)

'現在の構成部品名を読み込み
OldName = swChild.Name2

'外部参照有効化
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swExtRefUpdateCompNames, True
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swReferenceOnlyEnvelopeComponentType, False
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swReferenceInContextOfTopLevelAssembly, False

'現在の構成部品名に設備NOを追加
NewName = rValOut1 & "_" & OldName

'構成部品名書込
swChild.Name2 = NewName

'Set Part = swApp.ActiveDoc
'boolstatus = Part.Extension.SelectByID2(rValOut, "COMPONENT", 0, 0, 0, False, 0, Nothing, 0)

'Rename
'longstatus = Part.Extension.RenameDocument(NewName)
'boolstatus = Part.ForceRebuild3(True)

'構成部品保存
NewName = fPath1 & "\" & NewName & ".SLDPRT"
fPath1 = NewName
boolstatus = swExt.SaveAs(fPath1, 0, Options, Nothing, errors, warnings)

i1 = i1 + 1

Next i

boolstatus = swAssy.ForceRebuild3(False)

'Assemblyを保存
fPath = BrowseFolder & "\" & rValOut & ".SLDASM"
boolstatus = swExt.SaveAs(fPath, 0, Options, Nothing, errors, warnings)

よろしくお願いします。

 

コメント

コメント表示順: リミット: オートロード:
  • 西田将也 1358 日前

    解決しました。

    勉強になりました。情報提供ありがとうございます!

  • 福谷勇時 1359 日前

    解決しました。

    アセンブリパーツをパーツとして保存する場合は、部品種類ごとに作成してあるテンプレートを選択できるように
    SW標準のテンプレート選択ウィンドウ表示し選択適用できるようにしました。

    参考コード抜粋:
    Dim Ptemp As String

    'SW標準のテンプレート選択ウィンドウ表示
    Ptemp = swApp.GetDocumentTemplate(swDocPART, "", 0, 0#, 0#)

    '部品デフォルトテンプレートを選択テンプレートに設定
    boolstatus = swApp.SetUserPreferenceStringValue(swUserPreferenceStringValue_e.swDefaultTemplatePart, Ptemp)

    【システムオプション】→【デフォルトテンプレート】の設定は、
    「ドキュメントのテンプレートを選択するようプロンプト表示」を選択にして下さい。
    image

  • 福谷勇時 1360 日前

    先日の投稿ですが、困っている内容が少し違ったので、再度投稿します。

    AssemblyファイルをPartsとして保存するときに「オプション」設定のデフォルトテンプレート(部品)が
    適用されますが、これを指定して適用したい方法が不明です。

    SW標準保存であれば、テンプレート選択ウィンドウが表示され選択可能なので、マクロ記録し試しましたが、
    NewDocumentで指定した部品ファイルは開くが、モデルが保存されないです。

    【SW標準保存記録コードAssemblyファイルをPartsとして保存】

    Dim swApp As Object

    Dim Part As Object
    Dim boolstatus As Boolean
    Dim longstatus As Long, longwarnings As Long

    Sub main()

    Set swApp = Application.SldWorks

    Set Part = swApp.ActiveDoc
    boolstatus = swApp.SetUserPreferenceIntegerValue(swUserPreferenceIntegerValue_e.swSaveAssemblyAsPartOptions, swSaveAsmAsPartOptions_e.swSaveAsmAsPart_AllComponents)

    ' New Document
    Dim swSheetWidth As Double
    swSheetWidth = 0
    Dim swSheetHeight As Double
    swSheetHeight = 0
    Set Part = swApp.NewDocument("指定テンプレート.prtdot", 0, swSheetWidth, swSheetHeight)
    Dim swPart As PartDoc
    Set swPart = Part
    swApp.ActivateDoc2 "Part1", False, longstatus

    "Part1"は、NewDocument実行した時点で、自動で割付され部品用指定テンプレートが開くが、
    SW終了するまで、NewDocument実行するたび番号積算されるので、何番になるか毎回番号が
    変わるので、実際は指定ができない。次番号が何番になるか確認し数字入れてはみましたが、
    NewDocumentで開いた部品ファイルに保存されません。

    Set Part = swApp.ActiveDoc
    Set Part = swApp.ActiveDoc
    Dim myModelView As Object
    Set myModelView = Part.ActiveView
    myModelView.FrameLeft = 0
    myModelView.FrameTop = 0
    Set myModelView = Part.ActiveView
    myModelView.FrameState = swWindowState_e.swWindowMaximized
    swApp.ActivateDoc2 "テスト用Assemblyモデル.SLDASM", False, longstatus
    Set Part = swApp.ActiveDoc

    ' Save As
    longstatus = Part.SaveAs3("ファイルパス.SLDPRT", 0, 2)
    End Sub

    何か方法あれば、教えて下さい。
    よろしくお願いします。

  • 福谷勇時 1362 日前

    また困りました。

    AssemblyファイルをPartsとして保存するときに作成済みの部品用プロパティテンプレートを
    適用したいのですが、方法がわかりません。今は勝手に違う部品用テンプレートが適用されてしまいます。

    保存時に指定プロパティテンプレートを適用する方法を教えて下さい。
    よろしくお願いします。

  • 福谷勇時 1363 日前

    追記します。

    swComp.Name2で取得した構成部品名には、必ず末尾に子NO,がついてしまいますが、
    不要につきInStrRevで末尾から”ー”位置取得しMidにて取得した文字位置から文字列取得、
    Replaceで末尾”ー”以降を置換え(削除)するようにしました。

      '現在の構成部品名を読み込み
      Dim OldName As String
      OldName = swComp.Name2
     
      'ファイル名の子NO確認
      Dim j As Long
      j = InStrRev(OldName, "-")
      Dim txt As String
      txt = Mid(OldName, j)
     
      '子番号置換(削除)
      OldName = Replace(OldName, txt, "")

    連休前に追加しておいた「一度保存したデータを違う設備で使い回す」は、多々あるので残しました。
      '取得した構成部品名の左(先頭)から4文字取得
      Dim ChangeName As String
      ChangeName = OldName
      ChangeName = Left(ChangeName, 4)
     
      '取得した構成部品の左4文字が数字だった場合実行
      If IsNumeric(ChangeName) = True Then
      OldName = Replace(OldName, ChangeName & "_", "")
      End If

    あとは、サブアセンブリがあった場合の処理を頑張ります!

  • 福谷勇時 1363 日前

    重箱の隅つつかれるとダダ漏れしますよ(笑)連休明けフル回転で煙もでてますが。。

    Instrやっと理解できました。今回のように詳しく教えて頂かないと、
    すぐパンクするので手取り足取りで説明お願いします(笑)

    たしかにこの方法であれば、Nextで回してるので、つけたいプレフィックス名で判断がつくことになります。

    If InStr(取得名, プレフィックス名) = 0 Then
    SaveAs実行

    実行結果はすばらしい完璧です!これなら子番号に左右されず判定できますね。

    AAAA<1>
    AAAA<2>
    ※取得順は選べない

    OldName:AAAA-1 or AAAA-2
    Prefix:0000_
    InStr (OldName, Prefix) = 0なので、SaveAs実行

    0000_AAAA-1<1>
    0000_AAAA-1<2>
    ※SaveAsで同名部品書換られる
    ※取得順は選べない

    OldName:0000_AAAA-1-1 or 0000_AAAA-1-2
    Prefix:0000_
    InStr (OldName, Prefix) = 1なので、SaveAs未実行

    すごくスッキリしました!
    あとは、アセンブリにサブアセンブリがあった場合どうするか・・・う~ん。。。Zzzzzz

  • 辻 直樹 1367 日前

    InStrでの判定、これもうまく伝わっていないようですね。というかマクロを実行したときの挙動を把握出来ていないのかも知れません。(.AddPrefix専用コード?<-その話ではないです、これは私も初耳(目?))

    STEP BY STEPで1行ずつ見ていくと解りますが、SaveAsの行を実行すると、保存と同時に複数ある同じ構成部品の名前は一斉に変更されます。

    なので”For Next”なり”Do While”なりの内側で次の名前を取得すると、同じ部品なら既に追加したい文字が付いていることになります。(だからここで再度同じ処理をすると文字の追加を繰り返してしまうのですね。)

    ここで、InStr(取得した名前,追加したい文字)で判定すると戻り値は、既に追加したい文字が含まれていれば何番目かの数字になるので1以上、含まれていなければ0となって区別できることになります。(0の時だけ保存処理を実行)

     

    保存の繰り返し処理の前に、現状の名前を取得して配列に入れておき、それに対して文字追加するという方法も可能ですが、この場合インスタンス数回、同名で上書き保存することなってわずらわしいですよね。

  • 西田将也 1367 日前

    ぼくも重箱の隅を・・

    PathName = Right(PathName, 1)

    11個以上同じファイルがあるとだぶりそうです。
    ちなみにぼくはファイル名を配列に入れて逐一チェックしようかとイメージしてたので
    それよりはマシですね(笑)

    【設備ハンディボックス用カールコード】設計に必要アルかナシかで言えば、ナシ

    見てわかりやすいのはいろいろ気づくきっかけになるので大事だと思いますよ!
    色もつけましょう!笑

  • 福谷勇時 1367 日前

    理解しましたよ。

    <>番号1のインスタンスを削除・・確かにレアケースではありますが、無くはないですね。
    さて、どうしましょう?少し考えます。明日からの3連休で記憶から消す可能性もありますが・・(笑)
    アップサンプル画像の【元データ構成】から、同名参照部品が何個あるか見分ける
    何かいい方法あれば、教えて頂けると助かります。

    プレフィックスに関しては、表現が悪かったですね。.AddPrefix専用コード?で接頭につけていないです。
    単純に取得した名前の先頭に4桁の設備NO,&"_"をつけただけで、同じ部品であっても
    設備ごとに名前を変えて保存してます。

    理由としては、社内で部品ファイル共有できてなく基本個人プレーで、ファイルは設備ごとのフォルダ作り
    共有ネットワークに保存してます。仮にAさんとBさんで同じアセンブリを使用しAさんが参照部品を変更した場合、
    Bさんの部品も変更されてしまうので、設備ごとに違う設備番号をファイル名や参照部品名の先頭につけることで、
    同じ部品であってもリンクしないようにしてます。なので、InStrでの判定はできないかと。。

    ただ、一度保存したデータを違う設備で使用する場合、既に先頭に違う設備NO,がついているので
    違う名前にしたいときに追加で違う設備NO,をつけることになり、0000_1111_・・・マクロ使うたび増えるので、
    取得部品名の左4文字取得し数字だった場合は、一度消して新たな設備NO,をつけるようにしておきました。
    ChangeName = swComp.Name2
    ChangeName = Left(ChangeName, 4)
    If IsNumeric(ChangeName) = True Then
    OldName = Replace(OldName, ChangeName & "_", "")
    End If

    今回作ったマクロは毎回このマクロで保存する訳ではなく、プロパティ組合せた決まった形式で
    ファイル名を自動でつけたい場合に使用することを大前提としているので、マクロで保存した後の
    変更や追加後の保存は基本的にSW標準の保存を使用します。じゃないと複雑になりすぎるので・・・

    なので、万人向けではありません。

  • 辻 直樹 1367 日前

    うまく伝えられなかったですかね。

    一度構成部品を複数挿入・配置したけど、「やっぱりこれ要らんわ。」となって”-1”番目を削除していたら?という場合です。まあ、レアケースかもしれませんが無くはないということで。

    InStrでの判定も、マクロ中のプレフィックス文字を付けるタイミングでの、「既に付いているか?」を見るので、その後の改定とはあまり関係ないかと思うのですが・・・。

    また元々の名前に含まれている可能性についても、更に手間をかけると、プレフィックスなら文字の位置を特定することで識別は可能ですね。

     

    >業務の傍ら挑戦したところ業務以上にどっぷりハマってます。。。

    わかります!私もうまくいかないと気になってしょうがないので、マクロは暇な時しか手を出さないようにしています。

More ...