テキストファイルから秀丸のマクロに変数No.09482
moyabu さん 21/06/28 15:54
 
テキストファイルから秀丸のマクロに変数を取り込みたいのですが,次のようなマク
ロを考えてます.
テキストファイル"d_min.txt"の中身は,1行だけの"3675"のようなものです.

    openfile "d_min.txt";
 copyline;
 beginclipboardread;
 #tmp3 = val(getclipboard());

1回きりなら,これでいいのですが,whileで数千回実行したいので,画面がチラチラ
すること,および実行時間がかかりそうなので,他の方法はありませんでしょうか?

[ ]
RE:09482 テキストファイルから秀丸のマクNo.09483
ラフ さん 21/06/28 20:19
 
同じファイルを数千回読み込んで何がしたいのかよくわからないけれど、
2回目のopenfileで既にオープンされているので、その前にクローズしないといけま
せんね。
それは置いといて、速度的にはFileSystemObject使って読んだ方が圧倒的に速いです。

##objFso = createobject("Scripting.FileSystemObject");
if( getresultex(10) == false ) {
 endmacro;
}

##i = 0;
##maxloop = 1000;
##sum = 0;
while(##i < ##maxloop) {
 ##objFile = callmethod_returnobj( ##objFso,"OpenTextFile", @"d:\temp\a.txt",
 1);
 if( getresultex(10) == false ) {
  message "OpenTextFile Error";
  break;
 }
 if(getpropnum(##objFile, "AtEndOfStream")) {
  message "No data error";
  break;
 }
 $$line = member(##objFile,"ReadLine");
 ##tmp = val($$line);
 ##sum = ##sum + ##tmp;
 ##i = ##i + 1;
 member ##objFile,"Close";
}
message str(##i);
message str(##sum);
endmacro;



[ ]
RE:09483 テキストファイルから秀丸のマクNo.09484
moyabu さん 21/06/29 08:52
 
コメントそしてマクロまで提示していただき,ありがとうございます.使ったことの
ないFileSystemObjectですが,勉強して使ってみます.

元々は,プログラム(*.exe)がランダムに出力する値を,秀丸のマクロ変数に取得す
ることが目的でした.

プログラムの出力ー>テキストファイルー>秀丸マクロで読み取りー>処理

というスキームを考えていました.



>同じファイルを数千回読み込んで何がしたいのかよくわからないけれど、
>2回目のopenfileで既にオープンされているので、その前にクローズしないといけ
>ませんね。
>それは置いといて、速度的にはFileSystemObject使って読んだ方が圧倒的に速いです。
>
>##objFso = createobject("Scripting.FileSystemObject");
>if( getresultex(10) == false ) {
> endmacro;
>}
>
>##i = 0;
>##maxloop = 1000;
>##sum = 0;
>while(##i < ##maxloop) {
> ##objFile = callmethod_returnobj( ##objFso,"OpenTextFile", @"d:\temp\a.txt
>", 1);
> if( getresultex(10) == false ) {
>  message "OpenTextFile Error";
>  break;
> }
> if(getpropnum(##objFile, "AtEndOfStream")) {
>  message "No data error";
>  break;
> }
> $$line = member(##objFile,"ReadLine");
> ##tmp = val($$line);
> ##sum = ##sum + ##tmp;
> ##i = ##i + 1;
> member ##objFile,"Close";
>}
>message str(##i);
>message str(##sum);
>endmacro;
>
>

[ ]
RE:09482 テキストファイルから秀丸のマクNo.09485
山紫水明 さん 21/06/29 20:42
 
 moyabuさん,

まだここをご覧になっているかどうか分かりませんが,

>テキストファイル"d_min.txt"の中身は,1行だけの"3675"のようなものです.

 この意味が少し分かりにくいですね。
(1)この1個のファルを数千回開いたり閉じたりする。ラフさんはそのように
   解釈されているようです。
(2)数字だけの行が1行あるファイルが数千個ある。
(3)1個のファイルに数字だけの1行が数千行並んでいる。
どれを想定されているのでしょうか。

                    山紫水明
                    SANSHISUIMEI

[ ]
RE:09485 テキストファイルから秀丸のマクNo.09486
moyabu さん 21/06/30 09:34
 
ありがとうございます.しっかり見ております.

>(2)数字だけの行が1行あるファイルが数千個ある。

ただし,そのファイル名は同じですが,毎回,内容(数字)は違います.やりたい作
業は,以下の作業を"while"で数千回繰り返すことです.

プログラム(.exe)実行で"d_min.txt"を生成ー>その数字を秀丸マクロで読み取り評
価するー>その評価に基づき,種々のファイル処理(コピーなど,または何もしな
い)を秀丸マクロでおこなう.

"d_min.txt"は,プログラム(.exe)実行毎に書き換えられる(生成される).

要は,「プログラムからの出力の値を秀丸マクロの変数に取り込みたい.それを簡単
に実現できないか?」

というと,プログラムソースを書き換えて,プログラム内で数千回ループを実現する
のが早い,と言われそうですが.プログラムは複数個あり,"runex"を直列にして実
行しています.ここはあまりいじりたくない.

こんな意図です.
普通にある要望だと思うので,簡単にできそうに思うのですが...私がわからず,
投稿した次第です.よろしくアドバイスお願いします.

プログラム(.exe)から秀丸マクロへの値の受け渡しにファイルを介するという,私の
最初の考え方がまずいのですよね.


> moyabuさん,
>
>まだここをご覧になっているかどうか分かりませんが,
>
>>テキストファイル"d_min.txt"の中身は,1行だけの"3675"のようなものです.
>
> この意味が少し分かりにくいですね。
>(1)この1個のファルを数千回開いたり閉じたりする。ラフさんはそのように
>   解釈されているようです。
>(2)数字だけの行が1行あるファイルが数千個ある。
>(3)1個のファイルに数字だけの1行が数千行並んでいる。
>どれを想定されているのでしょうか。
>
>                    山紫水明
>                    SANSHISUIMEI

[ ]
RE:09483 テキストファイルから秀丸のマクNo.09487
おすぎ さん 21/07/01 10:40
 
横から失礼します。
秀丸の COMの呼び出しをよく使う者です。

「FileSystemObject使って読んだ方が圧倒的に速い」理由は、
ファイルの開閉(OpenTextFile, Close)が速くなるからですか?
それとも、読み取り(ReadLine)が速いからでしょうか?

よろしくお願いいたします。

[ ]
RE:09487 テキストファイルから秀丸のマクNo.09488
秀丸担当 さん 21/07/01 12:58
 

FileSystemObject使った方が速いのは、読み取りがメモリ上でのみ行われることが大
きいと思います。
openfileで秀丸エディタの本文に読み込むと、ファイルの内容を読み込むだけでなく、
秀丸エディタの動作に関わることがいろいろ発生します。disabledrawなどで描画を
抑制したりすることもできますが、それでもFileSystemObjectでメモリ上に読み込む
だけのほうが速いです。
ただFileSystemObjectの場合、Shift-JISかUnicode(UTF-16)のどちらかしか扱えない
ということもあります。
本文に読み込む場合でもまだ無駄な部分はあると思うので、いまさらながらではあり
ますが改善を検討しようと思います。


[ ]
RE:09488 テキストファイルから秀丸のマクNo.09489
おすぎ さん 21/07/01 17:20
 
秀丸担当さま

詳しいご説明をありがとうございます。
大変勉強になりました。

[ ]
RE:09486 テキストファイルから秀丸のマクNo.09490
山紫水明 さん 21/07/01 20:44
 
 moyabuさん,

 そういう目的でしたら,ラフさんのご提案のFileSystemObject使った方が速い
処理ができると思います。
 最初のお考えの「プログラムの出力→テキストファイル→秀丸マクロで読み取
り→処理」でやるとすれば,"/h"オプションで開き,gettext文で読取るという
方が少しは速くなると思います。
 あるいは出力するファイル名を"d_min1.txt","d_min2.txt"・・・というよう
に変えることができれば,
  (1)まず全部のファイルを出力する。
  (2)grep で数字の行を抽出する。
  (3)各行のタブ部分を全置換を用いて削除する。
  (4)上の行から読み取って順番に処理していく。
 このようにしたら,ファイルを全部開く必要はなくなるでしょう。

                    山紫水明
                    SANSHISUIMEI

[ ]
RE:09490 テキストファイルから秀丸のマクNo.09491
ラフ さん 21/07/01 22:57
 
>り→処理」でやるとすれば,"/h"オプションで開き,gettext文で読取るという
openfileの/hオプション有りだとクローズclosenewがうまく効かないですよね?
closenew自体は正しく動くんですが、動作環境で設定した起動秀丸エディタの起動数
の上限に達した時点でエラーになり、
マクロ終了させると空(無題)の全ウィンドウが表示されます。
ちなみに/hなしだと一々表示されてチラチラしますが、マクロ終了後は1個の無題ウ
ィンドウだけになります。
つまり、/h無しだと「最初のclosenewした無題ウィンドウで次のファイルがオープン
される」が繰り返されるのに対し、
/h有りだと非表示になっているために、別の非表示ウィンドウで読み込まれ、closen
ewの回数だけ新規ウィンドウを作ってしまい、上限に達するようです。
で、ウィンドウハンドル取得してクローズする方式にしてみたけど、それだとかなり
遅くなってしまいました。
他に/hオプション有りでopenfileしたウィンドウをクローズする方法ってありました
っけ?

[/hなし]約2秒
##i = 0;
##maxloop = 50;
disabledraw;
$$start_time = time;
while(##i < ##maxloop) {
 openfile @"d:\temp\a.txt";
 #tmp3 = val(gettext2(0, 1, linelen2, 1));
 ##i = ##i + 1;
 closenew;
}
$$end_time = time;
enabledraw;
message $$start_time+"-"+$$end_time;
endmacro;

[/h有り]約37秒
##i = 0;
##maxloop = 50;
#hwnd = hidemaruhandle( 0 ); //元ウィンドウのハンドルを取得する
disabledraw;
$$start_time = time;
while(##i < ##maxloop) {
 openfile @"/h d:\temp\a.txt";
 #hwnd_new = hidemaruhandle( 0 ); //ウィンドウハンドルの取得
 #tmp3 = val(gettext2(0, 1, linelen2, 1));
 ##i = ##i + 1;
 setactivehidemaru #hwnd; //元ウィンドウに戻る
 closehidemaru #hwnd_new; //別ウィンドウを閉じる
}
$$end_time = time;
enabledraw;
message $$start_time+"-"+$$end_time;
endmacro;


[ ]
RE:09491 テキストファイルから秀丸のマクNo.09492
h-tom さん 21/07/01 23:52
 
h-tom です。

>で、ウィンドウハンドル取得してクローズする方式にしてみたけど、それだとかな
>り遅くなってしまいました。
> 他に/hオプション有りでopenfileしたウィンドウをクローズする方法ってありまし
>たっけ?
常に同じファイルに出力される前提なら閉じる必要はないので、"reopen"すればいい
のでは?
で、最後に閉じればいいだけ。

##i = 0;
##maxloop = 50;
#hwnd = hidemaruhandle( 0 ); //元ウィンドウのハンドルを取得する
disabledraw;
$$start_time = time;
//とりあえず開く(ファイルはロックしていない前提)
openfile @"/h d:\temp\a.txt";
#hwnd_new = hidemaruhandle( 0 ); //ウィンドウハンドルの取得
while(##i < ##maxloop) {
 //runex実行
 //ここから

 //ここまで
 
 //アクティブになってないかもしれないのでアクティブにする
 setactivehidemaru #hwnd_new;
 //再読み込み
 reopen;
 //値を取り込み
 #tmp3 = val(gettext2(0, 1, linelen2, 1));
 //取り込んだ値を元に処理実行
 //ここから

 //ここまで
 
 ##i = ##i + 1;
}
setactivehidemaru #hwnd; //元ウィンドウに戻る
closehidemaru #hwnd_new; //別ウィンドウを閉じる

$$end_time = time;
enabledraw;
message $$start_time+"-"+$$end_time;
endmacro;

[ ]
RE:09492 テキストファイルから秀丸のマクNo.09494
ラフ さん 21/07/02 07:20
 
>h-tom です。
>
>常に同じファイルに出力される前提なら閉じる必要はないので、"reopen"すればい
>いのでは?
>で、最後に閉じればいいだけ。

なるほど、reopenって手がありましたね。

reopen前のsetactivehidemaru #hwnd_new;は無くても大丈夫でした。
早くなったのでループ500回で計測して16秒(50回に換算すると1.6秒)
FileSystemObjectは早すぎるので10倍のループ5000回で計測して5秒(50回換算すると
0.05秒)
やっぱreopenもopenfileと同じく秀丸の内部処理が走るから仕方ないですが。

[reopen]
##i = 0;
##maxloop = 500;
#hwnd = hidemaruhandle( 0 ); //元ウィンドウのハンドルを取得する
disabledraw;
openfile @"/h d:\temp\a.txt";
#hwnd_new = hidemaruhandle( 0 ); //ウィンドウハンドルの取得
$$start_time = time;
while(##i < ##maxloop) {
// setactivehidemaru #hwnd_new;
 reopen;
 #tmp3 = val(gettext2(0, 1, linelen2, 1));
 ##i = ##i + 1;
}
$$end_time = time;
setactivehidemaru #hwnd; //元ウィンドウに戻る
closehidemaru #hwnd_new; //別ウィンドウを閉じる
enabledraw;
message $$start_time+"-"+$$end_time;
endmacro;


[FSO]
##objFso = createobject("Scripting.FileSystemObject");
if( getresultex(10) == false ) {
 endmacro;
}

##i = 0;
##maxloop = 5000;
$$start_time = time;
while(##i < ##maxloop) {
 ##objFile = callmethod_returnobj( ##objFso,"OpenTextFile", @"d:\temp\a.txt",
 1);
 if( getresultex(10) == false ) {
  message "OpenTextFile Error";
  break;
 }
 $$line = member(##objFile,"ReadLine");
 ##tmp = val($$line);
 ##i = ##i + 1;
 member ##objFile,"Close";
}
$$end_time = time;
message $$start_time+"-"+$$end_time;
endmacro;

[ ]
RE:09494 テキストファイルから秀丸のマクNo.09495
moyabu さん 21/07/02 09:28
 
ラフさんはじめ,皆様のコメント,アドバイス,ありがとうございます.

>早くなったのでループ500回で計測して16秒(50回に換算すると1.6秒)
このスピードなら,十分私の希望に叶っております.

ついでなんですが,山紫水明さんとラフさんのコメントにありました"/h"オプション
の件.
ラフさんのコメント中の
>[/hなし]約2秒
>[/h有り]約37秒
は,どうしてでしょうか? 

マクロのヘルプに「 /h オプションは,画面から見えなくなる&マクロの実行が非常
に高速になります。」と書かれてあります.

私も前に,以下のような感じで使いました.

#cycle = 3;
while( #cycle > 0 ) {

// runex aaa        ;
// runex bbb        ;
// runex ccc        ;

 openfile "/h" + "d_min.txt";
 copyline;   //gettextなどで書き直しますが
 beginclipboardread;
 #tmp3 = val(getclipboard());

//ここでいろいろ処理する予定

 #a = findhidemaru("d_min.txt");
 closehidemaru #a;

 #cycle = #cycle - 1;
}
endmacro;

このマクロを実行すると,"d_min.txt"は見えずに,確かに画面のチラツキは消え
た?ようですが,ラフさんご指摘のように,
>マクロ終了させると空(無題)の全ウィンドウが表示されます。

このマクロでは,最後にボコボコと空(無題)がループ回数分(3個)だけ生成され
ました.
動作のスピード的には申し分ないのですが...

"/h"オプションの使い方で,記述ミスがあるのでしょうか?
そもそも"/h"オプションはこんな場面で使うものではないのでしょうか?


[ ]
RE:09495 テキストファイルから秀丸のマクNo.09497
ラフ さん 21/07/02 13:27
 
>>[/hなし]約2秒
>>[/h有り]約37秒
>は,どうしてでしょうか? 

こんにちは。

ループの中でオープン、クローズを繰り返すためではないでしょうか。
単一の処理なら/h有りの方が速いと思います。
そのためreopen(これはおそらくウィンドウを使い回ししている)だとかなり速くなり
ます。

09491の書き方が悪かったかもしれませんが、/h無し(約2秒)のほうはclosewinを使
っているため、最初のウィンドウの使い回しをしている(実際にウィンドウ位置固定
のままでタイトルバーがチラチラしている)。
一方/h有りの方はclosewinを使うと「/h有りだと非表示になっているために、別の非
表示ウィンドウで読み込まれ」になってしまい、起動上限(私の設定は30)に引っか
かったため、ウィンドウハンドルを使ってクローズするようにしたときの時間なので、
毎回ウィンドウ生成が行われ、その処理に時間を取られているのだと思います。

[ ]
RE:09495 テキストファイルから秀丸のマクNo.09499
ラフ さん 21/07/02 13:37
 
書き忘れたので。

moyabuさんのマクロの場合
(1) ループ回数が少ない。
(2) ウィンドウの生成処理関連の時間に比べ、他の部分の処理時間が多くかかってい
る。
そのため/hの効果が表れているのではないかと思います。


[ ]