これまで正常に作動していた差分チェックマクロが急に誤作動するようになり、原因が分からなくて
困っています。
<マクロの内容>
新旧2つの故障コードリストがあり、ワークシート1に新しいリスト、ワークシート2に古いリストが
記載されています。2つのリストの行数は同じではなく、新規コードの追加、既存原文の変更、既存
訳文の変更の可能性があります。
リストの構成
A列:コード、B列:原文、C列:訳文
- C列の訳文を比較し、差分(新出/変更)があれば、D列に「New」と表記
データ数が多いので、配列を使用
-
A列の訳文を比較し、差分があれば、コードを赤字に変更
-
B列の原文を比較し、差分があれば、原文を青字に変更
-
タイトル行を固定
実際のリストが公開できないため難しいかもしれませんが、誤作動を誘発している可能性のあるコードが
分かれば修正できるかもしれないので、それだけでも助かります。
また、誤作動の内容ですが、新出や変更でないものまで、Newとなったり、赤字/青字になったりする
ようになりました。ちなみに、今回、リストの全体的な修正があったため、どこかに誤作動の原因になる
変更があった可能性もありますが、基本的にリストの形式は同じです。
<実際のコード>
Sub KDVDB_DiffCheck()
Dim strProm As String
Dim ws1, ws2 As Worksheet
Set ws1 = Worksheets("New") Set ws2 = Worksheets("Old") Application.ScreenUpdating = False strProm = NoMtch(ws1.Cells(1, 3), ws2.Cells(1, 3)) Call CheckCode Call CheckSource Call Freeze_row Application.ScreenUpdating = True MsgBox "差分チェックの結果はシート『New』に表示されます。", Title:="処理完了", Buttons:=vbInformation
End Sub
Private Function NoMtch(ws1 As Range, ws2 As Range) As String
Dim i As Long Dim lngRows As Long Dim vntData() As Variant Dim dicIndex As Object Set dicIndex = CreateObject("Scripting.Dictionary") With ws2 lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row If lngRows <= 0 Then NoMtch = "データがありません" GoTo Wayout End If vntData = .Offset(1).Resize(lngRows + 1).Value End With For i = 1 To lngRows dicIndex.Item(vntData(i, 1)) = Empty Next i With ws1 lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row If lngRows <= 0 Then NoMtch = "データがありません" GoTo Wayout End If With .Offset(1).Resize(lngRows + 1) vntData = .Value End With End With For i = 1 To lngRows If Not dicIndex.Exists(vntData(i, 1)) Then With ws1.Offset(i) ws1.Offset(i, 1).Value = "New" End With End If Next i
Wayout:
Set dicIndex = Nothing
End Function
Sub CheckCode()
Dim strProm As String
Dim ws1, ws2 As Worksheet
Set ws1 = Worksheets("New") Set ws2 = Worksheets("Old") strProm = NoMtchC(ws1.Cells(1, 1), ws2.Cells(1, 1))
End Sub
Function NoMtchC(ws1 As Range, ws2 As Range) As String
Dim i As Long Dim lngRows As Long Dim vntData() As Variant Dim dicIndex As Object Set dicIndex = CreateObject("Scripting.Dictionary") With ws2 lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row If lngRows <= 0 Then NoMtchC = "データがありません" GoTo Wayout End If vntData = .Offset(1).Resize(lngRows + 1).Value End With For i = 1 To lngRows dicIndex.Item(vntData(i, 1)) = Empty Next i With ws1 lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row If lngRows <= 0 Then NoMtchC = "データがありません" GoTo Wayout End If With .Offset(1).Resize(lngRows + 1) vntData = .Value End With End With For i = 1 To lngRows If Not dicIndex.Exists(vntData(i, 1)) Then With ws1.Offset(i) .Font.Color = vbRed End With End If Next i
Wayout:
Set dicIndex = Nothing
End Function
Sub CheckSource()
Dim strProm As String
Dim ws1, ws2 As Worksheet
Set ws1 = Worksheets("New") Set ws2 = Worksheets("Old") strProm = NoMtchS(ws1.Cells(1, 2), ws2.Cells(1, 2))
End Sub
Function NoMtchS(ws1 As Range, ws2 As Range) As String
Dim i As Long Dim lngRows As Long Dim vntData() As Variant Dim dicIndex As Object Set dicIndex = CreateObject("Scripting.Dictionary") With ws2 lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row If lngRows <= 0 Then NoMtchS = "データがありません" GoTo Wayout End If vntData = .Offset(1).Resize(lngRows + 1).Value End With For i = 1 To lngRows dicIndex.Item(vntData(i, 1)) = Empty Next i With ws1 lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row If lngRows <= 0 Then NoMtchS = "データがありません" GoTo Wayout End If With .Offset(1).Resize(lngRows + 1) vntData = .Value End With End With For i = 1 To lngRows If Not dicIndex.Exists(vntData(i, 1)) Then With ws1.Offset(i) .Font.Color = vbBlue End With End If Next i
Wayout:
Set dicIndex = Nothing
End Function
Sub Freeze_row()
Worksheets("New").Activate
Rows(2).Select
ActiveWindow.FreezePanes = True
Range("A1").Select
End Sub
以上、よろしくお願いいたします。
<解決しました>
誤動作の原因が分かりました。
どう見ても同じなのに不一致、つまり差分箇所と判定されている箇所を
抜き出し、LEN関数で文字数を確認したところ、1文字違っていました。
一方のリストに余分な制御コードが含まれていたのです。
セル内の改行回数は同じであり、スペースもないので、その制御コードに
どのような機能があるのかは不明ですが、すべてのセルの制御コードを
削除した後、改めて差分チェックマクロを実行すると、正確な結果が得られました。
今後は、制御コードによる文字数の不一致にも対応できるようにコードを書き換えたいと
思います。ただし、
Private Sub trim()
Dim c As Range
For Each c In Selection
c = WorksheetFunction.Clean(c)
Next c
End Sub
のような簡易なコードでは時間が結構かかったので、これを何とかしなくてはいけませんが。
回答、コメントをくださった方々、ありがとうございました。
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/07 07:00