読者です 読者をやめる 読者になる 読者になる
スポンサーリンク

Excelブック内の全シートを,1ファイルずつに分けて一括保存するバッチ (シート単位で自動ファイル分割し,1シートごとに一斉ファイル出力)

単一のExcelブック内に,大量のワークシートが存在するとする。


シートがあまりにも多すぎて,ブックのサイズが何メガにも膨れ上がる。

そして,「もはや1ファイルで管理しきれない。

シートごとに別ファイルに分けよう」となる。


そういう場合,各シートを

「自動的に個別のファイルに分けてくれる」ツールがあると便利だ。

100シートあれば,100個のファイルに分割してくれる・・・というわけ。



下記のバッチで,すぐに実行できる。


以下のコードをメモ帳にコピペし,「シートごとに分割.bat」で保存。

そして,シートごとに分割したいExcelファイルを

このバッチにドロップすればよい。

@if(0)==(0) ECHO OFF

cscript.exe //nologo //E:JScript "%~f0" %*

@pause
GOTO :EOF
@end



/*

	ドロップしたExcelファイルの全シートを,
	1シートずつ個別のファイルに保存し直すバッチ

*/


// 引数取得
if( WScript.Arguments.length == 0 )
{
	WScript.Echo("引数がありません。");
	WScript.Quit();
}
var filename = WScript.Arguments.Unnamed(0);
var ws = WScript.CreateObject("WScript.Shell");
var cwd = ws.CurrentDirectory;
//var filepath = cwd + "\\" + filename;
var filepath = filename;



// Excelブックを開く
var excel = WScript.CreateObject("Excel.Application");
excel.Visible = true;
excel.Workbooks.Open( filepath );
var book = excel.Workbooks( excel.Workbooks.Count ); // ワークブックを取得
var xlMaximized = -4137;
excel.ActiveWindow.WindowState = xlMaximized; // 最大化




// 全シートをスキャンして,シート名を調査
var sheets = book.WorkSheets;
var e = new Enumerator( sheets );
var arr_sheets = [];
for( ; ! e.atEnd() ;  e.moveNext() )
{
	// シートを取得
	var sheet = e.item();
	
	// 保持
	arr_sheets.push( sheet );
	
}


// 取得済みの全シートについて
for( var i = 0; i < arr_sheets.length; i ++ ){

	// 新規ワークブックを作成
	excel.Workbooks.Add();
	var new_book = excel.Workbooks( excel.Workbooks.Count ); // ワークブックを取得

	// シートを先頭にコピー挿入
	//arr_sheets[i].Copy( new_book.Worksheets( new_book.Worksheets.Count ) );
	arr_sheets[i].Copy( new_book.Worksheets( 1 ) );
	
	// 不要シートを消す(Sheet1~Sheet3)
	new_book.Worksheets( 4 ).Delete();
	new_book.Worksheets( 3 ).Delete();
	new_book.Worksheets( 2 ).Delete();

	// 新規ファイル保存。ファイル名はシート名
	var new_filepath = cwd + "\\" + arr_sheets[i].Name + ".xlsx";
	WScript.Echo( "新規ブックのパス:" + new_filepath );
	new_book.SaveAs( new_filepath );
	
	// 閉じる
	new_book.Close();

}


このソースは,MS-DOS(コマンドプロンプト)バッチの中に,WSH/JScriptのコードを埋め込んで記述してある。


Excelファイルをドロップすると,バッチの存在するフォルダ内に,

各シートごとに分割されたエクセルが一斉に生成・保存される。


参考にしたページ:

JScript/WSH で,Excelファイルを読み書きしよう
http://language-and-engineering.hatenablog.jp/entry/20090717/p1


Excelブックの「シート目次」を,自動的に作成するバッチ (WSH/JScriptで,各シートへのリンク付きの目次を自動生成)
http://language-and-engineering.hatenablog.jp/entry/20110921/p1


BATとWSHのコードを1ファイルに混在させるためのshebang記法(複雑なバッチを1ファイルで実現)
http://computer-technology.hateblo.jp/entry/20131025/p1

関連する記事:

WSH/JScriptで,Excelファイルを読み書きする際のテンプレート (シート上の全行を読み書きするコードのひな型) - 主に言語とシステム開発に関して
http://language-and-engineering.hatenablog.jp/entry/20140214/p1


