-- 重要 --
こちらは古い記述です。
最新のものはこちらになります。
GitHub - kantoku-code/KCL: Library for personal CATVBA (CATIA macro)
------
公開するコードを短くしたい為、非常に個人的に作成している
CATVBA用ライブラリを公開しておきます。
未だに迷いに迷っている為、今後も変更が確実にあり
場合によっては破壊的な変更も十分ありえます。
(古いライブラリでは実行できたマクロが、新しいライブラリでは動かなくなる
と言う意味です。)
主な内容としては、
・汎用的と思われるCATIAの処理(選択等)
・ファイル操作
・配列操作
・簡易マクロスタート時チェック
・簡易ストップウォッチ
ベクトル演算関係も入れたいような・・・。
'vba Kantoku_CATVBA_Library ver0.0.13 'KCL.bas - 標準モジュール Option Explicit Private mSW& '時間計測用 #If VBA7 And Win64 Then Private Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long #Else Private Declare Function timeGetTime Lib "winmm.dll" () As Long #End If '開発用-オブジェクトチェック Sub CATMain() Dim msg$: msg = "選択して下さい : ESCキー 終了" Dim SI As AnyObject Dim doc As Document: Set doc = CATIA.ActiveDocument Do Set SI = SelectItem(msg) If IsNothing(SI) Then Exit Do Stop Loop End Sub '*****CATIAな関数***** 'マクロスタートチェック ''' @param:DocTypes-array(string),string マクロ実行を許可するドキュメントのタイプ ''' @return:Boolean Public Function CanExecute(ByVal docTypes As Variant) As Boolean CanExecute = False If CATIA.Windows.Count < 1 Then MsgBox "ファイルが開かれていません" Exit Function End If If VarType(docTypes) = vbString Then docTypes = Split(docTypes, ",") If Not IsFilterType(docTypes) Then Exit Function Dim ErrMsg As String ErrMsg = "ファイルのタイプが異なります。" + vbNewLine + "(" + Join(docTypes, ",") + " のみです)" Dim ActDoc As Document On Error Resume Next Set ActDoc = CATIA.ActiveDocument On Error GoTo 0 If ActDoc Is Nothing Then MsgBox ErrMsg, vbExclamation + vbOKOnly Exit Function End If If UBound(filter(docTypes, typename(ActDoc))) < 0 Then MsgBox ErrMsg, vbExclamation + vbOKOnly Exit Function End If CanExecute = True End Function '選択 ''' @param:Msg-メッセージ ''' @param:Filter-array(string),string 選択フィルター(指定無し時AnyObject) ''' @return:AnyObject Public Function SelectItem(ByVal msg$, _ Optional ByVal filter As Variant = Empty) _ As AnyObject Dim SE As SelectedElement Set SE = SelectElement(msg, filter) If IsNothing(SE) Then Set SelectItem = SE Else Set SelectItem = SE.Value End If End Function '選択 ''' @param:Msg-メッセージ ''' @param:Filter-array(string),string 選択フィルター(指定無し時AnyObject) ''' @return:SelectedElement Public Function SelectElement(ByVal msg$, _ Optional ByVal filter As Variant = Empty) _ As SelectedElement If IsEmpty(filter) Then filter = Array("AnyObject") If VarType(filter) = vbString Then filter = ToStrVriAry(filter) If Not IsFilterType(filter) Then Exit Function Dim sel As Variant: Set sel = CATIA.ActiveDocument.selection sel.Clear Select Case sel.SelectElement2(filter, msg, False) Case "Cancel", "Undo", "Redo" Exit Function End Select Set SelectElement = sel.Item(1) sel.Clear End Function 'InternalName ''' @param:AOj-AnyObject ''' @return:String Public Function GetInternalName$(ByVal aoj As AnyObject) If IsNothing(aoj) Then GetInternalName = Empty: Exit Function End If GetInternalName = aoj.GetItem("ModelElement").InternalName End Function 'T型のParent取得 Nameでのチェックも必要 ''' @param:AOj-AnyObject ''' @param:T-String ''' @return:AnyObject Public Function GetParent_Of_T( _ ByVal aoj As AnyObject, _ ByVal T As String) _ As AnyObject Dim aojName As String Dim parentName As String On Error Resume Next aojName = aoj.name parentName = aoj.Parent.name On Error GoTo 0 If typename(aoj) = typename(aoj.Parent) And _ aojName = parentName Then Set GetParent_Of_T = Nothing Exit Function End If If typename(aoj) = T Then Set GetParent_Of_T = aoj Else Set GetParent_Of_T = GetParent_Of_T(aoj.Parent, T) End If End Function 'BrepNameの取得 ''' @param:MyBRepName-String ''' @return:String Public Function GetBrepName(MyBRepName As String) As String MyBRepName = Replace(MyBRepName, "Selection_", "") MyBRepName = Left(MyBRepName, InStrRev(MyBRepName, "));")) MyBRepName = MyBRepName + ");WithPermanentBody;WithoutBuildError;WithSelectingFeatureSupport;MFBRepVersion_CXR15)" GetBrepName = MyBRepName End Function '言語取得 'return-ISO 639-1 code 'https://ja.wikipedia.org/wiki/ISO_639-1%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7 Public Function GetLanguage() As String GetLanguage = "non" If CATIA.Windows.Count < 1 Then Exit Function GetLanguage = "other" CATIA.ActiveDocument.selection.Clear Dim st As String: st = CATIA.StatusBar Select Case True Case ExistsKey(st, "object") '英語-Select an object or a command GetLanguage = "en" Case ExistsKey(st, "objet") 'フランス語-Selectionnez un objet ou une commande GetLanguage = "fr" Case ExistsKey(st, "Objekt") 'ドイツ語-Ein Objekt oder einen Befehl auswahlen GetLanguage = "de" Case ExistsKey(st, "oggetto") 'イタリア語-Selezionare un oggetto o un comando GetLanguage = "it" Case ExistsKey(st, "オブジェクト") '日本語-オブジェクトまたはコマンドを選択してください GetLanguage = "ja" Case ExistsKey(st, "объект") 'ロシア語-Выберите объект или команду GetLanguage = "ru" Case ExistsKey(st, "象或") '中国語-???象或?羅 GetLanguage = "zh" Case Else Select Case Len(st) Case 13 '韓国語-???? ?? ?? ?? unicode未対応の為 GetLanguage = "ko" Case 23 '日本語-日本語版以外のため GetLanguage = "ja" Case Else 'それ以外 End Select End Select End Function '文字列内に指定文字が存在するか? '大文字小文字は無視 Private Function ExistsKey(ByVal txt As String, ByVal key As String) As Boolean ExistsKey = IIf(InStr(LCase(txt), LCase(key)) > 0, True, False) End Function '文字型配列? Private Function IsStringAry(ByVal ary As Variant) As Boolean IsStringAry = False If Not IsArray(ary) Then Exit Function Dim i& For i = 0 To UBound(ary) If Not VarType(ary(i)) = vbString Then Exit Function Next IsStringAry = True End Function 'フィルタータイプとしてOK? Private Function IsFilterType(ByVal ary As Variant) As Boolean IsFilterType = False Dim ErrMsg$: ErrMsg = "フィルター又はドキュメントタイプの指定は" + vbNewLine + _ "Variant(String)型配列で行ってください" + vbNewLine + _ "(マクロコードのエラーです)" If Not IsStringAry(ary) Then MsgBox ErrMsg Exit Function End If IsFilterType = True End Function '文字型からバリアント配列生成(CATIAの為にすごく無駄・・・) Private Function ToStrVriAry(ByVal s$) As Variant Dim ary As Variant: ary = Split(s, ",") Dim vriary() As Variant: ReDim vriary(UBound(ary)) Dim i& For i = 0 To UBound(ary) vriary(i) = ary(i) Next ToStrVriAry = vriary End Function '*****システムな関数***** 'Nothing 書き方に統一感が無い為 ''' @param:OJ-Variant(Of Object) ''' @return:Boolean Public Function IsNothing(ByVal oj As Variant) As Boolean IsNothing = oj Is Nothing End Function 'Scripting.Dictionary ''' @param:CompareMode-Long ''' @return:Object(Of Dictionary) Public Function InitDic(Optional CompareMode As Long = vbBinaryCompare) As Object Dim dic As Object Set dic = CreateObject("Scripting.Dictionary") dic.CompareMode = CompareMode Set InitDic = dic End Function 'ArrayList ''' @return:Object(Of ArrayList)Public Function InitLst() As Object Set InitLst = CreateObject("System.Collections.ArrayList") End Function '型チェック ''' @param:OJ-Object ''' @param:T-String ''' @return:Boolean Public Function IsType_Of_T(ByVal oj As Object, ByVal T$) As Boolean IsType_Of_T = IIf(typename(oj) = T, True, False) End Function '*****配列な関数***** '配列の連結 ''' @param:Ary1-Variant(Of Array) ''' @param:Ary2-Variant(Of Array) ''' @return:Variant(Of Array) Public Function JoinAry(ByVal Ary1 As Variant, ByVal Ary2 As Variant) Select Case True Case Not IsArray(Ary1) And Not IsArray(Ary2) JoinAry = Empty: Exit Function Case Not IsArray(Ary1) JoinAry = Ary2: Exit Function Case Not IsArray(Ary2) JoinAry = Ary1: Exit Function End Select Dim StCount&: StCount = UBound(Ary1) ReDim Preserve Ary1(UBound(Ary1) + UBound(Ary2) + 1) Dim i& If IsObject(Ary2(0)) Then For i = StCount + 1 To UBound(Ary1) Set Ary1(i) = Ary2(i - StCount - 1) Next Else For i = StCount + 1 To UBound(Ary1) Ary1(i) = Ary2(i - StCount - 1) Next End If JoinAry = Ary1 End Function '配列の抽出 ''' @param:Ary-Variant(Of Array) ''' @param:StartIdx-Long ''' @param:EndIdx-Long ''' @return:Variant(Of Array) Public Function GetRangeAry(ByVal ary As Variant, ByVal StartIdx&, ByVal EndIdx&) As Variant If Not IsArray(ary) Then Exit Function If EndIdx - StartIdx < 0 Then Exit Function If StartIdx < 0 Then Exit Function If EndIdx > UBound(ary) Then Exit Function Dim RngAry() As Variant: ReDim RngAry(EndIdx - StartIdx) Dim i& For i = StartIdx To EndIdx RngAry(i - StartIdx) = ary(i) Next GetRangeAry = RngAry End Function '配列のクローン ''' @param:Ary-Variant(Of Array) ''' @return:Variant(Of Array) Public Function CloneAry(ByVal ary As Variant) As Variant If Not IsArray(ary) Then Exit Function CloneAry = GetRangeAry(ary, 0, UBound(ary)) End Function '配列の値が一致するか? ''' @param:Ary1-Variant(Of Array) ''' @param:Ary2-Variant(Of Array) ''' @return:Boolean Public Function IsAryEqual(ByVal Ary1 As Variant, ByVal Ary2 As Variant) As Boolean IsAryEqual = False If Not IsArray(Ary1) Or Not IsArray(Ary2) Then Exit Function If Not UBound(Ary1) = UBound(Ary2) Then Exit Function Dim i& For i = 0 To UBound(Ary1) If Not Ary1(i) = Ary2(i) Then Exit Function Next IsAryEqual = True End Function '*****IOな関数***** 'FileSystemObject ''' @return:Object(Of FileSystemObject) Public Function GetFSO() As Object Set GetFSO = CreateObject("Scripting.FileSystemObject") End Function 'パス/ファイル名/拡張子 分割 ''' @param:FullPath-ファイルパス ''' @return:Variant(Of Array(Of String)) (0-Path 1-BaseName 2-Extension) Public Function SplitPathName(ByVal FullPath$) As Variant Dim path(2) As String With GetFSO path(0) = .GetParentFolderName(FullPath) path(1) = .GetBaseName(FullPath) path(2) = .GetExtensionName(FullPath) End With SplitPathName = path End Function 'パス/ファイル名/拡張子 連結 ''' @param:Path-Variant(Of Array(Of String)) (0-Path 1-BaseName 2-Extension) ''' @return:ファイルパス Public Function JoinPathName$(ByVal path As Variant) If Not IsArray(path) Then Stop '未対応 If Not UBound(path) = 2 Then Stop '未対応 JoinPathName = path(0) + "\" + path(1) + "." + path(2) End Function 'ファイル,フォルダの有無 ''' @param:Path-パス ''' @return:Boolean Public Function IsExists(ByVal path$) As Boolean IsExists = False Dim FSO As Object: Set FSO = GetFSO If FSO.FileExists(path) Then IsExists = True: Exit Function 'ファイル ElseIf FSO.FolderExists(path) Then IsExists = True: Exit Function 'フォルダ End If Set FSO = Nothing End Function '重複しない名前取得 ''' @param:Path-ファイルパス ''' @return:新たなファイルパス Public Function GetNewName$(ByVal oldPath$) Dim path As Variant path = SplitPathName(oldPath) path(2) = "." & path(2) Dim newPath$: newPath = path(0) + "\" + path(1) If Not IsExists(newPath + path(2)) Then GetNewName = newPath + path(2) Exit Function End If Dim TempName$, i&: i = 0 Do i = i + 1 TempName = newPath + "_" + CStr(i) + path(2) If Not IsExists(TempName) Then GetNewName = TempName Exit Function End If Loop End Function 'ファイルの書き込み ''' @param:Path-ファイルパス ''' @param:Txt-String Public Sub WriteFile(ByVal path$, ByVal txt) '$) On Error Resume Next Call GetFSO.OpenTextFile(path, 2, True).Write(txt) On Error GoTo 0 End Sub 'ファイル読み込み ''' @param:Path-ファイルパス ''' @return:Variant(Of Array(Of String)) Public Function ReadFile(ByVal path$) As Variant On Error Resume Next With GetFSO.GetFile(path).OpenAsTextStream ReadFile = Split(.ReadAll, vbNewLine) .Close End With On Error GoTo 0 End Function '*****ストップウォッチな関数***** '時間計測スタート Public Sub SW_Start() mSW = timeGetTime End Sub '計測取得 ''' @return:Double(Unit:s) Public Function SW_GetTime#() SW_GetTime = IIf(mSW = 0, -1, (timeGetTime - mSW) * 0.001) End Function
Ver0.05-ストップウォッチな関数追加
Ver0.06-SelectItem関数でキャンセル時、IIfではエラーになるのを修正
Ver0.07-SelectItem/SelectElement関数のフィルタ指定を緩和
-CanExecute関数を追加
Ver0.08-CloneAry関数バグ修正
Ver0.09-JoinPathName関数バグ修正
Ver0.0.10-VBA7(64bit)対応
Ver0.0.11-CanExecute関数 ちょっと強化
Ver0.0.12-InitDicにCompareModeオプション追加
InitLst(DotNet-ArrayList)追加
Ver0.0.13:GetParent_Of_T,WriteFile,ReadFile に例外処理追加