C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

画面キャプチャをクリップボードに保存する

「CATIAで背景色を白にした状態で、画面のキャプチャをクリップボードに取得したい」
と相談を頂きました。

クリップボードではなく、ファイルとしてであればこちらの方法がお手軽かと
思います。
背景の設定を維持しつつ背景を白でキャプチャを行う | PLM Tips Magazine

'vba sample_Capture2Clipboard ver0.0.1 by Kantoku
'CATIAのキャプチャをクリップボードに保存

'--- WinAPI ---
'capture - https://qiita.com/nezuq/items/95cad79d9a9dd920d30e
#If VBA7 And Win64 Then
    Private Declare PtrSafe Sub keybd_event Lib "user32" ( _
    ByVal bVk As Byte, _
    ByVal bScan As Byte, _
    ByVal dwFlags As Long, _
    ByVal dwExtraInfo As Long)
#Else
    Private Declare Sub keybd_event Lib "user32" ( _
    ByVal bVk As Byte, _
    ByVal bScan As Byte, _
    ByVal dwFlags As Long, _
    ByVal dwExtraInfo As Long)
#End If

Const VK_SNAPSHOT = &H2C             '[PrintScrn]キー

Const KEYEVENTF_EXTENDEDKEY = &H1    'キーを押す
Const KEYEVENTF_KEYUP = &H2          'キーを放す

'wait
#If VBA7 Then
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
    Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If

'--- 設定 ---
'キャプチャ時の背景色 RGB
Private Const BACKCOLOR = "255,255,255"

'キャプチャ取得待ち時間 ここの時間は調整してください
Private Const WAITTIME = 200

Option Explicit

Sub CATMain()
    '現在の背景色
    Dim VisSetAtt As VisualizationSettingAtt
    Set VisSetAtt = CATIA.SettingControllers.Item("CATVizVisualizationSettingCtrl")

    Dim ActColor(2) As Long
    Call VisSetAtt.GetBackgroundRGB(ActColor(0), ActColor(1), ActColor(2))
    
    '背景色変更
    Dim rgb As Variant
    rgb = Split(BACKCOLOR, ",")

    Call VisSetAtt.SetBackgroundRGB(rgb(0), rgb(1), rgb(2))
    VisSetAtt.SaveRepository
    
    If MsgBox("キャプチャしますか?", vbYesNo + vbInformation) = vbYes Then
        Call Sleep(WAITTIME)
        Call Exec_Capture 'キャプチャ
    End If
    
    '背景色を戻す
    Call VisSetAtt.SetBackgroundRGB(ActColor(0), ActColor(1), ActColor(2))
    VisSetAtt.SaveRepository
End Sub

'キャプチャ
Private Sub Exec_Capture()
    AppActivate CATIA.Caption, True
    
    keybd_event &HA4, 0&, &H1, 0&
    keybd_event vbKeySnapshot, 0&, &H1, 0&
    keybd_event vbKeySnapshot, 0&, &H1 Or &H2, 0&
    keybd_event &HA4, 0&, &H1 Or &H2, 0&
End Sub

32bitでも対応できるようにしたつもりですが、試す環境が無い為
未テストです。

WinAPIでPrintScrnキーを押しているのですが、タイミングが難しく
確認用のダイアログを出したり、ウェイトしたりしてます。
環境によってはダイアログの残像が残ってしまう可能性があるため、

Private Const WAITTIME = 200

の数値を修正して頂く必要があるかもしれません。
f:id:kandennti:20171114155030p:plain

又、最初に紹介した方法では、アクティブなウィンドウをキャプチャしたファイルが出来上がるのに
対して、このマクロではCATIA全体のキャプチャになってしまう為、イマイチです。
(ウィンドウハンドルとか取得すれば何とかなるのかな?)

CATIAのマクロをDotNetで作る事をオススメしない理由

MVVMお勉強中ですが、イヤになってきたので久々にC#でCATIAの
マクロをちょっと作ろうかなぁ と思ったのですが、諦めました。

何時かは書こうかと思っていたので、折角の機会なので。

1.マクロの記録が取れない

結構重要です。 個人的には各コマンド類(~Factory.AddNew~メソッド類)
や検索キーワード(Selection.Search "~")等は、イチイチ覚えていません。
必要な時に記録を取って、必要な部分だけ(大半が2行)コピーし後は
捨てています。こちらのマクロを作ったのは、その為です。
GrabCAD - CAD library


