＞秀丸マクロのいろはにほへと

# 第III部〜秀丸マクロのいろはにほへと
マクロから別のマクロを実行する方法

## マクロから別のマクロを実行する方法

- はじめに
- execmacro文の使い方
- 引数を受け取る
- 戻り値を戻す/受け取る
- 変数の共有
- 補足

### はじめに

マクロ実行中に別のマクロを呼び出す方法として execmacro文 があります。

処理を分けるという意味ではサブルーチンと似ていますが、呼び出し元とファイルが別になっている事と変数のスコープが異なります。

- サブルーチンは呼び出し元と同じマクロ内に存在するため、呼び出し元マクロのグローバル変数にアクセスできます。

- execmacro 文 で呼び出した場合は呼び出し元のグローバル変数にはアクセスできず、別の変数として扱われます(文字変数に限定されるが、代替え手段あり)。

  呼び出し元で、「$a」 を設定しても、

      // check.mac
      $a = currentmacrobasename
      execmacro "check1.mac";
      endmacro;

  呼び出されたマクロ側では参照できません。別の変数として扱われます。

      // check1.mac
      message $a;
      endmacro;

サブルーチンのほうが便利そうですが、修正があった場合は同じ処理をしている箇所を探し出し修正しないといけません。 execmacro 文を使って呼び出している場合は、ひとつのファイルを修正するだけで済みます。

また、Ver.8以降だとサブルーチンと同様に引数も指定(文字列限定)できます。

注意事項もあるので、ヘルプのexecmacro文を一読しましょう。

### 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";

  - execmacro 文で実行する前に、existfile関数で対象マクロファイルが存在しているか確認しましょう。

        $macrofile = currentmacrodirectory + @"\folder\check1.mac";
        //実行するマクロファイルを事前に確認
        if(!existfile($macrofile)){
            message $macrofile + "が見つかりません。";
            endmacro;
        }
        execmacro $macrofile;

- 引数を指定する場合は、マクロファイル名の後に引数を指定します。最大で31個まで指定出来ます。

      execmacro "check1.mac", "arg1", "arg2", "arg3", … "arg31";

  配列を引数に指定できます。配列名と配列サイズを指定します。

      $array[0] = "arg1";
      $array[1] = "arg2";
      $array[2] = "arg3";
      execmacro "check1.mac", $array, 3;

### 引数を受け取る方法

execmacro 文から呼び出されたマクロ側で、引数が指定されているか確認する方法です。

- 指定された引数の個数は、argcount キーワードで取得可能。
- 引数自体は、getarg 関数で取得できる。

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

値が書き換えられるケース。

- 動作確認用マクロ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

1. "test_arg.mac" から "test_arg1.mac" を 引数付きで呼び出し。
2. "test_arg1.mac" から "test_arg2.mac" を引数付きで呼び出し。
3. "test_arg2.mac" から "test_arg1.mac" に復帰しても、呼び出す前には戻らない。

#### 動作確認その2

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

1. "test_arg3.mac" から "test_arg4.mac" を 引数付きで呼び出し。
2. "test_arg4.mac" から 新しい秀丸エディタを開く。
3. 新しい秀丸エディタからは、argcountキーワードは 0(zero)を返す。
4. 新しい秀丸エディタから戻っても、getarg関数で得られる内容/argcountキーワードの値は書き換えられていない。

getarg関数で得られる内容、argcountキーワードの値のスコープは、マクロを呼び出した秀丸エディタのみになります。

### 戻り値を戻す/受け取る

execmacro 文で実行したマクロから戻り値を設定出来ます。

文字列のみで、数値は指定できません。

- 戻り値を設定するには、endmacro 文に引数を指定します。

      //test_return.mac
      endmacro currentmacrobasename + "を実行しました。";

- 戻り値を受け取るには、getresultex 関数を使います。

      execmacro "test_return.mac";
      message "戻り値:" + getresultex(-1);

戻り値を設定出来るのは1つだけです。

### 変数の共有

文字列限定ですが、マクロ間で変数を共有する方法はあります(秀丸エディタ Ver.8以降)。

マクロ間で変数を共有するには、「静的な変数」を使います。「静的な変数」の詳細は、第III部〜秀丸マクロのいろはにほへと　静的な変数について を参照してください。

### 補足

#### execmacro文以外で引数付きでマクロを実行する方法

execmacro文の他に、秀丸エディタの起動オプションを使って指定する方法もあります。

- /x で実行するマクロ /a で引数を指定を指定。

詳細は 秀丸エディタヘルプ - 秀丸エディタ起動時のオプション を参照してください。

#### execmacro文をループ内で使う場合

execmacro 文は外部のファイルを都度読み込むため時間がかかります。ループ内で使うと顕著です。

setcompatiblemode 文を使えば、高速化する場合もあります。詳細は、第III部〜秀丸マクロのいろはにほへと　setcompatiblemode文 について を参照してください。

ページトップ 目次に戻る