ドキュメント作成を楽にするための,Excel VBA 頻出8パターン - 主に言語とシステム開発に関して
http://language-and-engineering.hatenablog.jp/entry/20090401/p1


Excelシートを読み取って,INSERT文SQLを生成するバッチ (Kingsoft SpreadsheetをWSH/JScriptで自動操作) - 主に言語とシステム開発に関して
http://language-and-engineering.hatenablog.jp/entry/20121218/p1


Excel VBAのマクロを,複数のブックから利用する方法 (標準モジュールをブックの外部で管理して,共通ライブラリとして読み込み) - 主に言語とシステム開発に関して
http://language-and-engineering.hatenablog.jp/entry/20090731/p1

JavaScriptの動かないコード(中級編)正規表現をwhile内で定義すると無限ループで固まるエラー (execでグローバルなマッチだと,処理がフリーズ)


以下のJavaScriptコードが,意図した動作をしないのは,なぜですか。(制限時間1分)


やりたい事:

  • 複数の文字列がある。
  • それぞれの文字列から,URLのトップレベルドメイン(TLD)を全て抜き出す。
  • 抽出のために,RegExp.exec() メソッドで,正規表現にグローバルオプションを付けて実行する。
<script>

// 検索対象の文字列たち
var strs = [
	"URLは,http://a.com/ と,https://b.jp/ です。よろしくね。",
	"どうぞhttp://c.com/においで下さい。",
	"http://d.jp/ から移転しました。こちら→https://e.info/ "
];


/*
  マッチするすべてのTLDを列挙
*/


// 検索対象のすべての文字列を,順番に検査する。
for( var i = 0; i < strs.length; i ++ ){

	// この一つの文字列の中に含まれる
	// 全てのTLDを抽出。
	var str = strs[i];


	// execメソッドが値を返し続ける限り,
	// whileでループを回し続ける。
	var arr;
	while( 
		( 
			// execの結果は毎回,配列として受け取る。
			arr = (
				// 正規表現にgオプションを付け,
				// 文字列内で複数回マッチさせる。
				/https?:\/\/[^\/]+\.([^\.\/]+)/g
			).exec( str ) 
		)
		!=
		null
	){

		// 括弧でキャプチャした文字列を表示
		alert( "トップレベルドメインは" + arr[1] );

	}


}


</script>


発生する不具合

続きを読む

JavaScriptの動かないコード(中級編) 正規表現の括弧キャプチャを,グローバルで繰り返しmatchできない (gオプションを付けると部分文字列の抽出が無効)


以下のJavaScriptコードが,意図した動作をしないのは,なぜですか。(制限時間1分)


やりたい事:

  • (試行1)では,文字列からトップレベルドメインを1つだけ抽出する。
    • これは上手くいく。
  • (試行2)では,文字列からトップレベルドメインを全て抽出する。
    • これは正常に動作しない。なぜなのか。

<script>

// 元の文字列
var str = "URLは,http://a.com/ と,https://b.jp/ です。よろしくね。";


/*
  (試行1)
  正規表現にgオプションを付けず,
  情報を1個だけ抽出してみる。
*/


// トップレベルドメインを抜き出す。
var m;
m = str.match( new RegExp( "https?://[^\\/]+\\.([^\\.\\/]+)/" ) );

	// httpとhttpsの両方に対応。
	// ドメイン名の最後の部分だけを,カッコで抜き出す。
	// つまり,ドメイン中の最後のドット以降の文字列を抜き出す。


// 配列の0番目には,マッチした文字列全体が入っている。
//alert( m[0] );  =>  "http://a.com/"

// 配列の1番目には,括弧でキャプチャした部分が入っている。
alert( "トップレベルドメインは" + m[1] );  // => "com"



/*
  (試行2)
  正規表現にgオプションを付けて,
  マッチした情報を全て抽出してみる。
*/


// 正規表現にgオプションを付ける。
m = str.match( new RegExp( "https?://[^\\/]+\\.([^\\.\\/]+)/", "g" ) );

// 括弧でキャプチャした部分を2つとも表示。
alert( "1つ目にマッチしたトップレベルドメインは" + m[1] );
alert( "2つ目にマッチしたトップレベルドメインは" + m[2] );


</script>

発生する不具合

続きを読む