|
|||||
テキストの差分を解析するライブラリ(DLL)、差分解析するテキストの文字コード判定 ダウンロード 画面イメージ 使用例(VB6) 使用例(VB.NET) 使用例(C#.NET) 使用例(VBS) ※ ファイル比較関係のその他のツール、サンプルソースはこちらです。 ファイル比較/フォルダ比較 ==================================================================================================== 【タイトル 】テキスト差分解析DLL(VB6/VB.NET/C#.NET) 【Version 】1.0.0.9 【ファイル 】NonDiffDll.zip 【圧縮ファイルの中身】NonDiffVb6.dll、NonDiffNet.dll、ReadMe.txt、サンプルソース 【動作確認 】Windows7/XP/2000 【必要ソフト 】VB6ランタイムまたはMicrosoft .NET Framework Version 2.0 【ソフト種別 】フリーソフト(寄付歓迎) 【作者/著作権者 】のん 【作者への連絡先 】http://homepage2.nifty.com/nonnon/ 【最近の主な変更(1) 】差分解析精度UPおよび高速化 【最近の主な変更(2) 】空白文字の違いを差分としない機能追加 【最近の主な変更(3) 】VB SCRIPTでのテキスト差分解析対応(VBSとVBAで動作確認) ==================================================================================================== 1.はじめに 本プログラムをダウンロード頂きまして誠にありがとうございます。 本プログラムは、テキスト差分を解析するDLLです。 サンプルソースとしてVB6版/VB.NET版/C#.NET版を用意しています。 本DLLは「テキスト差分表示ツール」で使っているロジックをライブラリ化しました。 また、本DLLは差分解析するテキストファイルの文字コード判定と変換が出来ます。 対応している文字コードはSJIS/JIS/EUC/UNICODE/UTF7/UTF8/バイナリです。 (注)100%完璧な文字コード判定は文字コードの性質上ありえませんが、 可能な限り高精度な判定を目指しています。 (注)64ビットの環境(Windows7等)でVBSを実行する際はSysWOW64を使用してください。 (例)C:\Windows\SysWOW64\CScript.exe VbsAp.vbs <関連プログラム> ・テキスト差分表示ツール→2つのテキストファイルの差分を表示します。コマンド ライン(バッチ)/FTP対応の差分出力ツールです。本DLLの差分アルゴリズム でテキスト差分を解析します。 ・フォルダ内のファイル比較ツール→フォルダ内の全ファイルを比較して一覧表示し ます。文字コードが異なるフォルダの全ファイル比較が出来る、FTP対応の同期 支援ツールです。本ツールのフォルダ比較機能として使用しています。 2.インストール方法/アンインストール方法 本プログラムはインストール操作が必要ありません。 アンインストール操作も必要ありませんので、本プログラム一式を削除してください。 NonDiffVb6.dllを使用する場合はVB6がインストールされている必要があります。 NonDiffNet.dllを使用する場合はVS2005(Microsoft .NET Framework Version 2.0)以上が インストールされている必要があります。 3.著作権・ライセンス 本プログラムの全ての著作権は「のん」が所有しています。 本プログラムを転載する場合は著作権所有者の許可が必要となります。 (NonSoftの紹介リンクは問題ありませんので宜しくお願いします) また、著作権所有者が許可したサイトでのみダウンロードが可能となります。 再配布は禁止させて頂きます。商用利用についての制限はありません。 本プログラムはフリーライセンス(寄付歓迎)です。 本プログラムを長期間使用される場合は、寄付やホームページ紹介等してください。 寄付はこちらでお願いします。http://homepage2.nifty.com/nonnon/kifu.html 4.免責事項 本プログラムが原因による損害・問題に対し一切の責任を負えません。 ご利用者の責任の範囲内でお使いください。 5.作者への問合せについて 作者への問合せはメールのみとさせて頂きます。 問合せ内容によっては回答出来ない場合もございますので予めご了承願います。 また、作者不在時または問い合わせ数が多い場合など、 回答に日数がかかる場合がございますので予めご了承願います。 <画面イメージ>
<使用例(VB6)>
' Form に MSFlexGrid を1つ追加したサンプルです。
Option Explicit
' カレントディレクトリを変更するAPI
Private Declare Function SetCurrentDirectory Lib "kernel32" Alias _
"SetCurrentDirectoryA" (ByVal CurrentDir As String) As Long
Private objDiff As Object ' テキスト差分オブジェクト
' フォームロード
Private Sub Form_Load()
' テキスト差分オブジェクト生成
InitNonDiff
' テキストファイル読込
Dim strDt0 As String
Dim strDt1 As String
strDt0 = TextRead(App.Path & "\TestSJIS.txt")
strDt1 = TextRead(App.Path & "\TestUTF8.txt")
' テキスト差分解析
Dim dfList() As String
dfList = objDiff.NonDiff(strDt0, strDt1, 5, 5, 10, "file0", "file1")
' テキスト差分表示
DspDiffList dfList
End Sub
' テキスト差分オブジェクト生成
Private Sub InitNonDiff()
On Error Resume Next
' カレントフォルダの変更
SetCurrentDirectory App.Path
' NonDiffVb6.dllの存在チェック
If CreateObject("NonDiffVb6.NonDiffClass") Is Nothing Then
If Len(Dir("NonDiffVb6.dll")) <> 0 Then
' NonDiffVb6.dllのレジストリ登録
Shell "regsvr32 /s NonDiffVb6.dll", vbHide
Else
' NonDiffVb6.dllをNonDiffAp.exeと同じフォルダに置いてください。
MsgBox _
"NonDiffVb6.dllが見つかりませんでした。" & vbCrLf & vbCrLf & _
"NonDiffVb6.dllを" & vbCrLf & "[" & App.Path & "]" & vbCrLf & _
"に置いてください。"
End
End If
End If
' NonDiffVb6.dllのオブジェクト生成
Set objDiff = CreateObject("NonDiffVb6.NonDiffClass")
If objDiff Is Nothing Then
MsgBox "NonDiffVb6.dllエラー(オブジェクトが生成出来ません)"
End
End If
End Sub
' テキスト差分表示
Private Sub DspDiffList(ByRef dfList() As String)
' 差分リスト初期化
ListInit
' テキスト差分の一覧表示
Dim i As Long
For i = 1 To UBound(dfList, 2)
' 表示データ変換(TABはスペースに変換)
Dim strDt(1) As String
strDt(0) = Replace(dfList(2, i), vbTab, " ")
strDt(1) = Replace(dfList(4, i), vbTab, " ")
' 差分リスト設定(行追加)
MSFlexGrid1.Rows = MSFlexGrid1.FixedRows + i
MSFlexGrid1.Row = MSFlexGrid1.Rows - 1
' 差分リスト設定(表示データ設定)
MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 0) = i
MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 1) = dfList(0, i)
MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 2) = dfList(1, i)
MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 3) = strDt(0)
MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 4) = strDt(1)
MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 5) = dfList(3, i)
' 差分リスト設定(背景色変更)
Dim colval As Long
If MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 1) = "ADD" Then
colval = &HBBBBFF
ElseIf MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 1) = "DEL" Then
colval = &HDDDDDD
ElseIf MSFlexGrid1.TextMatrix(MSFlexGrid1.Row, 1) = "UPD" Then
colval = &HFFFFBB
Else
colval = &HFFFFFF
End If
MSFlexGrid1.Col = 1: MSFlexGrid1.CellBackColor = colval
MSFlexGrid1.Col = 2: MSFlexGrid1.CellBackColor = colval
MSFlexGrid1.Col = 3: MSFlexGrid1.CellBackColor = colval
MSFlexGrid1.Col = 4: MSFlexGrid1.CellBackColor = colval
MSFlexGrid1.Col = 5: MSFlexGrid1.CellBackColor = colval
Next i
End Sub
' テキストファイル読込
Public Function TextRead(ByVal fpath As String) As String
' テキストをバイト配列で読込
Dim bytCode() As Byte
ReDim bytCode(FileLen(fpath) - 1) As Byte
Dim intFileNo As Integer
intFileNo = FreeFile
Open fpath For Binary As intFileNo
Get intFileNo, , bytCode
Close
' 文字コード判定(blnBin=バイナリ判定有り)
Dim codeName As String
codeName = objDiff.GetCodeName(bytCode, blnBin:=True)
' 文字コード変換
Select Case codeName
Case "SJIS"
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
Case "JIS"
TextRead = objDiff.JIS_To_VbUnicode(bytCode)
Case "EUC"
TextRead = objDiff.EUC_To_VbUnicode(bytCode)
Case "UNICODE"
TextRead = objDiff.UNICODE_To_VbUnicode(bytCode)
Case "UTF7"
TextRead = objDiff.UTF7_To_VbUnicode(bytCode)
Case "UTF8"
TextRead = objDiff.UTF8_To_VbUnicode(bytCode)
Case "BIN"
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
Case Else
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
End Select
Exit Function
End Function
' 差分リスト初期化
Private Sub ListInit()
With MSFlexGrid1
.Clear
.AllowUserResizing = flexResizeColumns
.Rows = 2
.Cols = 6
.FixedRows = 1
.FixedCols = 1
.Row = 0
.ColWidth(0) = 700
.Col = 0: .Text = "No."
.CellAlignment = flexAlignCenterCenter
.ColAlignment(0) = flexAlignRightCenter
.ColWidth(1) = 700
.Col = 1: .Text = "状態"
.CellAlignment = flexAlignCenterCenter
.ColAlignment(1) = flexAlignCenterCenter
.ColWidth(2) = 700
.Col = 2: .Text = "行No."
.CellAlignment = flexAlignCenterCenter
.ColAlignment(2) = flexAlignRightCenter
.ColWidth(3) = 4000
.Col = 3: .Text = "ファイル1"
.CellAlignment = flexAlignCenterCenter
.ColAlignment(3) = flexAlignLeftCenter
.ColWidth(4) = 4000
.Col = 4: .Text = "ファイル2"
.CellAlignment = flexAlignCenterCenter
.ColAlignment(4) = flexAlignLeftCenter
.ColWidth(5) = 700
.Col = 5: .Text = "行No."
.CellAlignment = flexAlignCenterCenter
.ColAlignment(5) = flexAlignRightCenter
.Row = MSFlexGrid1.FixedRows
.Col = MSFlexGrid1.FixedCols
.RowSel = MSFlexGrid1.Row
.ColSel = MSFlexGrid1.Col
.FocusRect = flexFocusLight
.SelectionMode = flexSelectionFree
End With
End Sub
<使用例(VB.NET)>
' Form に ListView を1つ追加したサンプルです。
Public Class Form1
Dim objDiff As NonDiffNet.NonDiffClass ' テキスト差分オブジェクト
' フォームロード
Private Sub Form1_Load( _
ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' テキスト差分オブジェクト生成
InitNonDiff()
' テキストファイル読込
Dim strDt0 As String
Dim strDt1 As String
Dim AppPath As String = System.AppDomain.CurrentDomain.BaseDirectory
strDt0 = TextRead(AppPath & "TestSJIS.txt")
strDt1 = TextRead(AppPath & "TestUTF8.txt")
' テキスト差分解析
Dim dfList(,) As String
dfList = objDiff.NonDiff(strDt0, strDt1, 5, 5, 10, "file0", "file1")
' テキスト差分表示
DspDiffList(dfList)
End Sub
' テキスト差分オブジェクト生成
Private Sub InitNonDiff()
objDiff = New NonDiffNet.NonDiffClass
End Sub
' テキスト差分表示
Private Sub DspDiffList(ByRef dfList(,) As String)
' 差分リスト初期化
ListInit()
Dim i As Long
For i = 1 To UBound(dfList, 2)
' 表示データ変換(TABはスペースに変換)
Dim strDt(1) As String
strDt(0) = Replace(dfList(2, i), vbTab, " ")
strDt(1) = Replace(dfList(4, i), vbTab, " ")
' 差分リスト設定(表示データ設定)
Dim dsp(6) As String
dsp(1) = i
dsp(2) = dfList(0, i)
dsp(3) = dfList(1, i)
dsp(4) = strDt(0)
dsp(5) = strDt(1)
dsp(6) = dfList(3, i)
Dim item As ListViewItem = New ListViewItem(dsp)
' 差分リスト設定(背景色変更)
If dsp(2) = "ADD" Then
item.BackColor = System.Drawing.Color.Pink
ElseIf dsp(2) = "DEL" Then
item.BackColor = System.Drawing.Color.LightGray
ElseIf dsp(2) = "UPD" Then
item.BackColor = System.Drawing.Color.Cyan
Else
item.BackColor = System.Drawing.Color.White
End If
' 差分リスト設定(行追加)
ListView1.Items.Add(item)
Next
End Sub
' テキストファイル読込
Private Function TextRead(ByVal fpath As String) As String
Dim sr As IO.Stream = Nothing
Dim br As IO.BinaryReader = Nothing
Try
' テキストをバイト配列で読込
Dim bytCode() As Byte = New Byte(-1) {}
sr = IO.File.Open(fpath, IO.FileMode.Open, IO.FileAccess.Read)
br = New IO.BinaryReader(sr)
bytCode = br.ReadBytes(sr.Length)
' 文字コード判定(blnBin=バイナリ判定有り)
Dim codeName As String
codeName = objDiff.GetCodeName(bytCode, blnBin:=True)
' 文字コード変換
Select Case codeName
Case "SJIS"
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
Case "JIS"
TextRead = objDiff.JIS_To_VbUnicode(bytCode)
Case "EUC"
TextRead = objDiff.EUC_To_VbUnicode(bytCode)
Case "UNICODE"
TextRead = objDiff.UNICODE_To_VbUnicode(bytCode)
Case "UTF7"
TextRead = objDiff.UTF7_To_VbUnicode(bytCode)
Case "UTF8"
TextRead = objDiff.UTF8_To_VbUnicode(bytCode)
Case "BIN"
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
Case Else
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
End Select
Exit Function
Catch ex As Exception
Throw ex
Finally
If br Is Nothing = False Then br.Close()
If sr Is Nothing = False Then sr.Close()
End Try
End Function
' 差分リスト初期化
Private Sub ListInit()
ListView1.Items.Clear()
ListView1.FullRowSelect = True
ListView1.GridLines = True
ListView1.View = View.Details
Dim columnDmy As ColumnHeader = New ColumnHeader
Dim columnNo0 As ColumnHeader = New ColumnHeader
Dim columnTyp As ColumnHeader = New ColumnHeader
Dim columnNo1 As ColumnHeader = New ColumnHeader
Dim columnFl1 As ColumnHeader = New ColumnHeader
Dim columnFl2 As ColumnHeader = New ColumnHeader
Dim columnNo2 As ColumnHeader = New ColumnHeader
columnDmy.Width = 0
columnNo0.Text = "No."
columnNo0.Width = 45
columnTyp.Text = "状態"
columnTyp.Width = 45
columnNo1.Text = "行No."
columnNo1.Width = 45
columnFl1.Text = "ファイル1"
columnFl1.Width = 265
columnFl2.Text = "ファイル2"
columnFl2.Width = 265
columnNo2.Text = "行No."
columnNo2.Width = 45
Dim colHeaderRegValue() As ColumnHeader = _
{columnDmy, columnNo0, columnTyp, columnNo1,
columnFl1, columnFl2, columnNo2}
ListView1.Columns.AddRange(colHeaderRegValue)
End Sub
End Class
<使用例(C#.NET)>
// Form に ListView を1つ追加したサンプルです。
namespace CsNetAp
{
public partial class Form1 : Form
{
NonDiffNet.NonDiffClass objDiff; // テキスト差分オブジェクト
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// テキスト差分オブジェクト生成
InitNonDiff();
// テキストファイル読込
String strDt0;
String strDt1;
String AppPath = System.AppDomain.CurrentDomain.BaseDirectory;
strDt0 = TextRead(AppPath + "TestSJIS.txt");
strDt1 = TextRead(AppPath + "TestUTF8.txt");
// テキスト差分解析
String[,] dfList;
dfList = objDiff.NonDiff(strDt0, strDt1, 5, 5, 10, "file0", "file1");
// テキスト差分表示
DspDiffList(dfList);
}
// テキスト差分オブジェクト生成
private void InitNonDiff(){
objDiff = new NonDiffNet.NonDiffClass();
}
// テキスト差分表示
private void DspDiffList(String[,] dfList)
{
// 差分リスト初期化
ListInit();
long i;
for (i = 1; i <= dfList.GetLength(1) - 1; i++)
{
if (i == dfList.GetLength(1) - 1 && dfList[2, i] ==
"" && dfList[4, i] == "") continue;
// 表示データ変換(TABはスペースに変換)
String[] strDt = new String[2];
if (dfList[2, i] == null) dfList[2, i] = "";
if (dfList[4, i] == null) dfList[4, i] = "";
strDt[0] = dfList[2, i].Replace("\t", " ");
strDt[1] = dfList[4, i].Replace("\t", " ");
// 差分リスト設定(表示データ設定)
String[] dsp = new String[7];
dsp[1] = "" + i;
dsp[2] = dfList[0, i];
dsp[3] = dfList[1, i];
dsp[4] = strDt[0];
dsp[5] = strDt[1];
dsp[6] = dfList[3, i];
ListViewItem item = new ListViewItem(dsp);
// 差分リスト設定(背景色変更)
if (dsp[2] == "ADD")
{
item.BackColor = System.Drawing.Color.Pink;
}
else if (dsp[2] == "DEL")
{
item.BackColor = System.Drawing.Color.LightGray;
}
else if (dsp[2] == "UPD")
{
item.BackColor = System.Drawing.Color.Cyan;
}
else
{
item.BackColor = System.Drawing.Color.White;
}
// 差分リスト設定(行追加)
ListView1.Items.Add(item);
}
}
// テキストファイル読込
private String TextRead(String fpath )
{
String TextRd = "";
System.IO.Stream sr = null;
System.IO.BinaryReader br = null;
try
{
// テキストをバイト配列で読込
sr = System.IO.File.Open(fpath,
System.IO.FileMode.Open, System.IO.FileAccess.Read);
br = new System.IO.BinaryReader(sr);
byte[] bytCode = new byte[sr.Length];
br.Read(bytCode, 0, bytCode.Length);
// 文字コード判定(blnBin=バイナリ判定有り)
String codeName;
codeName = objDiff.GetCodeName(ref bytCode, /*blnBin:=*/true);
// 文字コード変換
switch( codeName)
{
case "SJIS":
TextRd = objDiff.SJIS_To_VbUnicode(ref bytCode);
break;
case "JIS":
TextRd = objDiff.JIS_To_VbUnicode(ref bytCode);
break;
case "EUC":
TextRd = objDiff.EUC_To_VbUnicode(ref bytCode);
break;
case "UNICODE":
TextRd = objDiff.UNICODE_To_VbUnicode(ref bytCode);
break;
case "UTF7":
TextRd = objDiff.UTF7_To_VbUnicode(ref bytCode);
break;
case "UTF8":
TextRd = objDiff.UTF8_To_VbUnicode(ref bytCode);
break;
case "BIN":
TextRd = objDiff.SJIS_To_VbUnicode(ref bytCode);
break;
default:
TextRd = objDiff.SJIS_To_VbUnicode(ref bytCode);
break;
}
return TextRd;
}
catch(Exception ex)
{
throw ex;
}
finally
{
if (br != null) br.Close();
if (sr != null) sr.Close();
}
}
// 差分リスト初期化
private void ListInit()
{
ListView1.Items.Clear();
ListView1.FullRowSelect = true;
ListView1.GridLines = true;
ListView1.View = View.Details;
ColumnHeader columnDmy = new ColumnHeader();
ColumnHeader columnNo0 = new ColumnHeader();
ColumnHeader columnTyp = new ColumnHeader();
ColumnHeader columnNo1 = new ColumnHeader();
ColumnHeader columnFl1 = new ColumnHeader();
ColumnHeader columnFl2 = new ColumnHeader();
ColumnHeader columnNo2 = new ColumnHeader();
columnDmy.Width = 0;
columnNo0.Text = "No.";
columnNo0.Width = 45;
columnTyp.Text = "状態";
columnTyp.Width = 45;
columnNo1.Text = "行No.";
columnNo1.Width = 45;
columnFl1.Text = "ファイル1";
columnFl1.Width = 265;
columnFl2.Text = "ファイル2";
columnFl2.Width = 265;
columnNo2.Text = "行No.";
columnNo2.Width = 45;
ColumnHeader[] colHeaderRegValue =
{columnDmy, columnNo0, columnTyp, columnNo1,
columnFl1, columnFl2, columnNo2};
ListView1.Columns.AddRange(colHeaderRegValue);
}
}
}
<使用例(VBS)>
' ------------------------------------------------
' 事前にNonDiffVb6.dllをレジストリ登録してください
' レジストリ登録方法:regsvr32 NonDiffVb6.dll
' ------------------------------------------------
' テキスト差分オブジェクト定義
Private objDiff
' テキスト差分解析AP呼び出し
DiffTest
MsgBox "終了"
' テキスト差分解析AP
Private Sub DiffTest()
' NonDiffVb6.dllのオブジェクト生成
Set objDiff = CreateObject("NonDiffVb6.NonDiffClassV")
' テキストファイル入力
strDt1 = TextRead("TestUtf8.txt")
strDt0 = TextRead("TestSJIS.txt")
' テキスト差分解析
blnNoSp = False ' 空白文字を比較しない時True
dfList = objDiff.NonDiff(strDt0, strDt1, blnNoSp, 1, 0, 1, "file0", "file1")
' 差分解析結果出力
DiffWrite "DiffOut.csv", dfList
End Sub
' テキストファイル入力
Private Function TextRead(ByVal fpath)
' テキストをバイト配列で読込
Set objADOS = CreateObject("ADODB.Stream")
objADOS.Type = 1
objADOS.Open
objADOS.LoadFromFile fpath
objADOS.Position = 0
bytCode = objADOS.Read()
objADOS.Close
' 文字コード判定(blnBin=バイナリ判定有り)
blnBin = True
Dim codeName
codeName = objDiff.GetCodeName(bytCode, blnBin)
' 文字コード変換
Select Case codeName
Case "SJIS"
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
Case "JIS"
TextRead = objDiff.JIS_To_VbUnicode(bytCode)
Case "EUC"
TextRead = objDiff.EUC_To_VbUnicode(bytCode)
Case "UNICODE"
TextRead = objDiff.UNICODE_To_VbUnicode(bytCode)
Case "UTF7"
TextRead = objDiff.UTF7_To_VbUnicode(bytCode)
Case "UTF8"
TextRead = objDiff.UTF8_To_VbUnicode(bytCode)
Case "BIN"
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
Case Else
TextRead = objDiff.SJIS_To_VbUnicode(bytCode)
End Select
End Function
' 差分解析結果出力
Private Sub DiffWrite(ByVal fpath, ByVal dfList)
Set fso = CreateObject("Scripting.FileSystemObject")
Set txf = fso.CreateTextFile(fpath, True)
For i = 1 To UBound(dfList, 2)
txf.WriteLine dfList(0, i) & "," & _
dfList(1, i) & "," & dfList(2, i) & "," & _
dfList(3, i) & "," & dfList(4, i)
Next
txf.Close
End Sub
|