プログラマとプロマネのあいだ

プログラマもやるし、プロマネもやるし、たまに似非アーキとか営業っぽいこともやる

WSH&HTAでファイル分割

VBScriptで書いたコマンドツールをHTAにも対応させれば、簡単にGUI化が可能ではないか?との発想からやってみたところ、案外簡単に出来ました。が、hta中にWScriptという記述があると、スクリプトエラーになってしまうことから、コアのサブルーチンのみvbsで共有して、コード量を最小化できないかと考えました。
MSDNスクリプトを分割し再利用性を高めるを読んだところ、wsfとかいうのを使えば良いというのは分かったものの、具体的なサンプルは載っておらず。
WSFについては、XML要素を読めば、大体分かるかと思います。
で、こんな感じになりました。
■csvdiff.vbs

Sub csvdiff(infile1, infile2, outfile)
	Set fs = CreateObject("Scripting.FileSystemObject")
	Set ts1 = fs.OpenTextFile(infile1)
	Set ts2 = fs.OpenTextFile(infile2)
	Set ts3 = fs.CreateTextFile(outfile)

	While ts1.AtEndOfLine = False
		lineNum = ts1.Line
		line1 = ts1.readLine
		line2 = ts2.readLine

		line1Split = split(line1, ",")
		line2Split = split(line2, ",")

		ts3.writeLine lineNum & ",修正前," & line1
		ts3.writeLine lineNum & ",修正後," & line2

		diffLine = ""
		For i=0 to UBound(line1Split)
			If i <> 0 Then
				diffLine = diffLine & ","
			End If

			If line1Split(i) = line2Split(i) Then
				diffLine = diffLine & " "
			Else
				diffLine = diffLine & "×"
			End If
		Next
		ts3.writeLine lineNum & ",比較," & diffLine
	Wend

	ts1.close
	ts2.close
	ts3.close
End Sub

■csvdiff.wsf

<package>
	<job id="test">
		<script language = "VBScript" src = "csvdiff.vbs"></script>
		<script language = "VBScript">
			If WScript.Arguments.count <> 3 Then
				WScript.Echo "Usage: csvdiff.vbs [infile1] [infile2] [outfile]"
				WScript.Quit(1)
			Else
				infile1 = WScript.Arguments(0)
				infile2 = WScript.Arguments(1)
				outfile = WScript.Arguments(2)
			End If
			
			Call csvdiff(infile1, infile2, outfile)
		</script>
	</job>
</package>

■csvdiff.bat

@echo off

cscript //NoLogo csvdiff.wsf %1 %2 %3

■csvdiff.hta

<html>
<head>
<script language = "VBScript" src = "csvdiff.vbs"></script>
<script language = "VBScript">
Sub button1_Click
	Call csvdiff(form1.file1.value, form1.file2.value, form1.file3.value)
End Sub
</script>
</head>

<body>
<form name = "form1">
<input name = "file1" type = "file"><br>
<input name = "file2" type = "file"><br>
<input name = "file3" type = "file"><br>
<input name = "button1" type = "button" value = "csvdiff" onClick = "button1_Click()">
</form>
</body>
</html>

ポイントは、csvdiff.wsfでしょう。共通部品であるcsvdiff.vbsを読み込みつつ、メインとなる処理も記述できます。これならコピペで同じようなスクリプトを氾濫させずに済みそうです。