HOKKAPOKKA
@HOKKAPOKKA (HOKKA POKKA)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Windows10のコマンドラインから、cscriptを使って特定のフォルダにあるエクセルファイルを全部PDF化したい

解決したいこと

Windows10のコマンドラインから、cscriptを使って特定のフォルダにあるエクセルファイルを全部PDF化したい

素人ながらいろいろなブログを参照して、以下のようなスクリプト(.jsファイル)を試作してみましたが、うまく行きません。
jsファイルはc:\tempに置きました
複数のエクセルファイルはc:\temp2 に置きました。
以下のようなコマンドを発行しましたが、プロンプトがロックされたままでうんともすんとも行きません。
cscript c:\temp\test.js c:\temp2\

c:\temp2は1階層で、サブフォルダはありません。
他からいただいたスクリプトなので、本来不要な部分があると思いますが、見分けがつかないのです。それともコマンドのパラメーター表現が悪いのでしょうか。

該当するソースコード (test.js)

var args = WScript.Arguments;
var rootDir = args.Unnamed(0);
var wsh = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

// folderPath以下をトラバースしてファイル名をかき集める
function CheckFolder(filePathAry, folderPath, collectFunctor) {
var folderObj = fso.GetFolder(folderPath);

// ファイル名列挙
var files = new Enumerator(folderObj.Files);
for (; !files.atEnd(); files.moveNext()) {
    var filePath = fso.GetAbsolutePathName(files.item());
    if (collectFunctor(filePath) == true)
        filePathAry.push(filePath);
}

// サブフォルダへ
var folders = new Enumerator(folderObj.SubFolders)
for (; !folders.atEnd(); folders.moveNext()) {
    CheckFolder(filePathAry, folderPath + "\\" + folders.item().Name, collectFunctor);
}

}

// 取得フィルター
// 全部集める
function nullFunctor(filePath) {
return true;
}

// 特定拡張子のみ
function extFunctor(filePath) {
var extArray = ["xlsx"];
var ext = fso.GetExtensionName(filePath);
for (var i = 0; i < extArray.length; i++)
if (ext == extArray[i])
return true;
return false;
}

// カレントディレクトリ取得
var rootDir = wsh.CurrentDirectory;
var filePathAry = new Array;
CheckFolder(filePathAry, rootDir, extFunctor); // <- Fuctorでフィルター掛けられます

// 収集したファイルフルパスチェック
for (var i = 0; i < filePathAry.length; i++)
WScript.Echo(filePathAry[i]);

{
var file = filePathAry[i];
xls2pdf(file, file + ".pdf");
}

function xls2pdf(infile, outfile) {
var excel = null;
try {
// Excelオブジェクト生成
excel = new ActiveXObject("Excel.Application");
var book = null;
try {
// 読み取り専用で開く
book = excel.Workbooks.Open(infile, 0, true);
// PDF出力(xlTypePDF(0)、出力ファイル、xlQualityStandard(0))
book.ExportAsFixedFormat(0, outfile, 0);
} catch (e) {
// エラーの場合
WScript.Echo("IN:" + infile + "\nOUT:" + outfile
+ "\nError(" + (e.number & 0xFFFF) + "):" + e.message);
} finally {
// Workbookオブジェクト存在チェック
if (book != null) {
// Workbookを閉じる
book.Close(false);
book = null;
}
}
} catch (e) {
// エラーの場合
WScript.Echo("IN:" + infile + "\nOUT:" + outfile
+ "\nError(" + (e.number & 0xFFFF) + "):" + e.message);
} finally {
if (excel != null) {
excel.Quit();
excel = null;
}
}
}

0

1Answer

手元の環境で実行してみました(一部文法エラーを修正しました)が、特に問題なく動作しました。
おそらくExcelでブロックされているのではないかと思います。
ワークブックを開く際にパスワードがかかっていたり、警告が表示されて足りする場合にパスワードが入力されるまでブロックされたり、メッセージボックスを閉じるまでブロックされたりします。
裏でExcelが表示されていたりしませんか?(表示されていない場合、excel.Visible = trueで表示できるはずです)
Workbooks.Openの引数を変えたり、ワークブックを開く前にexcel.DisplayAlerts = falseで警告表示を無効化することで解消できる場合もあります。

ここからは余計なお世話ですので読み飛ばしてOKです。
cscriptwscriptWSH(Windows Scripting Host)の実行エンジンです。
WSHは下位互換のために残されていますが、Microsoftの公式ドキュメントから削除されているほど古い技術なので新たに利用するのはお勧めできません。
同様のスクリプト技術ではPowerShellで同じことが出来るので新たにスクリプトを作成するのであればPowerShellをお勧めします。

1Like

Comments

  1. @HOKKAPOKKA

    Questioner

    ありがとうございます。(Qiita初心者なのですが、ここからreplyするんでしょうか?)
    そちらでは動いたのですね。私は2つのパソコンで両方とも同じ現象なので、凹んでおりますが、
    御指南いただいた内容を試してみます。

  2. @mrbonjin さんのご指摘通りと思います。

    Workbooks.Openの引数にUpdateLinks:=0,ReadOnly:=Trueを指定しているので、パスワードが一番怪しいと思います。

    普通にExcelから該当のファイルを開いた時に、パスワード入力は求められないでしょうか?
    もしパスワードがかかっているなら、Workbooks.Openの引数に,Password:="xxxxx"の追加が必要です。

    また、複数のファイルが対象ということですが、一つ二つでもPDFが作成できたファイルがあるのでしょうか?

    あと、入力ファイルのフォルダにPDFファイルを出力しているように見えますが、PDFファイルを入力対象から外す制御(ファイル拡張子によるフィルタ)は正しく機能しているのでしょうか? ちょっと気になりました。


    もし、解決済みならCloseして読み捨ててください。
    @mrbonjin さんへ、『手元の環境で実行してみました(一部文法エラーを修正しました)が、特に問題なく動作しました』ときのコード全体をここに掲示して頂くことは可能でしょうか? お手数でなければ、よろしくお願いします。

Your answer might help someone💌