2.参照設定がシンドイ

こちらでは参照設定の方法を記載しましたが
DotNetでCATIA V5のマクロを作成する際の準備 - C#ATIA

こちらのコメント部に、imihitoさんアドバイスを頂きました。
Excelフォームボタンからマクロの起動 (未確認) - C#ATIA

CATIAっぽい全てのものを設定する必要は無いのですが、
結果的に何の参照が不足しているのかわからず、VBエディターを
開き、オブジェクトブラウザで該当するファイルを調べまくっている
と言うのが本音です。

3.デバッグが辛い

IDEを利用する利用の1つが、デバッグの行いやすさじゃないかと
思います。(インテリセンスもあるかもしれませんが)
個人的にはローカルウィンドウが重要で、変数の中身の状態が確認出来る
だけではなく、プロパティ類の中身をさかのぼって確認出来る点は
非常にありがたく、未知のオブジェクトを調べる際はかなり重宝します。
ところが、C#(DotNet)ではダメなんです。

こちらはVBAで"形状セット1"を選択した状態です。
f:id:kandennti:20171103175501p:plain
スケッチやジオメトリ(点・線・面)等も確認可能ですし、Parentをさかのぼって
行けばPartやPartDocumentも取得可能です。
(Documentが取得できれば、大半 事が足ります)

一方、C#の場合はこちら。
f:id:kandennti:20171103175513p:plain
"形状セット1"の名前すら確認出来ない状態です。 種類の部分は
”MECMOD.HybridBod{System.__ComObject}”と表示されていますが
これは形状セットとわかっている為、キャストした状態だからです。
キャストしないとこんな感じです。
f:id:kandennti:20171103175523p:plain
"INFITF.CATBaseDispatch" じゃ何だかわからないです。

GetTypeメソッドを利用しても

{Name = "__ComObject" FullName = "System.__ComObject"}

と返って来るだけ。 COMオブジェクトだってことは、GetTypeする前から
知ってます・・・。

COM相互運用が原因だとはわかっているのですが、
「動くようにしましたよ」ってだけで同等ではないです。

4.CATSafeArrayVariantが機能していない(と思った)

今日わかったのがこれです。これが書きたかったんです。

"CATSafeArrayVariant" は、点の座標値等受け取る際のもので
Variant配列です。 単純に面を選択し重心を所得する
VBAのコードです。

'vba using-'KCL0.0.12'
Sub CATMain()
    If Not CanExecute("PartDocument") Then Exit Sub
    
    Dim msg$: msg = "面を選択"
    Dim elm As SelectedElement
    Set elm = KCL.SelectElement(meg, "Face")
    If elm Is Nothing Then Exit Sub
    
    Dim doc As PartDocument
    Set doc = elm.Document
    
    Dim ref As Reference
    Set ref = elm.Reference
    
    Dim spa_wb As Object
    Set spa_wb = doc.GetWorkbench("SPAWorkbench")
    
    Dim mes As Variant 'Measurable
    Set mes = spa_wb.GetMeasurable(ref)
    
    Dim cog(2) As Variant 'これが CATSafeArrayVariant
    Call mes.GetCOG(cog)
    
    Debug.Print "重心 : "; Join(cog, ",")
End Sub

最後の方の "cog(2)" が、"CATSafeArrayVariant"です。
取得する際のGetCOGメソッドは、Measurableオブジェクトですが、
正しく型指定するとエラーになります。
(この手の、処理結果を引数のVariant配列に返す、悪魔仕様の
 ものは大半が型指定するとエラーになります)

同様の処理をC#でさせます。
(コードが長くなりすぎる為、例外処理はほぼしてません)

