はじめに
こんにちは、麻菜結と申します。
この記事は2025年になってもまだ滅びないJScriptについて、リファレンスとユースケースを示しつつ情報をまとめたものです。
基本的には実際に動かしてできたものを載せますが、お手元で実行する場合にはちゃんと動くか試してください。
環境
> cscript /?
Microsoft (R) Windows Script Host Version 10.0
Copyright (C) Microsoft Corporation. All rights reserved.
以降省略
ファイル操作系
var fs = new ActiveXObject('Scripting.FileSystemObject');
fs = null; // 使い終わったら解放。
var s = new ActiveXObject("ADODB.Stream");
s = null;
こちらのサイトが一番詳しくわかりやすいと思います。
また、任意のエンコードでテキストを修正したい場合はこちら。
以上のサイトに書いてあることがほとんどなので、ここで示すユースケースはありません。
エクセル
var excel = new ActiveXObject('Excel.Application');
excel.Visible = false; // これをtrueにするとエクセルのウィンドウが立ち上がり操作が表示される
excel = null;
このexcelオブジェクトはWorkbooksプロパティを持っています。
ここからWorkbookオブジェクトをつくり、ワークシートを取り出せばエクセルでやりたいことのほとんどができます。
以下の例で示したXXXオブジェクトはリファレンスの同名のものと対応していますので、詳細はリファレンスをどうぞ。
var workbook = excel.Workbooks.Add(); // Workbookオブジェクトの新規作成
var sheet = workbook.Sheets.Add(); // Worksheetオブジェクトの作成
sheet.Cells(1, 1).Value = 'hello'; // セルA1を示すRangeオブジェクトの値に'hello'を設定
workbook.SaveAs('test.xlsx'); // 名前を付けて保存
workbook.Save(); // 変更の上書き保存
workbook.Close(); // Workbookオブジェクトを閉じる。
JScriptの情報が乏しい中でエクセル操作の情報を探すコツとしては、世にあるVBAのソースコードをJScriptに翻訳することです。
以上のようにまずWorksheetオブジェクトを取得し、そこにはRangeなどがメソッドとして生えているので、後はVBAを読んで何とかしましょう。
以降は実際のユースケースです。
セルの結合
JScriptでは、RangeはRange("A1:C3")のように書きません。2つの引数として書きます。
sheet.Range('A1', 'C3').Merge();
またCellsをつかって以下のようにも書けます。
sheet.Range(sheet.Cells(1, 1), sheet.Cells(3, 3)).Merge();
プログラムとして扱う上では、おそらく後者の方が扱いやすいのではないでしょうか。
ちなみに、Cells(行, 列)です。Rangeと逆なのでお気をつけてください。
列/行を最適な幅にする
Columns/RowsプロパティのAutoFitメソッドを使います。
sheet.Columns(1).AutoFit();
sheet.Rows(1).AutoFit();
AutoFitは現在の表示に対していい感じに表示する機能であり、実は変更前の列/行の幅によってAutoFit後の幅が異なります。
「文字列が多いので折り曲げて次の行に表示している部分を、AutoFitで改行無しにして欲しいのに上手くいかない」といった場合は、まず列/行を最大まで大きくしてからAutoFitをかけるとよいかもしれません。
sheet.Columns(1).ColumnWidth = 254.88;
sheet.Columns(1).AutoFit();
sheet.Rows(1).RowHeight = 409.5;
sheet.Rows(1).AutoFit();
色をつける
色を付けたいものとして、代表的なものを集めました。
sheet.Tab.Color // シートのタブ
sheet.Cells(1, 1).Interior.Color // セルの背景
sheet.Cells(1, 1).Font.Color // セルの文字色
さて、色を付ける場合にはこのプロパティに設定すればよいのですが、JScriptでRGB関数を用いる方法が良くわかりません。(誰か知っていたら教えてほしい。)
なので、カラーコードを16進数形式で指定して対応する整数値を返す関数を作成しました。
良ければお使いください。
function ColorCode(color16Exp){
if (!color16Exp) {
return null;
}
var color = 0;
var R = parseInt(color16Exp.substring(1, 3), 16);
var G = parseInt(color16Exp.substring(3, 5), 16);
var B = parseInt(color16Exp.substring(5, 7), 16);
color += R;
color += G << 8;
color += B << 16;
return color;
}
sheet.Tab.Color = ColorCode('#FF0000');
sheet.Cells(1, 1).Interior.Color = ColorCode('#1F1F1F');
sheet.Cells(1, 1).Font.Color = ColorCode('#FFFFFF');
画像をセルに配置する
エクセルには画像をセル内にぴたっと収める機能があります。
JScriptでエクセルに画像をいい感じに配置することは結構いばらの道なのですが、セルに配置機能を用いれば楽できる場合があります。
var shape = sheet.Shapes.AddPicture('image.png', 0, -1, 0, 0, -1, -1); // シートに画像を追加
shape.Top = sheet.Cells(1, 1).Top; // 置きたいセルの上を合わせる
shape.Left = sheet.Cells(1, 1).Left; // 置きたいセルの左を合わせる
shape.Select(); // 画像を選択
shape.PlacePictureInCell(); // 画像をセル内に配置
画像編集
var img = new ActiveXObject('WIA.ImageFile');
var ip = new ActiveXObject('WIA.ImageProcess');
ip = null;
img = null;
Windowsには標準の機能として画像をいじる機能、Windows Image Acquisitionというものがありますので、そちらを使います。
imgオブジェクトのリファレンスはこちら、ipオブジェクトはipオブジェクトはこちらです。
どんな編集ができるかは、このページを見るのが良いでしょう。
画像を切り取る
サンプルにある上下左右をトリミングするものです。
img.LoadFile('image1.png');
ip.Filters.Add(ip.FilterInfos('Crop').FilterID);
ip.Filters(1).Properties('Left').Value = img.Width / 4;
ip.Filters(1).Properties('Top').Value = img.Height / 4;
ip.Filters(1).Properties('Right').Value = img.Width / 4
ip.Filters(1).Properties('Bottom').Value = img.Height / 4
img = ip.Apply(img);
img.SaveFile('image2.png');
画像のリサイズ
画像のリサイズもできるそうです。toshi様の記事を紹介いたします。
Wscript
Wscript
一定時間のスリープ
WScriptオブジェクトのSleepメソッドを使います。
WScript.Sleep(1000);
実行時のコマンドライン引数
WScriptオブジェクトのArgumentsメソッドを使います。
以下にコマンドライン引数を配列で返す関数を示します。
function getArgs(){
var arg = WScript.Arguments;
var args = [];
for (var i = 0; i < arg.length; i++) {
args.push(arg(i));
}
return args;
}
シェル操作
var shell = new ActiveXObject('WScript.Shell');
shell = null;
手っ取り早くコマンドを実行したい人はクジラ机様の記事をどうぞ。
おわりに
おつかれさまです。
勉強し蓄積した暗黙知をどこかに置いておきたいという気持ちで記事を作成しましたが、とても良いですね。
皆さんも日ごろ学んだ内容をまとめて全世界に大っぴらにしてみてはいかがでしょうか。
ここまで読んでいただき、ありがとうございました。