マクロについてご指導下さい。No.32649
HARAOS さん 13/10/15 16:49
 
いつもお世話になっております。

マクロの件で教えていただきたいので、よろしくお願いいたします。
7000〜10000行くらいのCSVファイルがあります。1行が1レコードになっているデー
タで、先頭のフィールド(8バイト)で並べ替えしてあります。(CSVモードで表示し
てあります。)
以下のマクロで、先頭フィールドが同じレコードまでを別のファイルにコピー・保存
しています。ところがWindows8で動作させると今まで(XP)の倍くらい時間が掛か
ります。文法的にもっと早く動かす方法はあるでしょうか?
-------------------------------------------------------------
gofiletop;

$fn=filename;

while(true){
 $wbs1=gettext(1,y,8,y);
 if (strlen($wbs1)==0) endmacro;
 copyline;
 while(true){
  down;
  $wbs2=gettext(1,y,8,y);
  if ($wbs1 != $wbs2) break
  selectline;
  appendcopy;
 }
 openfile "/h"+"";
 paste;
 saveas $wbs1+".csv";
 setactivehidemaru findhidemaru($fn);
 closehidemaru 1;
}

endmacro;

[ ]
RE:32649 マクロについてご指導下さい。No.32650
秀丸担当 さん 13/10/15 17:29
 

画面の描画をしていると遅いので、とりあえずdisabledraw;を使うといいと思い
ます。
マクロの先頭や、setactivehidemaruの直後などにdisabledraw;を書いておくと
描画しないようになり、描画のぶん高速になります。

[ ]
RE:32649 マクロについてご指導下さい。No.32651
アルビレオ さん 13/10/15 17:50
 
ユーザーのアルビレオです。

ちょっと気になったのですが、gettext(1,y,8,y)としていますが、gettextの場
合は左端は0なのでgettext(0,y,8,y)が意図した動作なのではないでしょうか。

