last updated:2023/12/27
マクロ実行中に別のマクロを呼び出す方法として execmacro文 があります。
処理を分けるという意味ではサブルーチンと似ていますが、呼び出し元とファイルが別になっている事と変数のスコープが異なります。
サブルーチンは呼び出し元と同じマクロ内に存在するため、呼び出し元マクロのグローバル変数にアクセスできます。
execmacro 文 で呼び出した場合は呼び出し元のグローバル変数にはアクセスできず、別の変数として扱われます(文字変数に限定されるが、代替え手段あり)。
呼び出し元で、「$a」 を設定しても、
// check.mac
$a = currentmacrobasename
execmacro "check1.mac";
endmacro;
呼び出されたマクロ側では参照できません。別の変数として扱われます。
// check1.mac
message $a;
endmacro;
サブルーチンのほうが便利そうですが、修正があった場合は同じ処理をしている箇所を探し出し修正しないといけません。 execmacro 文を使って呼び出している場合は、ひとつのファイルを修正するだけで済みます。
また、Ver.8以降だとサブルーチンと同様に引数も指定(文字列限定)できます。
注意事項もあるので、ヘルプのexecmacro文を一読しましょう。
execmacro 文は、引数に実行したいマクロファイルと、マクロに渡す引数を指定します。マクロに渡す引数は省略可能です。
execmacro "check1.mac", "arg1", "arg2";
マクロファイルの指定方法
フルパスでマクロを指定しない場合の認識は以下になります。
「マクロフォルダ」直下にあるマクロを指定する場合以外は、フルパスで指定するようにしましょう。
マクロフォルダからの相対パスにする場合は、macrodir キーワードを使用します。
execmacro macrodir + @"\folder\check1.mac";
実行中のマクロからの相対パスにする場合は、currentmacrodirectory キーワードを使用します。
execmacro currentmacrodirectory + @"\folder\check1.mac";
開いているファイルからの相対パスにする場合は、directory キーワードを使用します。
execmacro directory + @"\folder\check1.mac";
引数を指定する場合は、マクロファイル名の後に引数を指定します。最大で31個まで指定出来ます。
execmacro "check1.mac", "arg1", "arg2", "arg3", … "arg31";
配列を引数に指定できます。配列名と配列サイズを指定します。
$array[0] = "arg1";
$array[1] = "arg2";
$array[2] = "arg3";
execmacro "check1.mac", $array, 3;
execmacro 文から呼び出されたマクロ側で、引数が指定されているか確認する方法です。
argcount キーワードが 0 だと引数は指定されていないことになります。
debuginfo 2;
if(argcount > 0){
#max = argcount;
#n = 0;
while(#max > #n){
debuginfo sprintf("1:getarg(%d)=%s\n", #n, getarg(#n));
#n = #n + 1;
}
}else{
debuginfo "引数無し";
}
getarg関数で得られる内容、argcountキーワードの値は、状況により書き換えられたりします。 execmacro 文から引数付きでマクロを呼び出し、元のマクロに戻っても内容が復元されることはありません。
必要に応じて、argcountキーワードの値やgetargで取得できる内容を変数に保持しておくのがいいでしょう。
値が書き換えられるケース。
動作確認用マクロ1 test_arg.mac
//test_arg.mac
debuginfo 2;
execmacro "test_arg1.mac", "chk1-1", "chk1-2", "chk1-3";
endmacro;
動作確認用マクロ2 test_arg1.mac
//test_arg1.mac
//debuginfo 2;
#max = argcount;
#n = 0;
debuginfo sprintf("1:argcount=%d\n", #max);
while(#max > #n){
debuginfo sprintf("1:getarg(%d)=%s\n", #n, getarg(#n));
#n = #n + 1;
}
execmacro "test_arg2.mac", "chk2-1";
#max = argcount;
#n = 0;
debuginfo sprintf("3:argcount=%d\n", #max);
while(#max > #n){
debuginfo sprintf("3:getarg(%d)=%s\n", #n, getarg(#n));
#n = #n + 1;
}
endmacro;
動作確認用マクロ3 test_arg2.mac
//test_arg2.mac
//debuginfo 2;
#max = argcount;
#n = 0;
debuginfo sprintf("2:argcount=%d\n", #max);
while(#max > #n){
debuginfo sprintf("2:getarg(%d)=%s\n", #n, getarg(#n));
#n = #n + 1;
}
endmacro;
動作確認用マクロ1 "test_arg.mac" を実行すると、以下の内容がアウトプット枠に出力されます。
1:argcount=3
1:getarg(0)=chk1-1
1:getarg(1)=chk1-2
1:getarg(2)=chk1-3
2:argcount=1
2:getarg(0)=chk2-1
3:argcount=1
3:getarg(0)=chk2-1
execmacro 文を使っていないけど、値が読み込めなくなるケース。
動作確認用マクロ4 test_arg3.mac
//test_arg3.mac
debuginfo 2;
execmacro "test_arg3.mac", "chk1-1", "chk1-2", "chk1-3";
endmacro;
動作確認用マクロ2 test_arg1.mac
//test_arg4.mac
#max = argcount;
#n = 0;
$debug = "";
$debug = $debug + sprintf("1:argcount=%d\r\n", #max);
while(#max > #n){
$debug = $debug + sprintf("1:getarg(%d)=%s\r\n", #n, getarg(#n));
#n = #n + 1;
}
#main = hidemaruhandle(0);
newfile;
#sub = hidemaruhandle(0);
#max = argcount;
#n = 0;
$debug = $debug + sprintf("2:argcount=%d\r\n", #max);
while(#max > #n){
$debug = $debug + sprintf("2:getarg(%d)=%s\r\n", #n, getarg(#n));
#n = #n + 1;
}
setactivehidemaru #main;
closehidemaruforced #sub;
#max = argcount;
#n = 0;
$debug = $debug + sprintf("3:argcount=%d\r\n", #max);
while(#max > #n){
$debug = $debug + sprintf("3:getarg(%d)=%s\r\n", #n, getarg(#n));
#n = #n + 1;
}
//アウトプット枠へ出力
//「test_arg4.mac」で「debuginfo 2;」を実行していないが、debuginfoの出力モードはexecmacro文の実行でも伝搬される。
//その為、「test_arg3.mac」で実行しているので問題ない。
debuginfo $debug;
endmacro;
動作確認用マクロ1 "test_arg3.mac" を実行すると、以下の内容がアウトプット枠に出力されます。
1:argcount=3
1:getarg(0)=chk1-1
1:getarg(1)=chk1-2
1:getarg(2)=chk1-3
2:argcount=0
3:argcount=3
3:getarg(0)=chk1-1
3:getarg(1)=chk1-2
3:getarg(2)=chk1-3
getarg関数で得られる内容、argcountキーワードの値のスコープは、マクロを呼び出した秀丸エディタのみになります。
execmacro 文で実行したマクロから戻り値を設定出来ます。
文字列のみで、数値は指定できません。
戻り値を設定するには、endmacro 文に引数を指定します。
//test_return.mac
endmacro currentmacrobasename + "を実行しました。";
戻り値を受け取るには、getresultex 関数を使います。
execmacro "test_return.mac";
message "戻り値:" + getresultex(-1);
戻り値を設定出来るのは1つだけです。
文字列限定ですが、マクロ間で変数を共有する方法はあります(秀丸エディタ Ver.8以降)。
マクロ間で変数を共有するには、「静的な変数」を使います。「静的な変数」の詳細は、第III部〜秀丸マクロのいろはにほへと 静的な変数について を参照してください。
execmacro文の他に、秀丸エディタの起動オプションを使って指定する方法もあります。
詳細は 秀丸エディタヘルプ - 秀丸エディタ起動時のオプション を参照してください。
execmacro 文は外部のファイルを都度読み込むため時間がかかります。ループ内で使うと顕著です。
setcompatiblemode 文を使えば、高速化する場合もあります。詳細は、第III部〜秀丸マクロのいろはにほへと setcompatiblemode文 について を参照してください。