マクロの概要(入門用) サブルーチンについて(Ver9.34対応版)
サブルーチンについて
秀丸マクロでは、「サブルーチン」を使うことができます。サブルーチンとは、前述のキーワードや関数のように、ある程度まとまった一連の処理を記述した独立したマクロで、
メインのマクロから呼び出し実行させます。キーワードと関数とサブルーチンは、メインのマクロから呼び出す方法が違うだけで、ほぼ同じ動作をすると考えるとわかりやすいかもしれません。
ただし、キーワードと関数は予め用意されていますが、サブルーチンは使用者の利用目的に合わせた独自のマクロをサブルーチンとして定義(作成)しなければなりません。
メインのマクロとは、マクロのスタートから終了までを管理し、おおまかな処理の制御(舵取り)を実行します。細かい処理などは、
サブルーチンを呼び出し補佐させるようします。このように処理を大きな処理の流れ(メインのマクロ)、小さな処理の流れ(サブルーチン)と分けて考え、
大きな処理の流れから、小さな処理の流れを呼び出すようなプログラミングを「構造化プログラミング」と呼びます。全ての処理を1つの大きなマクロ(プログラム)で記述するよりも小さくなる(短く記述できる)ので、
構造が簡単になり、マクロの視認性が高くなります。その結果、エラーが発生しにくく、またエラーが発生しても修正が容易になることと、特定の処理をする、
ある程度汎用的なサブルーチンは他のマクロにも再利用できるなどのメリットがあります。
では、具体的なサブルーチンの作成方法です。
サブルーチンの名前を決めます。処理の内容がわかるような名前をつけてください。
マクロに記述する方法はサブルーチン名:(コロン)です。
例 |
CountTotalWordNum:
//処理を記述します
return; //return文でメインのマクロに復帰します
|
次にメインのマクロからサブルーチンを呼び出す方法です。
call文を使用します。
例 |
call CountTotalWordNum;
|
このときのマクロの動作は、メインのマクロから「call CountTotalWordNum;」で、サブルーチン「CountTotalWordNum:」を呼び出しています。
よって、サブルーチン「CountTotalWordNum:」の一連の処理が終了するまで、メインのマクロは実行を停止しています。
サブルーチンの処理が終了したら「
return 」でメインのマクロに戻っていきますので、
call文で呼び出した次の行からマクロが再開します。
実際にテキストファイルの文字数を取得するメインのマクロとサブルーチンを例として記述します。
メインのマクロ側 |
call CountTotalWordNum; //call文でサブルーチンを呼び出す
message "ファイルの文字数は " + str(##return) + " 文字です";
endmacro; //この位置でマクロの実行を停止
|
上記のメインのマクロ側の処理を説明します。
呼び出したサブルーチン側で取得した文字数を「 ##return 」で受け取り、受け取った文字数は数値型なので「str」関数で文字列型に変換して表示しています。
サブルーチン側 |
CountTotalWordNum: //サブルーチンの定義
##cnt = 0; //変数初期化
##cur_x = x;##cur_y = y; //現在のカーソル位置を代入
disabledraw;
movetolineno 1,1;
while( code != eof ){ //ファイルの終わりまで繰り返し
if (( code != 0x0D) && ( code != 0x20) && ( code != 0x8140) && ( code != 0x09)){
//改行、タブ、全角と半角スペース以外なので文字数にカウントする
##cnt = ##cnt + 1;
right;
}else{ //改行、タブ、全角と半角スペースなのでカウントしない
right;
}
}
moveto ##cur_x,##cur_y; //カーソルを元の位置に戻す
enabledraw;
return ##cnt; //カウントした文字数を戻り値とする
|
上記のサブルーチン側の処理を詳細に説明します。
##cnt = 0;は、文字数を格納する数値変数に0(ゼロ)を入れて初期化します。
##cur_x = x;##cur_y = y;は、現在のカーソル位置を代入します。
disabledraw;は、画面の書き換えを禁止します。そのために処理速度が上がります。
movetolineno 1,1;は、カーソルを最初の文字に移動します。
while文はcode != eof(ファイルの末尾)になるまで繰り返し実行されます。
while文のif文で使用している文字コードの意味は、下記のとおりです。
code == 0x0Dは改行です。よってcode != 0x0Dは改行でない。
code == 0x20は半角スペースです。よってcode != 0x20は半角スペースでない。
code == 0x8140全角スペースです。よってcode != 0x8140は全角スペースでない。
code == 0x09はタブです。よってcode != 0x09はタブでない。
if文の条件式は、「改行でない」かつ「タブでない」かつ「全角スペースでない」かつ「半角スペースでない」ときは真になります。よって、真の場合は文字数にカウントし、偽の場合はカウントしません。
right;は、カーソルを右へひとつ移動させます。
ファイルの末尾でwhile文から抜け出ると、moveto ##cur_x,##cur_y;でカーソルを最初の位置に戻します。
enabledraw;は、画面書き換えを許可するに戻します。
上記の例ではサブルーチンからメインのマクロに戻り値を返しています。戻り値は文字列型、数値型のどちらでも返せますが、返せる個数(変数数)はひとつだけです。
メインのマクロで数値型なら「
##return 」、文字列型なら「
$$return 」で受け取ります。
この場合、数値型を文字列型で受け取とったり、逆に文字列型を数値型で受け取とったりするとエラーが発生しますので、変数の型に気をつけてください。また、戻り値はローカル変数です。
逆にメインのマクロからサブルーチンを呼び出すときには、関数のようにパラメータ(引数)を渡すことができます。文字列型、数値型のどちらでも組み合わせて複数個渡せます。
書式
call サブルーチン名[パラメータ1,パラメータ2,・・・]
「 [ ] 」は省略できるという意味です(「 [ ] 」は記述の必要はありません)。
「 ・・・ 」は複数個を意味します。
例 |
call QuestionSub #lineno,$str_before,$srt_after,"置換しますか?";
|
受け取ったサブルーチンでは、渡されたパラメータを以下のようなローカル変数で参照することができます。
1番目のパラメータ(文字列型の場合):$$1
1番目のパラメータ(数値型の場合):##1
2番目のパラメータ(文字列型の場合):$$2
2番目のパラメータ(数値型の場合):##2
以下同様・・・
上記の例では、以下のようになります。
#linenoは「##1」
$str_beforeは「$$2」
$srt_afterは「$$3」
"置換しますか?"は「$$4」でサブルーチン内で参照できます。
パラメータの受け取り方をマクロの記述で表示します。
メインのマクロ側 |
#lineno = 25;
$str_before = "サイトウ";
$srt_after = "斉藤";
call QuestionSub #lineno,$str_before,$srt_after,"置換しますか?";
if(##return ){
beep; //「はい」ボタンが押されたら音を鳴らす
//ここに置換するマクロを記述します
}
endmacro; //この位置でマクロの実行を停止
|
サブルーチン側 |
QuestionSub: //サブルーチンの定義
question str(##1) + "行にある「"+ $$2 + "」を「" + $$3 + "」に" + $$4;
return result; //「はい」「いいえ」どちらのボタンが押されたかを戻り値とする
|
上記のサブルーチン側の処理を説明します。
受け取った文字数は数値型なので「str」関数で文字列型に変換し表示するメッセージを組み立てます。よって、表示されるメッセージは「25行にある「サイトウ」を「斉藤」に置換しますか?」となります。そのメッセージと「はい」「いいえ」かのダイアログボックスを表示します。
- ローカル変数
-
サブルーチン内でしか参照できない変数をローカル変数といいます。ローカル変数は変数を意味する#または$がふたつ変数名の前につきます。メインのマクロからサブルーチンを呼んだときに渡すパラメータはローカル変数でないと利用できません。また、サブルーチンからの戻り値もローカル変数でないと利用できません。
- サブルーチンからサブルーチンを呼び出す場合
-
callされたサブルーチンからさらにサブルーチンを呼ぶこともできます。最高20回程度重複可能です。