それはそれとして、本題です。
appendcopyをしている行は必ず連続しているので、範囲選択を使ってコピーを一
回で済ませることができますね。
動作テストはしていませんが、こういうマクロを書けるならおかしなところがあ
っても修正できると思います。(^^;

gofiletop;
$fn=filename;
while(true){
 $wbs1=gettext(0,y,8,y);
 if (strlen($wbs1)==0) endmacro;
 beginsel;
 while(true){
  down;
  $wbs2=gettext(0,y,8,y);
  if ($wbs1 != $wbs2) break;
 }
 endsel;
 copy;
 openfile "/h"+"";
 paste;
 saveas $wbs1+".csv";
 setactivehidemaru findhidemaru($fn);
 closehidemaru 1;
}
endmacro;

またgettextよりテキスト検索の方が低コストだと思われるので、こうするとも
っと高速化できると思います。

gofiletop;
$fn=filename;
while(true){
 $wbs1=gettext(0,0,8,0);//常に先頭行を取得
 if (strlen($wbs1)==0) endmacro;
 gofileend;//テキスト末尾へ移動
 setsearch $wbs1;//同じサーチを繰り返し行うので検索文字列の設定はここで
しておく
 while(true){
  searchup;//一致する最後の行を検索
  if(x==0) break;//一致したのが行の先頭なら目的の行
 }
 down;
 beginsel;//一致しない最初の行から
 gofiletop;
 endsel;//テキスト先頭までを選択
 cut;//コピーではなくカット
 openfile "/h"+"";
 paste;
 saveas $wbs1+".csv";
 setactivehidemaru findhidemaru($fn);
 closehidemaru 1;
}
endmacro;

さらに先頭8文字に正規表現で意味を持つ文字が含まれていないという前提があ
れば、
 setsearch $wbs1;
 while(true){
  searchup;
  if(x==0) break;
 }
の部分を
 searchup "^"+$wbs1;
に置き換えてループを減らせるのでかなり高速になるはずです。

[ ]
RE:32650 マクロについてご指導下さい。No.32655
HARAOS さん 13/10/16 14:16
 
秀丸担当 様

返答ありがとうございます。やってみましたが、元のファイルから新しいファイルに
コピーするという段階で、disabledraw が解除されてしまう仕様みたいでした。
1つのファイル内で処理を行なう場合は有効な手段と理解しました。
また問題はアルビレオ様のご指導により改善できました。
今後ともよろしくお願いいたします。

[ ]
RE:32651 マクロについてご指導下さい。No.32656
HARAOS さん 13/10/16 14:31
 
アルビレオ 様

大変ありがとうございました。結果として最後の方法で劇的に改善しました。

まず修正前の状態で計ったところ、26分30秒掛かっていた処理があります。これを行
毎ではなくまとめてコピーする方式にしたら10分50秒になり、半分以下になりました。
XPだと元のやり方でこの位の時間でした。

さらに最後の方式(検索文字には正規表現の文字はありませんので)で行なったとこ
ろ、何と!!たったの50秒で終わってしまいました。愕然としました。今まで何をや
っていたのかと・・。知らないという事は怖いですね。手作業ではとても出来ないよ
うな事がたった10分くらいで出来ると満足していた自分が情けないです。本当に感
謝です。

>ちょっと気になったのですが、gettext(1,y,8,y)としていますが、gettextの場
>合は左端は0なのでgettext(0,y,8,y)が意図した動作なのではないでしょうか。

各フィールドが""で括られているデータなので、最初の1文字を除いてました。ファ
イル名に使いたかったので。でも最後のやり方では先頭検索なので、gettext(0,y,8,
y)に変更してファイル名にするときに先頭の"を取り除くようにしました。

>動作テストはしていませんが、こういうマクロを書けるならおかしなところがあ
>っても修正できると思います。(^^;

情報系でもない単なるエンドユーザーですが、データを扱う事が多いので少しでも楽
をしたいと思っていろいろ勉強してます。でもやり方一つでこんなに違うものか!と
改めて思い知らされました。

最初の方法を試したときに、どうしてもうまく行かなくて調べてみたら、gettextし
たときに、範囲選択が解除されてしまうことが分かり、調べてみたら、オプションつ
ければそのまま行けるという事がわかりました。何かする度にあたらしい発見をして
います。

[ ]
RE:32656 マクロについてご指導下さい。No.32657
アルビレオ さん 13/10/16 17:17
 
アルビレオです。

>各フィールドが""で括られているデータなので、最初の1文字を除いてました。ファ
>イル名に使いたかったので。でも最後のやり方では先頭検索なので、gettext(0,y,8,
>y)に変更してファイル名にするときに先頭の"を取り除くようにしました。

なるほど、先頭が必ず " で始まっているのなら gettext の左端は 1 に戻して
 searchup "^\""+$wbs1, regular;
とすれば、一文字取り除く処理を省けてマクロがすっきりするのでおすすめして
おきます。
まあ速度に大した違いはないでしょうけど。

また disabledraw が途中で解除されるとしても、while ループの先頭で毎回
disabledraw をやっておけばより高速になると思います。
改良版では毎回ファイル末尾へ移動するため、画面の書き換えがたくさん起こり
ますからね。

[ ]
RE:32657 マクロについてご指導下さい。No.32658
HARAOS さん 13/10/17 09:15
 
アルビレオ 様

たびたびありがとうございます。

>先頭が必ず " で始まっているのなら gettext の左端は 1 に戻して
> searchup "^\""+$wbs1, regular;
>とすれば、一文字取り除く処理を省けてマクロがすっきりするので
>おすすめしておきます。

なるほどこういう書き方になるのですね。やろうと思いましたがわからなかったので
ファイル名の方に逃げてしまいました。こちらのほうがスマートですよね。

>また disabledraw が途中で解除されるとしても、while ループの先頭で毎回
>disabledraw をやっておけばより高速になると思います。

ループの外に書いていたので全く効果がわかりませんでした。
修正版で劇的に早くなったのでこれ以上望む事はないのですが、
せっかくですから早速やってみます。

いろいろとありがとうございました。

[ ]