WSHとxdoc2txtでExcelファイルの内容を検索

# WSHとxdoc2txtでExcelファイルの内容を検索

今更なWSHです。ネ申Excelな仕様書のお供にどうぞ。(´・ω・`)
Excelファイル の中身を展開するのは [xdoc2txt](http://ebstudio.info/home/xdoc2txt.html) を使用しています。

# 使い方

exgrep.js はxdoc2txt.exe と同一のフォルダに置いてください。


▼呼び出し側はこんなかんじ。

```
cmd /k cscript C:\test\exgrep.js "検索文字列" "C:\data\"
```
```
cmd /k cscript C:\test\exgrep.js -e "正規表現キーワード" "C:\data\"
```


▼本体

```js:exgrep.js
"use strict";

(function () {

var objFileSys = WScript.createObject("Scripting.FileSystemObject");

//このスクリプトが格納されているフォルダ
function GetScriptFolder() {
	return objFileSys.GetParentFolderName(WScript.scriptFullName);
}

//フォルダ内のファイルを列挙する
var objFileList = {
	files:[],
	ext:[],
	remove:[],
	init: function() {
		this.files = [];						//検索されたExcelファイル
		this.ext =  ["xls", "xlsx", "xlsm"];	//検索対象のExcelファイル拡張子
		this.remove = ["^~\\$.*"];				//Excelの一時ファイルは検索対象外
	},
	isTarget: function(sFile) {
		var i, j, strExt, sFileBase;
		if (this.ext.length == 0) { return true; }
		strExt = objFileSys.GetExtensionName(sFile);
		sFileBase = objFileSys.GetFileName(sFile);
		for (i = 0; i < this.ext.length; i++) {
			if (strExt == this.ext[i]) {
				for (j = 0; j < this.remove.length; j++) {
					var o = new RegExp(this.remove[j]);
					if (o.test(sFileBase)) {
						return false;
					}
				}
				return true;
			}
		}
		return false;
	},
	addFile: function(sFile) {
		if (this.isTarget(sFile)) {
			this.files.push(sFile);
		}
		return true;
	},
	EnumFiles: function(sRootFolder) {
		if (objFileSys.FolderExists(sRootFolder)) {
			var objFolder = objFileSys.GetFolder(sRootFolder);
			this.EnumFiles1(objFolder);
		} else if (objFileSys.FileExists(sRootFolder)) {
			this.addFile(sRootFolder);
		}
	},
	EnumFiles1: function(objFolder) {
		var fc = new Enumerator(objFolder.files);
		for (fc.moveFirst(); !fc.atEnd(); fc.moveNext()) {
			this.addFile(fc.item());
		}
		var fc2 = new Enumerator(objFolder.SubFolders);
		for (fc2.moveFirst(); !fc2.atEnd(); fc2.moveNext()) {
			this.EnumFiles1(objFileSys.GetFolder(fc2.item()));
		}
	}
};

function Usage() {
	WScript.Echo("usage\ncmd /k cscript exgrep.js \"search_word\" \"folder_path\" ");
	WScript.Echo("cmd /k cscript exgrep.js -e \"search_pattern\" \"folder_path\" ");
}

	var WSHShell =  WScript.createObject("WScript.Shell");
	var sExePath = "\"" + GetScriptFolder() + "\\xdoc2txt.exe\"";
	var arg = WScript.arguments;
	var i = 1;
	var Match1;

	if (arg.count() < 2) { return Usage(); }
	var sGrep = arg.item(0);
	if (sGrep == "-e") {	//正規表現検索
		if (arg.count() < 3) { return Usage(); }
		i++;
		var oReg = new RegExp(arg.item(1));
		Match1 = function(sTest) { return oReg.test(sTest); }
	} else {				//通常検索
		Match1 = function(sTest) { return (sTest.indexOf(sGrep) > -1); }
	}

	for (; i < arg.count(); i++) {
		objFileList.init();
		objFileList.EnumFiles(arg.item(i));
		for (var j = 0; j < objFileList.files.length; j++) {
			var sFileName = objFileList.files[j];
			var outExec = WSHShell.exec(sExePath + " -i \"" + sFileName + "\"");
			var StdOut = outExec.StdOut;
			var nCount = 0;
			while (!StdOut.AtEndOfStream) {
				var sLine = StdOut.ReadLine();
				if (Match1(sLine)) {
					if (nCount == 0) {
						WScript.Echo("");
						WScript.Echo(sFileName);
					}
					WScript.Echo(sLine);
					nCount++;
				}
			}
			var StdErr = outExec.StdErr;
			while (!StdErr.AtEndOfStream) {
				WScript.Echo(StdErr.ReadLine());
			}
		}
	}

	WScript.Echo("");
	WScript.Echo("done.");
}());
```