こちらの続きです。
同一UUIDのDraw参照元ファイルを差し替える1 - C#ATIA
前回の最後に「指定したPartファイルから、どのDrawファイルを利用するか?」が
難しくと書きました。 難しいです。
一発で差し替えは個人的にほぼムリと考えています。
・組み合わせる為の暫定的なリストを、CSVファイルで作成(マクロ)
↓
・Excelでチョロチョロ調整(人力)
↓
・差し替えDrawの作成(マクロ)
の2本立てを考えてます。
どうやって、暫定的な組合せを作ろうか? と思い真っ先に思いついたのが
こちらです。
Infomentさん感謝してます。正直、レーベンシュタイン距離なんて知りませんでした。
リンク先のリンク先のコードを元に、テストの為のコードを作ったのですが、
文字数の制約やExcel限定っぽさがあったので少し変更しました。
'vba using-'KCL0.0.12' by Kantoku Sub Test_LevenshteinDistance() Dim path1 As String path1 = "C:\Program Files\Dassault Systemes\B22\win_b64\code\bin32" Dim fs1 As Object Set fs1 = GetFiles(path1) Dim path2 As String path2 = "C:\Program Files\Dassault Systemes\B27\win_b64\code\bin32" Dim fs2 As Object Set fs2 = GetFiles(path2) Dim dic As Object Set dic = KCL.InitDic() Dim v1, v2, ratio, max_ra, stack For Each v1 In fs1 max_ra = 0 stack = "" For Each v2 In fs2 ratio = Levenshtein(v1, v2) If max_ra < ratio Then max_ra = ratio stack = v2 End If Next Debug.Print max_ra & "% : " & v1 & " <-> " & stack Next End Sub Private Function GetFiles(ByVal path As String) Dim fso As Object Set fso = KCL.GetFSO Dim lst As Object Set lst = KCL.InitLst() Dim f As Object For Each f In fso.GetFolder(path).files lst.Add f.Name Next Set GetFiles = lst End Function 'https://infoment.hatenablog.com/entry/2018/11/17/183339 'https://code.i-harness.com/ja/q/40be5c Private Function Levenshtein( _ ByVal str1 As String, _ ByVal str2 As String) As Long Dim str1_len As Long str1_len = Len(str1) Dim str2_len As Long str2_len = Len(str2) Dim dist() As Long ReDim dist(str1_len, str2_len) dist(0, 0) = 0 Dim smStr1() As Long ReDim smStr1(str1_len) As Long Dim i As Long For i = 1 To str1_len dist(i, 0) = i smStr1(i) = Asc(LCase(Mid$(str1, i, 1))) Next Dim smStr2() As Long ReDim smStr2(str2_len) As Long For i = 1 To str2_len dist(0, i) = i smStr2(i) = Asc(LCase(Mid$(str2, i, 1))) Next Dim min1 As Long, min2 As Long, min3 As Long, minmin As Long, MaxL As Long Dim j As Long For i = 1 To str1_len For j = 1 To str2_len If smStr1(i) = smStr2(j) Then dist(i, j) = dist(i - 1, j - 1) Else min1 = dist(i - 1, j) + 1 min2 = dist(i, j - 1) + 1 min3 = dist(i - 1, j - 1) + 1 If min2 < min1 Then If min2 < min3 Then minmin = min2 Else minmin = min3 Else If min1 < min3 Then minmin = min1 Else minmin = min3 End If dist(i, j) = minmin End If Next Next MaxL = str1_len If str2_len > MaxL Then MaxL = str2_len Levenshtein = 100 - CLng((dist(str1_len, str2_len) * 100) / MaxL) End Function
あまり業務っぽいファイル名だとまずいので、同一のCATIAのインストールフォルダの
一部をR22とR27で比較しています。結果はこちら
100% : CATAutoItf.dll <-> CATAutoItf.dll 100% : CATJNIBridge.dll <-> CATJNIBridge.dll 100% : CATRTCChildProcess.exe <-> CATRTCChildProcess.exe 100% : CATRTCDlg.dll <-> CATRTCDlg.dll 100% : CATRTCItf.dll <-> CATRTCItf.dll 100% : CATRTCMsgLayer.dll <-> CATRTCMsgLayer.dll 100% : CATRTCMSLiveImpl.dll <-> CATRTCMSLiveImpl.dll 100% : CATRTCSametimeImpl.dll <-> CATRTCSametimeImpl.dll 100% : CATSysAllocator.dll <-> CATSysAllocator.dll 66% : CATSysAllocator.dll.beforeSPK <-> CATSysAllocator.dll 100% : CATSysMainThreadMQ.dll <-> CATSysMainThreadMQ.dll 69% : CATSysMainThreadMQ.dll.beforeSPK <-> CATSysMainThreadMQ.dll 100% : CATSysMultiThreading.dll <-> CATSysMultiThreading.dll 71% : CATSysMultiThreading.dll.beforeSPK <-> CATSysMultiThreading.dll 100% : CATSysPreview.dll <-> CATSysPreview.dll 100% : CATSysTS.dll <-> CATSysTS.dll 55% : CATSysTS.dll.beforeSPK <-> CATSysTS.dll 100% : CATSysTSObjectModeler.dll <-> CATSysTSObjectModeler.dll 71% : CATSysTSObjectModeler.dll.beforeSPK <-> CATSysTSObjectModeler.dll 100% : CATVBAHostingApplication.exe <-> CATVBAHostingApplication.exe 100% : CATVBAInfra.dll <-> CATVBAInfra.dll 100% : JS0FM.dll <-> JS0FM.dll 47% : JS0FM.dll.beforeSPK <-> JS0FM.dll 100% : JS0GROUP.dll <-> JS0GROUP.dll 55% : JS0GROUP.dll.beforeSPK <-> JS0GROUP.dll 100% : JS0SPEXT.dll <-> JS0SPEXT.dll 55% : JS0SPEXT.dll.beforeSPK <-> JS0SPEXT.dll 100% : mfc70u.dll <-> mfc70u.dll 100% : msvci70.dll <-> msvci70.dll 100% : msvcr70.dll <-> msvcr70.dll
「~win_b64\code\bin」の様に、ファイル数が多いフォルダで試すと
処理が返って来ませんでした・・・。
恐らく毎回動的配列を確保しているからじゃないかな?
「AI採用してます」って嘘ついても大丈夫そうなぐらいな結果が
得られている気がします。