超基本 秀丸メールマクロと秀丸エディタNo.10362
hutec さん 24/05/18 12:01
 
識者の皆様

いつも、助けていただいて本当にありがとうございます。
早く、そっち側に行きたいですが、しばらくはこっち側の人です。

秀丸エディタマクロでtextfileのreadを作成しましたが、メールマクロ側へ取得した
値の渡し方が判りません。
マクロを始めた皆様は同じところでつまずくと思うのですが・・・、検索しても見つ
けられません。

※read自体はLoadStringFromFile関数 CSV_LoadFile関数 を見つけたので、そちらを
利用しようと思っています。
今回の質問は、値の受渡についてです。

・もしかして、メールマクロ側のグローバル変数の値をエディタマクロ側でも参照出
来たりする?
試してから質問しろと突っ込まれそうですが・・
・メールマクロ.macにエディタマクロ.macのソースをサブルーチン風に記載出来るの
か?
それだったら、メールマクロ側でもエディタマクロの関数を呼べることになるから、
そんなはず無いか・・

ヘルプでは下記の様に記載があったので、練習でエディタマクロで作成しました。

/*
openfile、loadfile文など、通常のテキストファイルを扱う文は使えません。通常の
テキストファイルを扱いたい場合には、秀丸メール内のマクロから、run文等を使っ
て秀丸エディタを呼び出し、その秀丸エディタ内で別のマクロを実行させてください。
 ちなみに、秀丸エディタ側でのマクロ実行と秀丸メール側でのマクロ実行は並行し
て動作可能です。ただし、秀丸メールのマクロと秀丸エディタ側のマクロの両方でア
クティブウィンドウの切り替え(nexthidemaruやsetactivehidemaru等)を使うこと
は避けるか、またはrunsync等で同期させてください。

run "c:\\hidemaru\\hidemaru.exe /xテキスト処理.mac";
*/

質問1.テキスト処理.macへReadするファル名を渡したいです。%1とかで渡すのでし
ょうか?

質問2.テキスト処理.macでreadした値を、戻り値みたいな感じでメールマクロに渡
したいです。

どうぞ、宜しくお願いします。




[ ]
RE:10362 超基本 秀丸メールマクロと秀丸No.10365
h-tom さん 24/05/18 19:12
 
h-tom です。

>質問1.テキスト処理.macへReadするファル名を渡したいです。%1とかで渡すのでし
>ょうか?
run文で起動するなら、秀丸エディタの起動オプションを確認しましょう。

>質問2.テキスト処理.macでreadした値を、戻り値みたいな感じでメールマクロに渡
>したいです。
run文で起動するなら、戻り値で戻すことは出来ないです。

しかし、なぜ秀丸エディタ側で処理する必要があるのでしょうか?
秀丸メール側で制限のある opnefile は LoadStringFromFile関数 等で代替するなら、
そのまま秀丸メール上で実行すればいいのでは?
他の制限に引っかかったり、秀丸エディタ側とバージョンが合わないから使える命令
が異なるのが問題?

[ ]
RE:10365 超基本 秀丸メールマクロと秀丸No.10367
hutec さん 24/05/19 01:19
 
h-tom様、休日にフォロー有り難うございます。

>しかし、なぜ秀丸エディタ側で処理する必要があるのでしょうか?
私、もしかして勘違いしているのでしょうか?
秀丸エディタマクロの方が、関数が沢山ある。
しかし、秀丸エディタマクロの関数は、秀丸メールマクロでは使えない。よって、秀
丸エディタマクロで作った方が、色々作りやすい。

もしかして、制限があるのはほんの一部の関数だけで、
基本的には秀丸メールマクロで作成して困らないのでしょうか。

一番最初に作成したマクロが、textfileのreadでした。
その際、エディタマクロの方が下記の様な関数があり、
普通の言語っぽいので、作りやすそうでした。
readonlyopenfile $filename;

まだ、勉強して数日なので、今なら引き返せます。
宜しくお願いします。

[ ]
RE:10367 超基本 秀丸メールマクロと秀丸No.10370
こみやんま さん 24/05/19 06:44
 
うーむ、初めて「秀丸メール」の秀丸マクロを見てみたけれども、
結構グチャグチャになってる印象ですねぇ。

「秀丸メールの秀丸マクロ」は、「秀丸エディタの秀丸マクロ」も踏まえたうえで、
その差分をみていく必要みたいなのがあるけれども、
秀丸メール側だけ使えないメソッド(なぜ使えないのか妥当性一切なし)や
秀丸メール側だけ使えないプロパティ(多分秀丸エディタからの移植忘れが多数ある
んだろうなぁ。。。)


とりあえず、以下の3つのファイルを1つのフォルダにいれておけば、



★--- hmail.mac として保存 ---- 秀丸メールから実行可能
  (秀丸エディタからも実行可能なようにしてある)
   ☆☆☆ 「C:\usr\hidemaru\hidemaru.exe」の部分は、自分の秀丸のパスに書
き換えること。