//cs ↓これらの参照設定必要です
using System.Runtime.InteropServices;
using INFITF;
using MECMOD;
using SPATypeLib;

    class Program
    {
        static void Main()
        {
            //モロモロ
            var cat = (INFITF.Application)Marshal.GetActiveObject("CATIA.Application");
            var doc = cat.ActiveDocument as MECMOD.PartDocument;

            //選択
            var msg = "面を選択";
            var sel = doc.Selection;
            var cancel_code = new string[] { "Cancel", "Undo", "Redo" };
            var filter = new object[] { "Face" };

            sel.Clear();
            string res = sel.SelectElement2(filter, msg, false);
            if (cancel_code.Any(x => x.ToString() == res)) { return; }

            var face_ref = sel.Item2(1).Reference;

            //SPAWorkbench
            var SpaWB = doc.GetWorkbench("SPAWorkbench") as SPAWorkbench;
            if (SpaWB == null) { return; }

            //Measurable
            var mes = SpaWB.GetMeasurable(face_ref);

            //重心
            var cog = new object[3];
            mes.GetCOG(cog);

            Console.WriteLine(string.Format(
                "重心 : {0},{1},{2}", cog[0], cog[1], cog[2]));
            Console.ReadKey();
        }
    {

VBAのVariant配列は、C#の場合object配列です。 これ

            mes.GetCOG(cog);

ここでエラーになる予定だったのですが、正しく処理してます・・・。
不安定ですね・・・。本当は

            var mes_oj = mes as object;
            mes_oj.GetCenter(cog);

だと、型付けが邪魔で出来ないから

            dynamic mes_oj = mes as object;
            mes_oj.GetCenter(cog);

にしたけど、やっぱりエラーになるよ って書きたかったのですけどね。

こちらでも機能してないって書いてあるんですけど。
http://www.coe.org/p/fo/st/per=10&sort=0&thread=24278&p=1




他にも 
C#だと "遅い" → どうでも良いです。
DLL化すれば同レベルで処理します。(要レジストリに登録ですが)

C#だと配布しやすい → catvbsやvbsでも同様です。

・catvbsやvbsだとソースコード見られちゃう
  → CATVBAでパスワード付けるか。
 vbsを暗号化
VBScriptの暗号化 | VBScript さんま屋


・他言語熟知者にとってのVBAの学習コスト 
  →VBA異質だから、結構納得。

検索すると結構 "PythonでCATIAのマクロ" がHitするのですが、
動的型付け言語の方がC#より向いている気がします。

現状、DotNetで作る価値が見つかりませんね。

※追記です
GetCOGのパラメータです。
f:id:kandennti:20171106092508p:plain
配列としか出ていませんでした。

「簡単」すら難しい

過去に社内で使うものはWPFを素のままで作成しましたが、しんどいので
Prismを利用する事にしました。
基本的なサンプルから練習しようとこちらのサイトを参考にさせてもらいました。

簡単MVVM入門 with Prism - Qiita

個人的には、「簡単」すら難しかったです・・・。


VS2017 Community で行っていますが、NuGetパッケージマネージャーは改めて
インストールする必要は無かったです。

「Prism Template Pack」ではなく、NuGetの方の「Prism v5.0.0」です。 
僕が行った際、ターゲットフレームワークは 「.NET Framework 4.0」では、
「Prism.Composition」だけが、インストール出来ませんでした。(悩みました)
最低でも 4.5 は必要なのではないか? と思われます。


まず新規に作成する際、Prismのテンプレートではないです。(ここでも悩みました)
素の「WPFアプリ」から作成し、名前空間の記載から恐らくソリューションの状態は
各フォルダ毎に分けているっぽいので、こんな感じです。
f:id:kandennti:20171102143930p:plain

最後の部分ではViewについてはサラッとしか記載されていないのですが、
こんな感じで動きました。(恐らくPrismには無関係だからでしょう)

xaml

<!-- xaml View/View.xaml -->
<Window x:Class="Calclator.View.View"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Calclator.View"
        mc:Ignorable="d"
        Title="View" Height="140" Width="240">
    
    <Grid>
        <TextBox 
            x:Name="textBox" HorizontalAlignment="Left" Height="25" 
            Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding Path=X}" 
            VerticalAlignment="Top" Width="120"/>
        
        <TextBox 
            x:Name="textBox_Copy" HorizontalAlignment="Left" Height="25" 
            Margin="10,40,0,0" TextWrapping="Wrap" Text="{Binding Path=Y}" 
            VerticalAlignment="Top" Width="120"/>
        
        <TextBox 
            x:Name="textBox_Copy1" HorizontalAlignment="Left" Height="25" 
            Margin="10,70,0,0" TextWrapping="Wrap" Text="{Binding Path=Ans}" 
            VerticalAlignment="Top" Width="120"/>
        
        <Button 
            x:Name="button" Content="Button" HorizontalAlignment="Left" 
            Margin="140,10,0,0" VerticalAlignment="Top" Width="75" 
            Command="{Binding calcCommand}"/>
    </Grid>
</Window>

答えがTextBoxで良いのかな? とか有りますが、元の記載に合わせました。

コードビハインド側

//cs View.xaml.cs
using System.Windows;
using Calclator.ViewModel;

namespace Calclator.View
{
    /// <summary>
    /// View.xaml の相互作用ロジック
    /// </summary>
    public partial class View : Window
    {
        public View()
        {
            InitializeComponent();
            this.DataContext = new ViewModels();
        }
    }
}

テンプレートで出来あがるXAMLは削除した為、起動時にView.xamlが表示されるように
App.xaml(エントリーポイント?)も修正。

<!-- xaml App.xaml -->
<Application x:Class="Calclator.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Calclator"
             StartupUri="View/View.xaml">
    
    <Application.Resources>
         
    </Application.Resources>
</Application>

何で、C#はこんなにコード書かなきゃいけないんだろう?

VS2017

社内で利用する為のツールを作らなきゃならないと思いつつ
数年経ってしまっているのですが、気が重いです。

目的のものはGUIが必要なのですが、個人的に非常に苦手です。

本来であれば、勉強ついでにPythonで と思っていたのですが
GUIが必要となるとC#の方が楽な気がして、仕方無しに
VS2017 Communityエディションをインストールしました。

何もかも忘れてます。 困ったな・・・。

ボディをかき集める

Fusion360と他のCADを併用されている方いらっしゃいますか?

Fusion360は色々なフォーマットのデータを読み込んでくれるので
助かっているのですが、Fusion360上ではこんな感じで表示しているのに
f:id:kandennti:20171027193132p:plain
中間フォーマットでエクスポートしたものを、他のCADで読み込んだ際
こんな感じになってガッカリした経験は無いでしょうか?
f:id:kandennti:20171027193141p:plain
何で、色が抜けるのか? 僕、理由を知ってます。
実はデータの状態で色が抜けてしまうようです。
f:id:kandennti:20171027193149p:plain
ちょっと大げさにしましたが赤印位置にボディがあり
全てルートコンポーネント(一番トップのコンポーネント)ではない位置に
入っています。 原因はこれなんです。
(Upしたデータは、子コンポーネントに入っているような気がしてます)

色を反映させてエクスポートしたいのであれば、全てのボディを
ルートコンポーネントに移動させればOKです。
f:id:kandennti:20171027193200p:plain
これって、Tree上でD&Dをやれば済む話ではあるのですが、
対象のボディが案外Treeの深い位置にあり、数が多いと面倒なんです。

・・・そう、面倒。 なので全てのボディをかき集めるスプリクトを
作ってみました。

#FusionAPI_python
#Author-kantoku
#Description-Collect_All_Body
#アクティブなプロダクトの全てのボディをルートにかき集める

import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        #確認
        msg = '全てのボディをルートコンポーネントにかき集めます。\nよろしいですか?'
        title = 'ボディかき集め'
        btn = adsk.core.MessageBoxButtonTypes.OKCancelButtonType
        icon = adsk.core.MessageBoxIconTypes.QuestionIconType
        Res = ui.messageBox(msg, title, btn, icon) 
        
        if Res != adsk.core.DialogResults.DialogOK: return       
        
        #モロモロ
        product = app.activeProduct
        des = adsk.fusion.Design.cast(product)       
        
        #パラメトリックじゃないとNG
        des.designType = adsk.fusion.DesignTypes.ParametricDesignType
        
        #ルート
        root = des.rootComponent
        
        #ルート以下のコンポーネント
        cmplst = []
        cmplst = Get_Comps(root, cmplst)
        
        #全ボディコンテナ
        bdyslst = [cmp.bRepBodies for cmp in cmplst if cmp.bRepBodies.count > 0]
        
        #全ボディ
        bdylst = []
        for bdys in bdyslst:
            for bdy in bdys:
                bdylst.append(bdy)
        if bdylst.count == 0 :
            return
        
        #カットペースト
        tgtBodies = root.features.cutPasteBodies
        [tgtBodies.add(bdy) for bdy in bdylst]
        
        #おしまい
        ui.messageBox('Done')

    except:
        if ui:
            ui.messageBox('エラー\n{}'.format(traceback.format_exc()))

#全コンポーネント
def Get_Comps(comp, complst):
    occs = comp.occurrences
    
    lst = [occ.component for occ in occs]
    
    if lst.count == 0:
        return complst
    
    for cmp in lst:
        complst.append(cmp)
        Get_Comps(cmp, complst)
    return complst

Pythonまだまだ駄目だなぁ。見事に二重ループがあるし…。
こんな感じです。

本当は、CATIAのProductからPartを作るコマンドをイメージしていたのですが
異なるDocument間でどうやったらコピペ出来るのか、方法わかりませんでした。
僕はこれで事足りるんですけどね。

Drawのテーブルに最後の列を追加2

こちらの続きです。
Drawのテーブルに最後の列を追加 - C#ATIA

前回のマクロ、ちょっとダメなんです。
セルの文字だけのコピーだったので、フォントのボールド等が正しくなかったのです。
f:id:kandennti:20171027123422p:plain

寸法テーブルのサイズ変更する方法をmineさんに教えて
頂いたのですが、実際に使う際、一定しない列数を追加し
テーブルの見出し? も入れたいのです。
f:id:kandennti:20171027123434p:plain
結構めんどくさいんです。

そこで修正してみました。

'vba DrawTable_Add_LastColumn ver0.0.2  using-'KCL0.0.12'  by Kantoku

Option Explicit

Private Const Def = "hoge,piyo,huga" 'デフォルト文字

Sub CATMain()

    'ドキュメントのチェック
    If Not CanExecute("DrawingDocument") Then Exit Sub

    'テーブル選択
    Dim Msg As String
    Msg = "列を追加するテーブルを選択 // [Esc]=Cancel"
    
    Dim Tbl As DrawingTable
    Set Tbl = KCL.SelectItem(Msg, "DrawingTable")
    If Tbl Is Nothing Then Exit Sub
    
    'ユーザー
    Msg = "追加するタイトルを入力 例)hoge,piyo""
    Dim Inp As String
    Inp = InputBox(Msg, "", Def)
    If Inp = vbNullString Then Exit Sub
    
    '追加数列
    Dim Txts As Variant: Txts = Split(Inp, ",")
    Dim AddCnt As Long: AddCnt = UBound(Txts) + 1
    
    '元列数
    Dim CntCol As Long: CntCol = Tbl.NumberOfColumns
    Dim AllColCnt As Long: AllColCnt = CntCol + AddCnt
    
    '列追加
    Tbl.ComputeMode = CatTableComputeOFF
    
    Dim i As Long
    For i = 1 To AddCnt
        Call Tbl.AddColumn(CntCol)
    Next
    
    '最後を追加の最初にコピー
    Call Copy_Column(AllColCnt, CntCol, Tbl)
    
    '空欄設置
    Call Reset_Column(CntCol + 1, AllColCnt, Tbl)
    
    'タイトル設置
    Call Set_Title(Txts, 25#, Tbl)
    
    Tbl.ComputeMode = CatTableComputeON
End Sub

Private Sub Set_Title(ByVal Ary As Variant, _
                      ByVal Width As Double, _
                      ByVal Tbl As DrawingTable)
    Dim Ed As Long: Ed = Tbl.NumberOfColumns
    Dim St As Long: St = Ed - UBound(Ary)
    
    Dim i As Long, Cell As DrawingText
    Dim Cnt As Long: Cnt = 0
    
    For i = St To Ed
        Call Tbl.SetColumnSize(i, Width)
        Set Cell = Tbl.GetCellObject(1, i)
        Cell.Text = Ary(Cnt)
        Cnt = Cnt + 1
        Cell.TextProperties.Justification = catCenter
    Next
End Sub

Private Sub Reset_Column(ByVal A As Long, _
                         ByVal B As Long, _
                         ByVal Tbl As DrawingTable)

    Dim Vw As DrawingView: Set Vw = Tbl.Parent.Parent
    Dim Dmy As DrawingText: Set Dmy = Vw.Texts.Add("", 0#, 0#)
    Dmy.TextProperties.Justification = catCenter
    
    Dim CntRow As Long: CntRow = Tbl.NumberOfRows
    Dim Cell As DrawingText
    Dim i As Long
    
    For i = 1 To CntRow
        Set Cell = Tbl.GetCellObject(i, B)
        Call Copy_DrwTxtProperties(Cell.TextProperties, _
                                   Dmy.TextProperties)
        Cell.Text = ""
    Next
    
    For i = B To A + 1 Step -1
        Call Copy_Column(i, i - 1, Tbl)
    Next
    
    Dim Sel As Selection
    Set Sel = KCL.GetParent_Of_T(Vw, "DrawingDocument").Selection
    With Sel
        .Clear
        .Add Dmy
        .Delete
    End With
End Sub

Private Sub Copy_Column(ByVal A As Long, _
                        ByVal B As Long, _
                        ByVal Tbl As DrawingTable)
    Dim CntRow As Long: CntRow = Tbl.NumberOfRows
    Dim Cell(1) As DrawingText
    Dim TxtPpt(1) As DrawingTextProperties
    Dim i As Long
    
    For i = 1 To CntRow
        Set Cell(0) = Tbl.GetCellObject(i, A)
        Set Cell(1) = Tbl.GetCellObject(i, B)
        Call Copy_DrwTxtProperties(Cell(0).TextProperties, _
                                   Cell(1).TextProperties)
        Cell(1).Text = Cell(0).Text
    Next
End Sub

Private Sub Copy_DrwTxtProperties(ByVal Tpp1 As DrawingTextProperties, _
                                  ByVal Tpp2 As DrawingTextProperties)
    With Tpp2
        .AnchorPoint = Tpp1.AnchorPoint
        .Blanking = Tpp1.Blanking
        .Bold = Tpp1.Bold
        .Color = Tpp1.Color
        .FONTNAME = Tpp1.FONTNAME
        .FONTSIZE = Tpp1.FONTSIZE
        .FrameName = Tpp1.FrameName
        .FrameType = Tpp1.FrameType
        .Italic = Tpp1.Italic
        .Justification = Tpp1.Justification
        .Kerning = Tpp1.Kerning
        .Mirror = Tpp1.Mirror
        .Overline = Tpp1.Overline
        .StrikeThru = Tpp1.StrikeThru
        .Subscript = Tpp1.Subscript
        .Underline = Tpp1.Underline
    End With
End Sub

見事な肥大化っぷり・・・。
最初の時点ではかなり遅かったのですが、DrawingTable.ComputeModeを
利用するとストレスを感じるほどでは無くなりました。

マクロ実行後、ダイアログが出現しカンマ区切りで文字を入力すると
区切った分の列を追加し、見出しとして入力されます。

作ったけど、使うかなぁ・・・。

複数のフォルダを削除する

仕事が薄い時に、日頃の不満を解消したい。

PowerMill内のフォルダを削除したい時が多々あるのですが、
まとめて削除出来ず、一個一個チマチマやるのが辛いです。

一度に複数のフォルダを削除する為のマクロを作りました。

//PMill_Macro2018
//フォルダー削除 ver0.0.1

function main(string args) {
	//フォルダリスト
	string list folderLst = {}
	call GetFolderNameLIST($args, $folderLst)
	if is_empty($folderLst) {
		message error  'フォルダがありません!!'
		return
	}
	
	string msg = '削除するフォルダーを選択してください'
	call Exec_DownMenu($folderLst, $msg, 1, $folderLst)
	if size($folderLst) < 1 {
		return
	}
	
	//削除
	call Msgoff()
	string  path = ""
	foreach fdr in $folderLst {
		$path = $args + '\' + replace($fdr, '@', '\')
		//message info  $path 
		string cmd = 'DELETE ' + $args + ' FOLDER "' + $path + '"'
		call Exec_Cmd(cmd) 
	}
	call Msgon()
	
	//終了
	message info  'Done'	
}

//指定した組み込みルートフォルダ内のフォルダ名を取得
function GetFolderNameLIST(string FolderType, output string list Outlst ) {
	string list Folders = get_folders($FolderType)
	if (size($Folders) == 0) {
		return
   }
   
	string list names={}
	foreach path in $Folders {
		string name = path
		$name = replace($name, $FolderType + '\', '')
		$name = replace($name, '\', '@')
		int dmy = add_last($names,$name)
   }
	$Outlst= $names
	return
}
//コマンド
function Exec_Cmd(string cmd) {
	docommand $cmd
}

function Msgoff() {
	graphics lock
	dialogs message off
	dialogs error off
}

function Msgon() {
	graphics unlock
	dialogs message on
	dialogs error on
}
include downmenu.inc

mainのargsは、"Toolpath"等のフォルダ名で、コンテキストメニューから起動させる
タイプです。

過去に、こちらでフォルダ名を取得するものを作りましたが、
イマイチだった為、Forumにあった方法をパクリ参考に
させてもらいました。
フォルダ名リストを取得する - C#ATIA

又、以前作成したプルダウンリストが必要です。
"group" フォルダは犠牲にした、プルダウンリストライブラリ - C#ATIA