こちらの続きです。
外部ファイルから点を3Dに取り込む1 - C#ATIA
これは過去に "Unofficial CATIA User Forum" でUpしたものです。
CATVBA や CATVBScript では無く、VBScriptです。
VBScriptで作成するメリットは、D&Dが利用出来るところでしょうか?
ソースコードです。
'VBScript Language = "VBSCRIPT" 'Option Explicit '************************* 'CAT_CSV_Inport 'CSVファイル形式の座標値を、点としてCATIAのファイルに取り込みます '簡単な説明です。アイコンをダブルクリックしても表示されます。 Dim sDClickMsg sDClickMsg = "CSVファイル形式の座標値を、CATIAのファイルに取り込みます。" & vbCrLf & vbCrLf & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "○取り込みファイルについて" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・CSV形式ではない場合は、Excelやメモ帳等を使用して各座標の区切りを「,」にして下さい。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・数値の状態は「X,Y」又は「X,Y,Z」の順に並んでいることを前提に取り込み、4個目以降に" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & " 入っている数値は、無視します。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・データが「X,Y」のものを3Dに取り込む場合、Zの値は「0」として行います。" & vbCrLf & vbCrLf & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "○取り込み実行" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "1)CATIAを起動・ファイルを開き、取り込みを行うワークベンチにしておきます。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "2)本ファイルにCSVファイルをD&Dします。" & vbCrLf & vbCrLf & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "○対応ワークベンチ" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・パート・デザイン:絶対座標値として通常の取り込みを行います。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・ジェネレーティブ・シェープ・デザイン:パートと同様です。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・アセンブリー・デザイン:取り込み先のパートを指定してから実行されます。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & " ※キャッシュ利用している場合、PartファイルであってもCGRファイルとなっている" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & " 可能性があるため指定できません。事前にロードを行ってください。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・プロダクト・ストラクチャー:アセンブリーと同様です。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・スケッチャー:X座標→H座標 Y座標→V座標 Z座標→無視として取り込みます。" & vbCrLf & vbCrLf sDClickMsg = sDClickMsg & "・ドラフティング:アクティブなビューに対し、Z座標を無視して取り込みます。" & vbCrLf & vbCrLf '************************* Dim Catia 'catia Dim FSO 'FileSystemObject Dim TakashimaEGFG 'As Boolean Dim oActDoc 'As Document Dim oSel 'As Selection Dim sMsg '各種メッセージ Const PART = 1 'パート-PrtCfg Const DRW = 3 'ドラフティング-Drw Const ASSY = 4 'アセンブリ-Assembly Const SKET = 5 'スケッチャ-CS0WKS '********* Call Main Set FSO = Nothing Set oActDoc = Nothing Set oSel = Nothing wscript.Quit 0 '********* Private Sub Main() 'メインルーチン Dim i 'As Integer Dim InputType(0) 'As Variant'Assy-SelectElement2用 Dim Result 'ユーザー入力結果 Dim WBtype 'As Integer'WBタイプ Dim objArgs 'D&D Dim sCsv 'csvファイル-配列 Dim aryPos '座標値配列 Dim oTempPart ' As PART 'ActivePart取得用-Assy対策 Dim oSketch 'As Sketch 'ActiveSketch取得用 Dim ConFG 'As Boolean '拘束オプション Dim sFilePath 'D&Dファイル名 Do 'D&Dチェック Set FSO = CreateObject("Scripting.FileSystemObject") Set objArgs = wscript.Arguments 'debug If Drop(objArgs) Then Exit Do 'debug On Error Resume Next 'Catia起動チェック Set Catia = GetObject(, "CATIA.Application") 'debug If Err.number <> 0 Then Exit Do 'Catiaファイルオープンチェック If Catia.Windows.Count < 1 Then sMsg = "インポートするファイルを開いてください" Exit Do End If On Error GoTo 0 'WBチェック WBtype = WBcheck(Catia.GetWorkbenchId) If WBtype = 0 Then sMsg = "未対応のワークベンチです" MsgBox (sMsg) Exit Do End If 'ファイルパス等取得 sFilePath = objArgs(0) Set objArgs = Nothing 'ファイル読み込み sCsv = InPortFile(sFilePath, 0) 'CSV座標変換 aryPos = CreatePos(sCsv) If UBound(aryPos, 2) = 0 Then sMsg = "取り込むべきデータがありません" & vbCrLf sMsg = sMsg & "D&Dファイルをチェックしてみてください" Exit Do End If 'WB別 点作成 Set oActDoc = Catia.ActiveDocument Set oSel = oActDoc.Selection Select Case WBtype Case PART With oSel Call .Clear Call .Search("((((((CATProductSearch.Part + CATStFreeStyleSearch.PartFeature) + CATAsmSearch.Part) + CATPrtSearch.PartFeature) + CATGmoSearch.PartFeature) + CATSpdSearch.PartFeature) + CATPcsSearch.Part),in") Set oTempPart = .Item(1).Value Call .Clear End With Call Del_OJ(oSel, CreateGSD_Point(oTempPart, aryPos)) sMsg = "処理が終了しました" Set oTempPart = Nothing Case ASSY InputType(0) = "Part" With oSel Call .Clear sMsg = "インポート先Partを指定してください // [Esc]=Cancel" Result = .SelectElement2(InputType, sMsg, False) If Result <> "Cancel" Then Call Del_OJ(oSel, CreateGSD_Point(.Item(1).Value, aryPos)) sMsg = "処理が終了しました" Else sMsg = "" End If End With Case SKET sMsg = "インポートの際、拘束を省略しますか?" ConFG = MsgBox(sMsg, vbYesNo) - 6 With oSel Call .Clear Call .Search("CATPrtSearch.Sketch,in") Set oSketch = .Item(1).Value Call .Clear End With Call Create2DPoint(SKET, oSketch, ConFG, aryPos) sMsg = "処理が終了しました" Set oSketch = Nothing Set ConFG = Nothing Case DRW Call Create2DPoint(DRW, oActDoc.Sheets.ActiveSheet.Views.ActiveView, False, aryPos) sMsg = "処理が終了しました" End Select Exit Do Loop '終了前処理 Select Case Err.number Case 0 '正常終了 Case 429 'CATIA起動していないエラー sMsg = "CATIAが起動されていません" Case Else sMsg = "エラーにより中止します" End Select If Len(sMsg) <> 0 Then Call MsgBox(sMsg) End If On Error Resume Next Erase aryPos On Error GoTo 0 End Sub Private Function Drop(DDFiles) 'ドロップ処理 If DDFiles.Count = 0 Then 'ダブルクリック Call MsgBox(sDClickMsg, vbOKOnly, "説明") Drop = True ElseIf DDFiles.Count > 1 Then 'ファイルが複数 sMsg = "D&DするCSV形式のファイルは、1つにしてください" MsgBox (sMsg) Drop = True Else Drop = False End If End Function Private Function WBcheck(ByVal sWorkbench) 'As String) '現在のワークベンチ取得し、処理方法を判断 Select Case sWorkbench Case "PrtCfg", "CATShapeDesignWorkbench" WBcheck = PART Case "Drw" WBcheck = DRW Case "Assembly", "PrsConfiguration" WBcheck = ASSY Case "CS0WKS" WBcheck = SKET Case Else WBcheck = 0 End Select End Function Private Function InPortFile(ByVal sPath, ByVal iDammy) 'ファイル読み込み Dim sTxt, Buf, TS, lngRowMax With FSO.GetFile(sPath).OpenAsTextStream Buf = .ReadAll .Close End With Set TS = FSO.OpenTextFile(sPath) lngRowMax = TS.Line Set TS = Nothing ReDim sTxt(lngRowMax + iDammy) sTxt = Split(Buf, CheckCRLF(Buf), -1, 1) InPortFile = sTxt Erase sTxt End Function Private Function CreateGSD_Point(ByVal oPart, ByVal Pts) '(ByVal oPart As PART, ByVal Pts) '3DのPOINT作成 Dim oHBFactory 'As HybridShapeFactory Dim oAxis 'As AxisSystem Dim oHybridBody 'As HybridBody Dim oHybShpPt 'As HybridShapePointCoord Dim oHybShpPtExp 'As HybridShapePointExplicit Dim oPt, i Set oHBFactory = oPart.HybridShapeFactory Set oAxis = CreateAxis(oPart) Set oHybridBody = oPart.HybridBodies.Add() oHybridBody.Name = "Inport_CSV" 'ダミー作成 oPt = Array(0, 0, 0) Set oHybShpPt = oHBFactory.AddNewPointCoord(oPt(0), oPt(1), oPt(2)) Call oPart.UpdateObject(oHybShpPt) '点作成 For i = 0 To UBound(Pts, 2) oPt = Array(CDbl(Pts(0, i)), CDbl(Pts(1, i)), CDbl(Pts(2, i))) Call oHybShpPt.SetCoordinates(oPt) Call oPart.UpdateObject(oHybShpPt) Set oHybShpPtExp = oHBFactory.AddNewPointDatum(oHybShpPt) Call oHybridBody.AppendHybridShape(oHybShpPtExp) Call oPart.UpdateObject(oHybShpPtExp) Next With oHBFactory .DeleteObjectForDatum oHybShpPt End With Set CreateGSD_Point = oAxis Set oHBFactory = Nothing Set oAxis = Nothing Set oHybridBody = Nothing Set oHybShpPt = Nothing Set oHybShpPtExp = Nothing End Function Private Function CreateAxis(ByVal oPart) ' As PART) '座標系作成 Dim colAxiss 'As AxisSystems Dim oAxis 'As AxisSystem Dim oAxisSysVnt ' As Variant Set colAxiss = oPart.AxisSystems Set oAxis = colAxiss.Add() With oAxis .Type = catAxisSystemStandard .OriginType = catAxisSystemOriginByCoordinates .XAxisType = catAxisSystemAxisByCoordinates .YAxisType = catAxisSystemAxisByCoordinates .ZAxisType = catAxisSystemAxisByCoordinates .IsCurrent = False End With Set oAxisSysVnt = oAxis With oAxisSysVnt .PutOrigin Array(CDbl(0), CDbl(0), CDbl(0)) .PutXAxis Array(CDbl(1), CDbl(0), CDbl(0)) .PutYAxis Array(CDbl(0), CDbl(1), CDbl(0)) .PutZAxis Array(CDbl(0), CDbl(0), CDbl(1)) End With oPart.UpdateObject oAxis Set CreateAxis = oAxis Set colAxiss = Nothing Set oAxis = Nothing End Function Private Sub Del_OJ(ByVal oSel, ByVal OJ) 'セレクションによるオブジェクト削除 With oSel Call .Clear Call .Add(OJ) Call .Cut Call .Clear End With End Sub Private Sub Create2DPoint(ByVal iWB, ByRef oWorkSpace, ByVal ConstFG, ByVal Pts) '2DのPOINT作成 'oWorkSpace SKET-Sketch,DRW-DrawingView Dim oFac2D 'As Factory2D Dim oAxis2D 'As Axis2D Dim oRefH 'As Reference Dim oRefV 'As Reference Dim oRefPnt 'As Reference Dim oPart 'As PART Dim i 'As Integer Dim oPnt2D 'As point2D Dim oConstH 'As Constraint Dim oConstV 'As Constraint Dim colConst 'As Constraints Set oFac2D = oWorkSpace.Factory2D If iWB = SKET Then With oWorkSpace Set colConst = .Constraints Set oAxis2D = .GeometricElements.Item(1) '日本"絶対座標軸":英語"AbsoluteAxis" End With With oSel Call .Clear Call .Add(oWorkSpace) Set oPart = .FindObject("CATIAPart") Call .Clear End With With oAxis2D Set oRefH = oPart.CreateReferenceFromObject(.HorizontalReference) Set oRefV = oPart.CreateReferenceFromObject(.VerticalReference) End With End If For i = 0 To UBound(Pts, 2) Set oPnt2D = oFac2D.CreatePoint(CDbl(Pts(0, i)), CDbl(Pts(1, i))) oPnt2D.Construction = False If ConstFG Then Set oRefPnt = oPart.CreateReferenceFromObject(oPnt2D) With colConst Set oConstH = colConst.AddBiEltCst(1, oRefH, oRefPnt) 'VBS:第一引数catCstTypeDistanceではNG Set oConstV = colConst.AddBiEltCst(1, oRefV, oRefPnt) 'VBS:第一引数catCstTypeDistanceではNG Set oConstH = Nothing Set oConstV = Nothing End With Set oPnt2D = Nothing End If Next Set oFac2D = Nothing Set oAxis2D = Nothing Set oRefH = Nothing Set oRefV = Nothing Set oRefPnt = Nothing Set oPart = Nothing Set oPnt2D = Nothing Set oConstH = Nothing Set oConstV = Nothing Set colConst = Nothing End Sub Private Function CreatePos(ByVal sCsv) 'CSVを座標変換-数値的に細かくても無駄のため小数点以下3桁まで Dim Pos(2) 'As Double '座標値 0-x,1-y,2-z Dim aryPos() '座標値配列 Dim tempPos 'As Text '一時座標値 Dim xyzcount 'As Integer Dim iTenPos 'As Integer ReDim aryPos(2, UBound(sCsv) - 1) For i = 0 To UBound(sCsv) - 1 tempPos = sCsv(i) xyzcount = 0 Do Pos(xyzcount) = CDbl(GetValue(tempPos)) iTenPos = InStr(1, tempPos, ",") If iTenPos = 0 Then Exit Do End If tempPos = Mid(tempPos, iTenPos + 1) xyzcount = xyzcount + 1 Loop Until xyzcount > 2 If xyzcount > 0 Then aryPos(0, i) = CDbl(Pos(0)): Pos(0) = 0 aryPos(1, i) = CDbl(Pos(1)): Pos(1) = 0 If xyzcount > 1 Then aryPos(2, i) = CDbl(Pos(2)): Pos(2) = 0 End If End If Next CreatePos = aryPos Erase Pos Erase aryPos End Function Function CheckCRLF(ByVal sWord) '簡易改行チェック Dim CrFg, LfFg CrFg = InStr(sWord, vbCr) LfFg = InStr(sWord, vbLf) If CrFg <> 0 Then If LfFg <> 0 Then CheckCRLF = vbCrLf Else CheckCRLF = vbCr End If ElseIf LfFg <> 0 Then CheckCRLF = vbLf Else '改行が無い CheckCRLF = vbCrLf End If End Function Private Function GetValue(sTxt) 'Valの代わり Dim i, temp For i = 1 To Len(sTxt) If blnCheck(Mid(sTxt, i, 1)) = False Then Exit For End If Next If i = 1 Then GetValue = 0 Else GetValue = Left(sTxt, i - 1) End If End Function Function blnCheck(strLen) '正規表記による数字のチェック Dim objRE Set objRE = New RegExp objRE.IgnoreCase = True objRE.Pattern = "[0-9.+-]" blnCheck = objRE.test(strLen) Set objRE = Nothing End Function
簡単な説明は、ソースコード先頭付近に記載しています。
又、面倒な方はサンプルと共に下記のサイトにUpしていますので
DLして下さい。
https://grabcad.com/library/csvfile-inport-test-1
今見るとイマイチな部分が多々見られます・・・。
VBScriptだとアウトプロセスになる為、遅いです。
(3000点のサンプルをスケッチの拘束付きで行うと、物凄く時間かかります)
こちらに記載した "システムメニューを表示させる" を行うと、
マクロを高速に実行させる(非公式) - C#ATIA
表示させない時との違いを体感できるかと思います。