jsmode "WebView2";
execjs currentmacrodirectory + @"\common.mac";
js {

    /// <reference path="../types/hm_jsmode.d.ts" />

    // このマクロ実行しているのは秀丸なの?
    let isHidemaruApp = isHidemaru();
    function isHidemaru() {
        let hidemaruExePath = hidemarudir() + @"\hidemaru.exe";
        return existfile(hidemaruExePath);
    }

    function getHidemaruPath() {
        let hidemaruExePath = String.raw`C:\usr\hidemaru\hidemaru.exe`;
        return hidemaruExePath;
    }

    function getTargetText() {
        return "おーーーぼぼぼぼぼ";
    }
    function getHmTargetMacroPath() {
        return String.raw`C:\macro\hedit.mac`;
    }

    function prevFunction() {
        try {
            deleteTempFile();
            let loadText = getTargetText();

            if (typeof (loadText) == "undefined") { throw "ファイルが無し"; }

            let hidemaruPath = getHidemaruPath(); // 秀丸エディタの絶対パス
            if (!existfile(hidemaruPath)) {
                throw "秀丸未発見";
            }

            if (!existfile(getHmTargetMacroPath())) { throw "マクロファイル
が見つかりません"; }

            let directoryPath = hidemaruPath.substring(0, hidemaruPath.lastI
ndexOf("\\"));

            let processParam = {
                msg: loadText,
                num: 3,
                returnFile: getReturnFile()
            };

            let saveFile = getArgFile();
            let paramJSON = JSON.stringify(processParam);
            saveTextFile(saveFile, paramJSON);

            let hidemaruArgs = `"${hidemaruPath}" /x"${getHmTargetMacroPath
()}"`;
            message(hidemaruArgs);
            console.log(hidemaruPath);
            console.log(directoryPath);

            // これを呼び出してるのが秀丸なら...
            if (isHidemaruApp) {
                let processInfo = hidemaru.runProcess(hidemaruArgs, ".", "gu
i", "utf8");
                processInfo.onClose(closeAsync); // 多少時間が長くても、呼び
出し側アプリ(秀丸メール?)が固まらないように

                // 非同期(マクロ実行中外でJSエンジンだけで動いてる)なので、
マクロ実行中に戻す
                function closeAsync() {
                    hidemaru.postExecMacroMemory("js {postFunction();}");
                }
            } else {
                runex(hidemaruArgs
                    , 1     //sync   0:async, 1:sync
                    , 0, "" //stdin  0:none, 1:auto, 2:<file, 3:(reserved),
                    //       4:current content, 5:selection
                    , 0, "" //stdout 0:none, 1:auto, 2:>file 3:>>file, 4:new
 window,
                    //       5:insert, 6:replace, 7:>output pane, 8:>>output
 pane
                    , 0, "" //stderr 0:none, 1:auto or >>stdout, 2-8:same as
 stdout's param
                    , 0, "" //folder 0:none, 1:current, 2:specify 3:(reserve
d), 4:exe's
                    , 1     //show   0:auto, 1:show, 2:hide, 3-13:ShellExecu
te()'s SW_*
                    , 1     //draw   0:draw, 1:no draw when stdout redirected
                    , 2     //encode 0:ansi, 2:utf-16, 6:utf-8
                    , 0     //extended flags
                );

                postFunction();
            }

        } catch (err) {
            message(err);
        }
    }

    prevFunction();

    function postFunction() {
        try {
            let returnFile = getReturnFile();
            let loadText = loadTextFile(returnFile);
            message("JSONだよ");
            message(loadText);
            let returnObj = JSON.parse(loadText);

            message(returnObj.msg); // 最初の10文字
            message(returnObj.test); // リターンオブジェクトのプロパティ

        } catch (err) {
            message(err);

        } finally {
            deleteTempFile();
        }
    }



    function saveTextFile(fname, text) {
        try {
            if (isHidemaruApp) {
                hidemaru.saveTextFile(fname, text, "utf16");
            } else {
                let dll = loaddll(hidemarudir() + "\\tkinfo.dll");
                let n = dll.dllfunc.SaveStringToFile(fname, text, 0, 1);
                if (n == 0) {
                    throw "保存に失敗しました。";
                }
            }
        } catch (err) {
            message(err);
        }
    }

    function loadTextFile(fname) {
        try {
            if (isHidemaruApp) {
                hidemaru.loadTextFile(fname, "utf16");;
            } else {
                let dll = loaddll(hidemarudir() + "\\tkinfo.dll");
                let text = dll.dllFuncStr.LoadStringFromFile(fname);
                return text;
            }

        } catch (err) {
            message(err);
        }
    }


    function deleteTempFile() {
        try {
            let fso = createobject("Scripting.FileSystemObject");
            let argFile = getArgFile();

            if (fso.FileExists(argFile)) {
                fso.DeleteFile(argFile);
            }

            let returnFile = getReturnFile();
            if (fso.FileExists(returnFile)) {
                fso.DeleteFile(returnFile);
            }
        } catch(err) {
        }
    }
}


★--- hedit.mac として保存 ----
(秀丸エディタ側で実行されるマクロ)

// 何か処理
message("秀丸開始だよ");

jsmode "WebView2";
execjs currentmacrodirectory + @"\common.mac";
js {
try {
    let argJSONFile = hidemaru.loadTextFile(getArgFile(), "utf16");
    if (typeof(argJSONFile) == "undefined") { throw "argJSONファイルが無し"; }

    let paramObj = JSON.parse(argJSONFile);

    debuginfo(2);
    message(paramObj.msg);

    let lentgh = paramObj.msg.length;

    let text = `秀丸エディタ上で渡されたメッセージは${lentgh}文字です`;
    let returnOBJ = {
        msg : text,
        test: 300,
    };

    let returnJSON = JSON.stringify(returnOBJ);
    hidemaru.saveTextFile(getReturnFile(), returnJSON, "utf16");

} catch(err) {
    message(err);
}
}

message("秀丸終了直前");

exit; // exitすることで 呼び出し元の ProcessInfoのcloseメソッドが発動する。



★--- common.mac として保存 ----
function getTempFolder() {
    let tempFolder = getenv("TEMP");
    if (!tempFolder) { tempFolder = currentmacrodirectory(); };
    return tempFolder;
}

function getArgFile() {
    return `${getTempFolder()}\\hm_args.json`;
}

function getReturnFile() {
    return `${getTempFolder()}\\hm_return.json`;
}



■「巣の秀丸マクロ」だと結構大変だろうなぁ、といった印象

少なくともJSON.stringify や JSON.parse 周辺だけは、
JavaScript使わないと、結構めんどくさいでしょうなぁ
(JSONか何かにしておかないと、渡す情報や返す情報のパラメータ情報が増えるほど
惨くなる)

ProcessInfoとhidemaru.runProcessを使ってやりとりする手もなくはないけれども、
秀丸メール側は実装が中途半端なんじゃないかなぁ。
少なくとも秀丸エディタと同じだけのものは実装されていないっぽいし。



[ ]
RE:10370 ミス訂正No.10371
こみやんま さん 24/05/19 06:52
 
getHmTargetMacroPath の中身が決め打ちになっていたので、同じフォルダというこ
とで。


    function getHmTargetMacroPath() {
        return currentmacrodirectory() + "\\hedit.mac";
    }

[ ]
RE:10367 超基本 秀丸メールマクロと秀丸No.10372
こみやんま さん 24/05/19 07:15
 
>もしかして、制限があるのはほんの一部の関数だけで、
>基本的には秀丸メールマクロで作成して困らないのでしょうか。

ざっくりは「秀丸メール」上で、「秀丸エディタの関数や記述」は「概ね」動作する
んじゃないでしょうか。

ただ全部動作するわけではないようです。
「これは動作しないと変でしょw」ってところすら動作しないものが結構あるようで
す。、

「秀丸エディタ上で作って、そのがマクロが秀丸メールでも動くのかを確認」といった
なかなかメンドクサイ作業が必要かも。

そうしないと、
@そもそも記述や使い方が間違ってるのか?
A記述も使い方もあってるけれども、秀丸エディタでは動作するけど、秀丸メールで
は動作しないのか?

は「どこにも記載はない」ので、一つずつ叩くしかなさそうw

[ ]
RE:10367 超基本 秀丸メールマクロと秀丸No.10373
h-tom さん 24/05/19 22:03
 
h-tom です。

>もしかして、制限があるのはほんの一部の関数だけで、
>基本的には秀丸メールマクロで作成して困らないのでしょうか。
秀丸メール側でサポートしていない機能はムリですが、秀丸マクロならだいたい動く
ハズです。
(JavaScript側は知りませんが)

秀まるおのホームページ(サイトー企画)−秀丸メールの紹介 - 強力なマクロ機能
https://hide.maruo.co.jp/software/hidemarumail/doc7.html

秀丸エディタ最新版と秀丸メールに内蔵しているバージョンが違う時もあるので、そ
の辺りは注意が必要です。
(まぁ、だいたい一致していません)

[ ]
RE:10373 超基本 秀丸メールマクロと秀丸No.10374
hutec さん 24/05/20 12:39
 
h-tom さま、お世話になります。

>https://hide.maruo.co.jp/software/hidemarumail/doc7.html
このページは斜め読みしたせいか、記憶に有りませんでした。
偶然ですが、ここに記載されているマクロ例
(宛先が社外なら確認メッセージを表示する例)
は、丁度やりたかった作業に近いので、とても助かります。
自社ドメインじゃ無かったら、迷惑メールとして別フォルダに移動する仕様です。

メールマクロでエディタマクロが使用出来るのであれば、
だいぶ助かります。

有り難うございました。

[ ]
RE:10371 ミス訂正No.10375
hutec さん 24/05/20 16:57
 
こみやんま様、
休日&早朝にフォルー頂いて恐縮です。
すぐにお返事したかったのですが、農作業に忙殺されておりました。
また、ご提供のソースコードが、私には何をやってるのか全然判らず、さらに時間が
かかりました。
メールマクロとエディタマクロと外部のcommonマクロでなんやらやっているのは判り
ましたが、
秀丸メールのマクロ実行で、hmail.macを実行すると、
TypeError:hidemaruusaveTextFile is nota a function
と表示されます。
今晩じっくり検証してみます。有り難うございました。

[ ]