ほとんど身辺雑記に近いので、自分のところに書くべきかもしれないのです が、一応、Vzマクロネタなのでこちらに。 TTY時代のニフティのログ整理を行っております。 この際に扱うというか同時にオープンしているのは、日付単位の生ログと、 会議室単位の分割ログ、そしてその会議室の RMN で取得したタイトル一覧の ファイルです。 当然、ログ整理にあたっては、Vzマクロは大活躍です。 ログ整理用マクロは、普段は使わないので外部マクロファイルとしています。 自分がログ整理する時の手順はほぼ確立しているので、このファイルも長い こと触っていませんでした。 最近、タイトル一覧のファイルの扱いを変えることにしました。 その時のチェックに、昔作ったマクロが使えるな、と思いあたりました。 具体的には、ここの #2127 に書いたマクロです。 アレをもうちょっと改造して、検索文字列の連続取得を使ったり、ラベルを 3つくらい使ったりして、そこそこ満足の行くものができました。 そこで、本格運用に移行しようとして、2年振りぐらいにログ整理マクロの ファイルを開いてみたら・・・何やら、知らんマクロが書き込まれている。 いや、マクロの文体やらなんやらから、私が作ったのには間違いないのです が、コメントはおろか、マクロタイトルも入っていないし、何をするマクロ なのかさっぱり見当もつかない。 基本的に私、キーボードマクロで使い捨てな仕事をすることがほとんどで、 よっぽど繰り返し同じ作業をすると考えない限り、ファイルにマクロを保存 するようなことはしない人間です。その上、マクロタイトルすら入れていな い事から推測すると、そのマクロを記録した当時の私にとって、そのマクロ の動作は自明なものだったはず。同じファイルに記録されている他のマクロ も同じ状況でしたから。そして、実際、それらのマクロについては現在でも 動作を完璧に把握しているというか、ログ整理のたびに使っています。だけ ど、該当のマクロについては、何をするものかさっぱりわからないし、そも そも使った記憶すらない。 ということで、それはいったい何をするマクロなのか、解答を募集してみる ことにしました。以下に、そのマクロを掲載します。 72 [F14] "" &s c0, :b &24&24 #r (r)?{ #x c++, >b }?{ #39#c#b#c#B#B (c>0)?{(c){#e}} } &d * このうち、外部マクロ24番は、検索文字列の連続取得マクロです。 この発言の一番上の方に書きましたが、処理対象として推測されるものは、 日付単位の生ログ、会議室単位の分割ログ、RMN で取得したタイトル一覧の ファイルのいずれかであると思われます。実はそれが間違いなのかもしれま せんが。 あと、ラベルや条件分岐を使っているところから、私としてはそれなりに力 を入れて作ったはずです。私はそういうのを使わざるをえないような複雑な マクロはあまり作りませんから。 さて、このマクロ、どんなファイルのどの部分にカーソルを置いて起動する と、どのような動作をするのでしょうか。いや、まぁ、別にわかったからど うという事もないのですけど。
> さて、このマクロ、どんなファイルのどの部分にカーソルを置いて起動する> と、どのような動作をするのでしょうか。いや、まぁ、別にわかったからど> うという事もないのですけど。一応、自分でも色々と試してみているのですが、さっぱりわかりません。 まず、テキストの切換がないことから、同一のファイル内で何かを行うもの であるのは間違いありません。次に、検索文字列の連続取得を2回続けて行 ってから上方向検索を行っている、というところが手がかりになります。こ れが意味をなすという事は、ログなら発言ヘッダの先頭とか、タイトル一覧 なら発言番号とIDの組み合わせ、というのが可能性が高いのかな、と思い ます。でも、実際にそういうところで実行してみても、よくわからん動作を するだけ。動作開始場所が誤っているのか、想定しているファイルの構造ま たは形式が異なっているのか。 ということで、一応、成果は上がらないながらも自助努力はしています。
全然,解りませんでした。> 72 [F14] ""> &s> c0,> :b &24&24 ;カーソル位置から2VZ文節を検索文字列にセット;2VZ文節限定ということはIDやハンドルではないらしい> #r ;後方検索:つまりカーソルは複数行のブロックの内にあるらしい> (r)?{ ;探索失敗:同じ文字列を探すということは発言番号ではないらしい> #x c++, >b ;1行だけ降ろしてループ:行単位のデータ?ということは;同じ桁位置に同じ要素が存在するということで, ;ブロック単位データではないということになる> }?{ ;探索成功:同じ文字列があるということは ID なのか?> #39 ;画面の上端へ移動? それまでのカーソル位置をチャラに?> #c ;前方検索:必ずヒットするという前提だが元位置とは限らない> #b #c ;ブロック指定してさらに探索する:切り出すため?> #B #B ;ブロックの最初と最後を一旦行き来するだけ? mb 指定か?> (c>0)?{(c){#e}} ;失敗した回数を行単位で上に移動;#B*2では意味が解らない> }> &d> *いやー,解らないですねぇ。 IDとそれに続くスペースで特定の人の切り出し前の範囲指定かと思った。 でも,やっぱりそれではないらしい。 うーむ。
> 全然,解りませんでした。今日は宿直明けで、いつも以上に頭が回っていませんが。 めざらさんの注釈で、解析が大きく前進しました。 最大のヒントとなったのは、以下の部分です。> > #x c++, >b ;1行だけ降ろしてループ:行単位のデータ?ということは> ;同じ桁位置に同じ要素が存在するということで,行単位のデータとなると、処理対象は明らかにタイトル一覧のファイルです。 もう一つのヒントは、ここ。> > #c ;前方検索:必ずヒットするという前提だが元位置とは限らないこのコメントから、多分、タイトル一覧ファイルに重複している行があった 場合の処理をなにか考えたのではないか、と思われます。先日、実験しても うまく行かなかったのは、たまたま重複のないファイルで実験してしまった から、と思われます。あるいは、ある特定のパターンの重複の場合だけ処理 をする、とか。で、当時はそのパターンは結構あったけど、その後、そんな 特殊なパターンにはとんと出会っていないのですっかり忘れてしまった、と いうのはありそうな話です。 まだ、めざらさんのコメントを読んでから実験していないので確かなことは わからないのですが、いくつか重複するパターンを作って、いろんな位置に カーソルを置いて実行してみたいと思っております。
今日は快晴、絶好のお散歩日和。 ちょっとショックだったのは、現住所に35年近く住んでいるというのに、 自宅から2kmと離れていないところに知らない道があったこと。 その道の先は新興住宅地だった、というのならよくある話ですけど、目の前 に広がったのは丘の上の広い畑の風景。30年以上前ならこの近辺でもよく 見かけた風景なんですが、今ではなんかとてつもなく懐かしい感じ。 昔は雑木林だったところを開墾しました、という感じなのですが、いつ開墾 したんだろう。なんとなく、子供の頃はなかったような気がするので、ここ 15年ほどの間にできたのかなぁ。その道は、10年ぐらい前にはあったよ うに思うのですが、もしかしたら25年前にはなかったかもしれない。 と、長い長い余談はさておき、本題です。> わからないのですが、いくつか重複するパターンを作って、いろんな位置に> カーソルを置いて実行してみたいと思っております。1時間ほどですが、いろいろと実験してみました。 結果、どうもこれは、作りかけのマクロを登録してそれっきり忘れてしまっ たのではないか、と思うようになりました。 例えば、生ログというか実際の巡回の際、最初は発言番号1000番以降のタイ トル一覧を取得したとします。この時、最終発言が1060番だとすると、そこ までのタイトル一覧しか得られません。次の巡回時に、例えば1050番以降の タイトル一覧を取得すると、1050〜1060が重複します。一般的なログ整理ツ ールでは、タイトル一覧を抽出する際に自動では重複を削除しませんから、 タイトル一覧ファイルにはその重複がそのまま含まれてしまいます。 この時に、2回目に出てきた「1050」という発言番号の先頭にカーソルを置 いてこのマクロを起動すると、重複部分のファイル先頭に近い方をブロック してくれる、というのが目指す動作のようです。 が、未完成というか、バグというか、どうもうまく動かない部分がある。 まず、マクロ起動時のカーソル位置というか、2回目に出てきた発言番号、 上記の例で言うなら1050が画面上端にあった場合の挙動。これはなんかとて も変。あと、重複していない発言番号で起動した場合などのエラーチェック も何にもないようだし。 どうもこれは、私の基準ではとても正式マクロに格上げできないようなもの なんですが、なにかを間違えてしまったのかもしれません。 大変お騒がせしました。
まぁ,よくある話と言えばそうかもしれませんね。 わたしも以前は作りかけて放り出したマクロが山のようにあって, それらを後から見ても何をしようとしていたのか忘れてしまっていて 思い出せないということがよくありました。 そこで,雛形作成マクロに起動後所定の位置に必ず所期の機能の 書き込みを促すようなオマケ機能をつけたところ,それからは 作りかけで何週間放っておいても,気が向いたときに続きを 書くことができるようになりましたね。 #^ #> #m "#if 0" #m "#endif" #< #n &m("最初に期待する機能をメモしておきましょう。") こんな感じ。
> アレをもうちょっと改造して、検索文字列の連続取得を使ったり、ラベルを> 3つくらい使ったりして、そこそこ満足の行くものができました。さらに改造して、今回ネタとして提出したような、ブロック化機能を取り付 けてみました。結果、こんな感じ。 72 [F13] "タイトル一覧番号順" ?. #< #f &n a=r, :a #x #< #f (r)?>c &n b=r, (a<b)?{a=b, >a} &s &24 #39 #c #x #c (r)?{#e} #b :b #e #< #f &n c=r, (b<=c)?{>b} &d #x #B :c . こんなもので、とりあえずは役に立っております。 本人は満足しているのですが、もし添削して頂ければ幸いです。
> 本人が満足しているものにアレコレ手を出す趣味はありませんが…
> マクロ番号って,本人の環境以外では異なっている可能性が高いので,
> Web上に書くときは,やはりその内容を書くか,代替コードが良いと思います。
> まぁ,#3143で言及していますから,同じなんだろうと推測しますけれど。
> それはそれとして,その#Gで何を取得するのか読み手には分からないので,
> …というか処理対象のデータがどのような構造なのかまったく解らないので
> 想像するしかないわけですが…この時の取得文字列の内容によっては,
> 組み込みマクロを使わずに #G ひとつで済むのではあるまいかと思います。
> 実は,前回もそうだったのですが,#39 の効用が今ひとつ解りません。
> 文字列を取得してカーソル行を変更して検索して,何故所期の動作なのか。
> 取得した文字列そのものにマッチしはしないか,心配になったります。
とりあえず、コメントをつけてみました。 結果、どうも、元となった連番処理マクロからいろんなものを引きずってい るためにいろいろと変なことになっているのではないか、と思うようになり ました。 72 [F13] "タイトル一覧番号順" ?. #< #f ;行頭の空白を無視して &n a=r, ;発言番号を数値で取得 :a #x ;1行下げて #< #f ;行頭の空白無視 (r)?>c ;行頭がファイル末なら終了?(終了条件が変?) &n b=r, ;次の発言番号を取得して (a<b)?{a=b, >a} ;番号が増加していればさらに次の行で同じ比較を実施 &s #G ;増加していなければ今度は文字列として発言番号を取得 #39 #c ;カーソルを画面上端に持っていきたいのかな? #x #c (r)?{#e} ;その発言番号が見つからなければカーソルを戻して #b ;ブロックモード :b #e #< #f &n c=r, ;重複部の始りまで、今度は上方向にカーソル移動 (b<=c)?{>b} ;重複部が終了したら &d #x ;カーソルが行きすぎているので一つ戻して #B ;重複部の終了部分にカーソルを持ってきて終了 :c . これをさらに、ロジックだけをまとめると、以下のようになりました。 番号が下方向に単調増加かチェック 増加していないところにきたら、その小さい方の番号を記憶 そして、なにやらカーソルを移動してブロックモード 今度は、記憶した番号まで上方向に遡り 遡りきったらブロックモードのままカーソルだけ下に持ってきて終了> > 実は,前回もそうだったのですが,#39 の効用が今ひとつ解りません。> 私自身にもよくわかっていないのかもしれません。もしかしたら、単に見ばえの問題でカーソル移動を行っているのかもしれま せんし、カーソル移動しなかったらどのような問題が生じるか、というよう なことはまったく不明です。
今日は前橋で叔父の葬儀があり, 電車の乗車時間が長かったためアレコレ考えていました。 手元のログには RTN(でしたっけ,忘れた)での一覧はまったく残っていなかった ので,マクロを見ながら再現させようと思ったものの,ともかく行頭に空白がある というところでどういった形式なのかも想像できず難渋していましたが, 昔,- ジョンの魂 -さんが ISH 会議室の発言一覧出力をライブラリに アップしていたなと思い出し,探してみたら,ありました,ありました。 これでようやく同じ土俵に立てます。 ご存じない方のために例示すると, −会議室16 :とくせつ:Ish□夢見る小さなプログラム 発言数 :1759 未読 :0− <タイトル一覧> 番号 ID 登録日 TO CO 題名 801 HFD00076 11/13 22:25 0 発言者削除 802 GCD00613 11/14 21:24 0 発言者削除 :修正版アップのため 803 HFD00076 11/15 20:56 0 発言者削除 804 QFF00306 11/15 21:55 0 【VZ】 VWX Ver 1.03c(差分) …こんな感じ。(お手元と同じでしょうか>としきさん) これをブロック単位で重複するようにすればサンプルテキストになるわけですね。 汎用性という視点で気の付いたことを列挙します。 としきさんの手元では特別問題にならないところが,くどいと感じるかもしれません。 ・ファイル先頭で実行してみたらさすがに無限ループになりました &nの戻り値で数字かそれ以外か判断できます。これくらいのエラーチェックは あっても良いのではないかと思います。 ・1発言だけ重複しているケースでは行ブロックになりません これもある意味で無限ループになっているのかな。 汎用性ということなら(このテキスト例ではおそらくありえませんが), 次行頭にカーソルを移動するときは,#x #< というコードは無限ループを 招くことが多いので,これを回避するために #> #d (r)?{ &m("EOFです") . } という風にするのがよく使われます。このマクロが無限ループを生じる 原因は別のところにありますが,少し気にしてみると吉かもです。 今日は遠くの葬式で疲れてますからこのへんで。
ども、いろいろとご多忙のところ、大変お手数をおかけしています。> …こんな感じ。(お手元と同じでしょうか>としきさん)同じでございます。 ただ、#3156にも書きましたとおり、行頭の空白は必要ですが、数字だけのテ キストファイルでもきちんと動作してくれると嬉しい、というのが期待する 仕様です。> ・ファイル先頭で実行してみたらさすがに無限ループになりました> &nの戻り値で数字かそれ以外か判断できます。これくらいのエラーチェックは> あっても良いのではないかと思います。なるほど、追加します。> ・1発言だけ重複しているケースでは行ブロックになりません> これもある意味で無限ループになっているのかな。ありゃ、本当だ。 以前はこれ、1行だけの行ブロックになっていたのです。 なんか、いろいろと手を加えているうちに何かを間違ってしまったようです。 これはマズイ。もう一度ロジックを検討します。 もしかしてこれは、謎の #39 の関係かな。> 次行頭にカーソルを移動するときは,#x #< というコードは無限ループを> 招くことが多いので,これを回避するために #> #d (r)?{ &m("EOFです") . }> という風にするのがよく使われます。このマクロが無限ループを生じる> 原因は別のところにありますが,少し気にしてみると吉かもです。御意見ありがとうございます。気にしてみたいと思います。
また少し考えてみました。 001 002 002 この行でエラー認識,この行よりも上を同じ番号まで削除したい #Gでカーソル位置は変わらない(&nも) つまりこの行は対象行に含まれないよう行ブロックする必要がある カーソル位置を動かさずに#rすれば行ブロックされる ただし,行の最初のフィールドの番号がヒットしたのか保証はない 判断する基準はおそらく桁位置しかない 変数 lx はあくまでも表示桁位置なので折り返しにヒットした可能性もある 変数 lh と表示桁数 we の積を加算すれば論理桁位置は特定できる 比較するのは移動前の桁位置なので保存する必要がある ブロックモードに入る 後方検索し,論理桁位置が合っていれば,そのままカット (左右に動かしていないので行ブロックになっているはず) 問題なのは重複開始と思われる番号が後方(上)にない場合 飛んで増えた番号がなかった場合の処理が難しそうです。
年度末は人事異動の季節。今日も送別会があったもので酔いどれています。 ちなみに、うちの会社、平均3年で人事異動があるのですが、私はすっかり 干されているもので、4月からは同じ仕事の7年生です。 あれ、もしかしたら8年生かな。 あまりに長いこと同じ事をやっているので、わけわからなくなりました。 単に酔いどれているせいかも。 さて。 いくつか思い出したことがありました。> ご存じない方のために例示すると,> −会議室16 :とくせつ:Ish□夢見る小さなプログラム 発言数 :1759 未読 :0−> <タイトル一覧>> 番号 ID 登録日 TO CO 題名> 801 HFD00076 11/13 22:25 0 発言者削除> 802 GCD00613 11/14 21:24 0 発言者削除 :修正版アップのため> 803 HFD00076 11/15 20:56 0 発言者削除> 804 QFF00306 11/15 21:55 0 【VZ】 VWX Ver 1.03c(差分)> …こんな感じ。(お手元と同じでしょうか>としきさん)コメント発言の場合、TO のフィールドに親発言の発言番号が入ります。 すると、場合によっては、第1フィールドといっていいのかな、最初のフィ ールドの発言番号と同じ番号が TO の欄に出てきます。そのため、うっかり 発言番号だけで検索をかけると、そちらが引っかかってしまったりします。 それを避けるために、私の最初のマクロでは、行頭に近い2つのフィールド、 つまり発言番号と発言者のIDの両方を使って検索をかけるようにしていた のです。 これら2つの情報を検索文字列に入れるために取った手段が カーソルを行頭に飛ばす 1単語右 検索文字列の連続取得を2回 という動作をキーボードマクロを使って取り出したわけです。 恐らく、これが私のマクロが妙であることの出発点。 現在、酔った頭で考えると、 カーソルを行頭に飛ばす 1単語右 ブロックモード 1単語右 を 2回 検索文字列の取得 とするべきであるような気がします。 もちろん、もっと良い方法はあるでしょう。 それから、発言者削除についてなんですが、私の持っている RMN により取得 したリストの場合、そもそもホストから送られて来ていませんでした。これ は、RMN だからなのかどうかは不明です。ただし、1994年の2月ごろ、発言 者削除の扱いが大きく変わったという事ですので、それ以前は表示されてい たけどそれ以後は表示されなくなった、ということはあるかもしれません。
なるほど,&24の 2回実行の意味がようやく解りました。 でも今回は汎用性 を持たせるために第 1フィールドのみの判定で所期の動作とするという仕様に 変化はないと考えてよいのですよね。 その後つらつら考えるに,第 1フィールドを基準とするのであれば,桁位置 なんて考えずに正規表現で検索してしまえばよいのではあるまいかと思い至り ました。 mi[-, mp[=2, RX[+, #< ;直前のカーソル位置に依存 (ct==2)?#f #G #F #e #< "^[\s\t]*" #m #r RX], mp], mi], (r)?{ マッチする文字列がなかったときの処理 } マッチしなかったときの処理を考え始めると,ドツボに填まるかもしれませ んね。後方検索する場合は,該当の番号がなければ &n で取得した数値をイン クリメントしながら探すということになるのかと思いますが,果たしてそこま でやる必要があるのやら,必要がなければどう処理するのかが悩ましいところ です。ただ,仕様が変更されて削除発言が表示されなくなったということは, 上のような心配はとりあえずないということになりますね。削除発言がそのま ま残りはしますが。> 恐らく、これが私のマクロが妙であることの出発点。もちろん, ID も取得すればより強固になることは間違いありませんので 妙ではありませんが,第1フィールドのみで動作するということを考えるなら ID が使えなくなるので,正規表現を使うのが残された道かと思います。
> なるほど,&24の 2回実行の意味がようやく解りました。 でも今回は汎用性> を持たせるために第 1フィールドのみの判定で所期の動作とするという仕様に> 変化はないと考えてよいのですよね。汎用性という事を考えれば、第1フィールドのみ、というのは動かせません。 が、元々は別目的で作っていたマクロをタイトル一覧に応用しようとして、 その上、ブロック化を行うような付加機能をつけている、というような成立 過程を考えると、そういう機能のタイトル一覧専用マクロを作ってしまうべ きではないか、という気もしています。> マッチしなかったときの処理を考え始めると,ドツボに填まるかもしれませ私も自分で色々考えているのですが、現在、はまっています。 とりあえず、以下のようなパターンでうまく行く事を希望しています。 その1:単調増加パターン 1001 1002 1003 1005 1006 1007 欠番があっても、何もなかったかのように正常終了すること その2:重複パターン 重複があった場合、上側をブロックして終了する事を希望 1001 1002 1003 1005 1004 1005 1006 1007 この例の場合、1003の次の1005がブロックされること その3:逆転パターン 1001 1002 1003 1005 1004 1006 1007 この場合も、単調増加パターンと同じく、何もなかったかのように正常終了 すること この、最後のパターン3の処理で、ちょっともがいています。 もしかしたら、簡単なうまい解決法が見つかりそうな気もしていますので、 もうちょっと遊んで見ます。
> この、最後のパターン3の処理で、ちょっともがいています。
> > この、最後のパターン3の処理で、ちょっともがいています。> いや,これを他のパターンと同じにするのは,かなり無理がありませんか?かなり無理があるようですね。 当初の要求条件であった「何もなかったかのように正常終了」というところ に問題があるので、素直に取り下げます。 新たな要求条件は「その場所がわかるように停止」という形にします。> あ,単純にソートすると後の方を消してしまう可能性があるのか。それもありますけど、タイトル一覧の場合、ユニークではそもそも消えてく れない場合がある、というのが問題でして。 #3157のリストではわかりませんが、「CO」の欄は付いているコメント数を表 しています。つまり、1回目のタイトル一覧取得の後、2回目の取得までの 期間にコメントがつくと、ここの値が変わってくるのです。こうなるともう ユニークでは消えてくれません。でも、行頭の発言番号と発言者IDだけを キーにすれば、うまく削除することも可能なような気がしています。 とりあえず、このツリーでこれまでに頂いたご意見を反映させたバージョン を以下に記しておきます。 72 [F13] "タイトル一覧番号順" ?. #< #f ;行頭の空白を無視して &n a=r, ;発言番号を数値で取得 (r==-1)?>c ;数字以外で実行時は終了 :a #> #d #f (r)?>c ;ファイル終端なら終了 &n b=r, ;次の発言番号を取得して (a<b)?{a=b, >a} ;番号が増加していればさらに次の行で同じ比較を実施 &s #b #f #f #G ;増加していなければ今度は文字列として発言番号を取得 #39 #c ;カーソルを画面上端に持っていきたいのかな? #x #c (r)?{#e} ;その発言番号が見つからなければカーソルを戻して #b ;ブロックモード d0, ;カウンタクリア :b #e #< #f &n c=r, ;重複部の始りまで、今度は上方向にカーソル移動 d++, ;重複部が何行かカウント (b<=c)?{>b} ;重複部が終了したら &d #x ;カーソルが行きすぎているので一つ戻し #B ;重複部の終了部分にカーソルを持ってくる (d==1)?{#x} ;1行重複の場合はさらに下 :c 謎の #39 は結局そのまま。 1発言だけの重複をブロック指定するためにカウンタを使っていますけど、 これはもっとスマートな方法があるような気がしています。だけど、以前は カウンタ等に頼らずに解決できていたような気がするのですが、もしかした らそれが気のせいというか記憶違いであるような気もしてきました。
> それは残念。
> でも、タイトル一覧のデータ構造がどのようになっているかはこの界隈の方
> 々にとっては自明だと思っているのですが、この認識は甘いでしょうか。
> どうも世の中には、キーボードマクロからマクロを作るようなことは絶対に
> ない、という方もいるようですが、私にはそのようなことは全くできません。
> 手は出さないけれど,口は出す,みたいな。
> それに,例えばMRE(ad)だけで自動運転させていたわたしのような者は,タイトル一覧を取得するなんてことは滅多になかったのです。