過去の桐井戸端BBS (桐ver.9)
25283 OCR変換後のCSVデータを監視してデータ蓄積をしたい あたる 2004/03/06-15:37
OCRソフト(読んで!!ココ)で,ある特定のフォルダに"認識結果.CSV"を作成し,
桐でこのフォルダに生成される"認識結果.CSV"を監視して,
次々に生成されるファイルを表にファイル変換して蓄積する処理を考えていますが,
行き詰まっております。

以下のような印刷物(10000枚前後)

所在    地番
A市B町  123-1
A市B町  123-2
  ・    ・
A市C町   1
A市C町   2-1
  ・    ・
  ・    ・

これを当初,一括処理中でループを回し,

繰り返し
 IF (#ファイル検索("認識結果.CSV",1)
  ファイル複写 "認識結果.CSV","SCANTEMP.CSV"
  ファイル削除 "認識結果.CSV"
  ファイル変換 CSV,"SCANTEMP.CSV","SCANTEMP.TBL"
    ・
    ・
  B町,C町それぞれの表ファイルに地番書き出し処理
   ・
    ・
  ファイル削除 "SCANTEMP.TBL"
 END
繰り返し終了

と考えたのですが,ループから抜けるためのトリガーを
どのように組み込んだらよいか思いつかず,
フォームのイベント処理でやったらどうかとも思ったのですが,
一括処理から フォーム呼び出し "OCRデータ監視,WFM"
として,”監視開始ボタン"を実行してループにはいると
”監視終了ボタン”のイベントが発生しないようです。
一括処理中と同じようにループ中になにかトリガーを
設けないとだめのようですが,良い方法が思いつきません。
どなたかお知恵を拝借できませんか?
よろしくお願いいたします。


25290 ループ終了のトリガ 佐田 守弘 2004/03/06-23:03
記事番号25283へのコメント
あたるさん
実際に行っていないのですが、次の様な方法を試してみてはいかがでしょうか。
ただしあくまでも思いつきで、うまく行くかは解りません。

●ループ終了をフラグで判断する
一括処理のループを一部以下の様に直してみて下さい。

 代入 &ループ=1
 繰り返し (&ループ=1)

要するに、変数「&ループ」の値が1である間の繰り返しとします。
そして、キーダウン、あるいはマウスクリックなどのイベントを使って、
終了操作の手続きを呼び出したら、その手続きの中で、&ループに0を代入します。
これで繰り返しのループを終了するだろうと思います。
ただし、一括処理の実行中にイベントが動作するかどうかが自信がありません。

●タイマイベントを使うのが良いのでは
実は、今考えておられる方法で行いますと、一括処理の中でループを回すので、
CPUの負荷がかなり掛ります。
おそらくこれによってスキャナでの読み取りや、OCR処理も極端に遅くなっているのではないかと思います。

そこで、ループを回すのではなくて、タイマイベントを使って、一定時間毎にファイル検索を行い、
認識結果のファイルが存在するかどうかのチェックをした方が、速度も格段に上がると思います。

スキャナで読み取ってOCR処理を行うのですから、おそらくは、10秒とか、
あるいは1分ごとのチェックでも良いのではないでしょうか。

この方法であれば、終了のトリガは不要で、メニューのフォームを閉じれば良いだけです。

佐田守弘(KS-00119)

ps.タイマイベントは私はほとんど使いません。
後はタイマイベントのプロの方にフォローをお願いします。
25294 Re:ループ終了のトリガ あたる 2004/03/07-04:18
記事番号25290へのコメント
こんにちは、佐田 守弘さん

今回、件の処理を含むその他の処理を一括処理で作成するために
ここのところ、過去の井戸端BBSをはじめ、ROMさせていただいておりました。
いつも、懇切丁寧にアドバイスしておられ、敬服いたします。
また、お返事をいただきありがとうございます。

>実際に行っていないのですが、次の様な方法を試してみてはいかがでしょうか。
>ただしあくまでも思いつきで、うまく行くかは解りません。
>
>●ループ終了をフラグで判断する
>一括処理のループを一部以下の様に直してみて下さい。
>
> 代入 &ループ=1
> 繰り返し (&ループ=1)
>
>要するに、変数「&ループ」の値が1である間の繰り返しとします。
>そして、キーダウン、あるいはマウスクリックなどのイベントを使って、
>終了操作の手続きを呼び出したら、その手続きの中で、&ループに0を代入
>します。
>これで繰り返しのループを終了するだろうと思います。
>ただし、一括処理の実行中にイベントが動作するかどうかが自信がありません。


どうも、ループ処理中に他のイベントはさすがに発生しないのではないか、
と感じているのですが、というのも、この処理に取り組んでからはいつも、
SHIFT + BREAKで中止するしかなくなってしまいますから <(^^;
フォームを開いて監視開始ボタンでループを実行すると、監視終了ボタン
(閉じる)でフォームを閉じることができないけれど、フォームを開いて
すぐ監視終了ボタンをおすと、それが機能するということは他のイベント処理(ループだから?)
実行中は目的のイベントは実行できないってことですよね?
イベントなんだからどんな時も同時多発的に発生してほしいけど・・・



>●タイマイベントを使うのが良いのでは
>実は、今考えておられる方法で行いますと、一括処理の中でループを回すので、
>CPUの負荷がかなり掛ります。
>おそらくこれによってスキャナでの読み取りや、OCR処理も極端に遅くなって
>いるのではないかと思います。
>
>そこで、ループを回すのではなくて、タイマイベントを使って、一定時間毎に
>ファイル検索を行い、認識結果のファイルが存在するかどうかのチェックを
>した方が、速度も格段に上がると思います。


確かに、ループを回しっぱなしっていうのは負荷がかなりかかっているようです。
アドバイスをいただいた、タイマイベントを使う方法で、やってみます。
また、結果をご報告いたします。ありがとうございました。

あたる
25304 Re:ループ終了のトリガ 佐田 守弘 2004/03/07-20:13
記事番号25294へのコメント
あたるさん
試しに簡単なループテストを作ってみました。
やはり予想通り、ループの繰り返しに入ってしまうと、イベントは有効にならない様です。

イベントはフォーム編集が行われている間でしか有効ではない様ですね。
というか、そもそもイベントはフォームがアクティブになっていて、
そこで何かの操作を行う事をチェックしている機能の様です。
フォームから呼び出された手続きが行われている間は、制御はそのプログラムの方に移ってしまっていて、
フォームは単に表示が残っているだけの状態の様です。だからイベントも発生しないのだろうと推定されます。

「イベントで処理している間は、処理が終るまで待て」という事なのでしょうか。

いずれにしても解決策は処理速度の点で考えても、ループで回すべきではないと思います。

●コマンドでキーの押下が拾えれば
かつて、BASICでプログラミングしていた頃の話ですが、キー押下を拾うには
確かinmput$を使ったような記憶が残っています。またリアルタイムゲームの様にキーが押されているかどうかを
判断するためにIOポートを直接読み出す方法もあった様に記憶します。

イベントを使えばこういったことは可能なのですが、キー入力機能のコマンドで
入力待ちなしに、キー押下を拾う方法はない様ですね。

佐田守弘(KS-00119)
25366 Re:ループ終了のトリガ あたる 2004/03/10-14:51
記事番号25304へのコメント
こんにちは 佐田さん
度重なるコメント ありがとうございます

>試しに簡単なループテストを作ってみました。

お時間を割いていただき恐縮です。
私は今回の処理に手をつけるまではイベントを使ったことがほとんどありませんでした。
佐田さんのホームページやこの掲示板を読ませていただいて、すこしずつ処理を書けるようになっておりますが、
桐9のヘルプだけでは桐5のマニュアルのような具体的な記述例が少なく、
とても私にはマスターできないと痛感しております。

>いずれにしても解決策は処理速度の点で考えても、ループで回すべきではないと
>思います。

佐田さんの云われるとおりですね。おかげさまで、タイマーイベントで目的の処理を作ることができました。
今回の処理は一括処理からイベント定義したフォームを開き、一時ファイルを作っておいて、
それから一括処理に戻って後処理をするようにしたので、
イベント処理に要する時間はそれほどではないと思っていますが、
イベント発生の時間間隔より、タイマーイベントで発生した処理に要する時間が、
長い場合、次のタイマーイベント発生がかぶってくるのか、どうかが頭に引っかかっています。
佐田さんにテストしていただいたようにイベントでのループ処理中に
他のイベントが発生しないことを考えると、タイマーイベントも中断するのではないかと感じていますが、
時間があればテストしてみたいと思っています。


>●コマンドでキーの押下が拾えれば
>かつて、BASICでプログラミングしていた頃の話ですが、キー押下を拾うには
>確かinmput$を使ったような記憶が残っています。またリアルタイムゲームの様に
>キーが押されているかどうかを判断するためにIOポートを直接読み出す方法も
>あった様に記憶します。

私は、いわゆるプログラミング言語の素養がないので、漠然としたイメージしかありませんが、
シェル実行コマンド等を使用して、そのような低(高?)レベルの制御が、できるのでしょうか?
たとえば、他の言語で作った処理とのあいだで、
値の受け渡しを行い、一体として桐で作ったシステムに仕上げるとか・・・
今回のOCRのデータ処理も、OCRエンジン等を利用して、桐からの制御が
もしかしたら、できるのかな?というようなことも(漠然と)考えていました、
予算がないので考えたそばから自分で却下しましたが・・・ <(^^;

>イベントを使えばこういったことは可能なのですが、キー入力機能のコマンドで
>入力待ちなしに、キー押下を拾う方法はない様ですね。

あっ!一括処理実行ウィンドウを使用するという前提であれば、機能キー入力コマンドを使用して、

変数 整数{&key},
繰り返し
  機能キー入力 (1,1)プロンプト="監視中止はESCキーを押してください",\
入力待ち=しない,&key
  条件 (&key=27) 繰り返し中止
繰り返し終了

という方法があったのですね。佐田さんにヒントをいただくまでは思いつきません
でした。ただ、外見と負荷が問題ですね。どちらにして、佐田さんにアドバイスを
いただいたタイマーイベントを使うことにはかわりありません。
いろいろ、ご指導いただきありがとうございました。
今後とも、よろしくお願いいたします。

25377 タイマイベント他 佐田 守弘 2004/03/10-20:58
記事番号25366へのコメント
あたるさん
まず、
 >次のタイマーイベント発生がかぶってくるのか、どうかが頭に
 >引っかかっています。
について言えば、心配する必要はないと思います。むしろ、タイマの間隔をどの程度
にするのが効率的なのか、およびそれ以外の点について補足します。

●タイマイベントのかぶり
なさそうですね。ヘルプによると、タイマイベントは、
 >または他のイベントハンドラが実行中のときは発生しません。
と明記してあるので、OCR処理したテキストを桐の表に取り込んでいる間は発生しないと思います。

●タイマの間隔に関連して、取り込み処理に掛る時間は
おそらくこれは関心事だと思います。これを調べるアイデアを提示しますので、試してみて下さい。
・処理中表示のオブジェクト:テキストオブジェクト、ラベルオブジェクトあるいは
ランプの様に赤い色の円オブジェクトでも何でも構いません。
これを作って非表示にしておきます。
そしてCSVの取り込み処理には入る前に、オブジェクト操作コマンドを使って表示に
切り替え、終ったら再び非表示に戻します。
この表示ランプをフォーム上につけておけば、「ただ今取り込み中」が解ります。

あるいは開始時に#日時値の値を日時型の変数に代入し、終ったらその時の日時値の値からこれを減算すれば、
処理時間が得られます。
この処理時間を上記のランプの代りに表示しても良いでしょう。

テストの意味だけでなく、状態監視のために作っておいても良いかと思います。

●適切なタイマ間隔の設定
タイマの間隔は、上記の取り込み処理時間より少し長く、かつ、スキャナからOCR処理の時間よりも短くするのが良いのですが、
最適値はそのシステムでやってみないとわかりません。
最も好ましいのは、タイマ間隔を自由に設定できるようにするのが良いかと思います。
タイマ間隔の表示と増減させるコマンドボタンを組み合わせれば、
タイマ間隔の自由な設定が可能です。

設定値は、オブジェクト操作 ハンドル= @フォーム.タイマー値1 = "10.00"の様なコマンドを使って、設定できます。

●取り込み処理について
始めからこの部分については書かれておりましたが、論点がループの抜け出しのトリガにあったので、
言及しておりませんでした。
今見直してみると、効率的でない気がする部分があります。
・認識結果ファイルの複写
 これはファイル名変更で良いのでは。その方が速いと思います。
・CSVから表ファイルへの変換
 同じ形式(項目並びが同じと言う意味)のCSVでしたら、表ファイルに変換するのではなく、
 表に読み込んだ方が速いと思います。
その他、
 >B町,C町それぞれの表ファイルに地番書き出し処理
の意味が解りませんが、ここも何かしら単純化して速度アップができるのではと思うのですが。
どの程度のデータを読みのか、PCはどの程度の能力かが解りませんが、
うまく作れば、1秒以下で処理できる事もあり得ると思います。
その意味で、最初に述べた「ただ今取り込み中!」ボタンを作っておく事には意味があると思います。
要するに自分自身で問題点を発見して改善する切っ掛けにするわけです。

●スキャナからOCR
この部分はどうされていますか。シェル実行で「読んde!!ココ」を起動しても、その後の操作は手動になります。
ダイアログでの操作を自動化するプログラムを作る方法はあるのですが、そちらの方は私も得意ではありません。

この部分はhidetakeさんが詳しいと思います。

佐田守弘(KS-00119)
25421 Re:タイマイベント他 あたる 2004/03/12-19:25
記事番号25377へのコメント
佐田 守弘さんこんにちは 度重なるコメントまことにありがとうございます。

>●タイマの間隔に関連して、取り込み処理に掛る時間は
>おそらくこれは関心事だと思います。これを調べるアイデアを提示しますので、試して
>みて下さい。

ラベルオブジェクトの背景をイベント処理中に赤くするようにしてみましたが、
OCR変換したCSVファイルが1Kb以下のサイズしかないため、
処理に要する時間が短く、目をこらしても、確認できませんでした。
このため、変換したファイルをためておいて、一括処理に戻って、
後処理をと考えておりましたが、これも、イベント処理内部に戻してしまいました。
この状態で、処理にかかる時間を表示する、ラベルオブジェクトを配置し、
佐田さんにアドバイスいただいた、処理時間を表示するフォームに書き替えました。
1秒でした (^^;

>タイマ間隔の表示と増減させるコマンドボタンを組み合わせれば、タイマ間隔の自由な
>設定が可能です。

佐田さんにアドバイスいただいたとおり、このコマンドボタンと、
タイマー値を表示するラベルオブジェクトも付けさせていただきました。
フォームの再定義を要せずに変更できるのは便利ですね。

>今見直してみると、効率的でない気がする部分があります。
>・認識結果ファイルの複写
> これはファイル名変更で良いのでは。その方が速いと思います。

仰るとおりですね。これも、変更させていただきました。

>・CSVから表ファイルへの変換
> 同じ形式(項目並びが同じと言う意味)のCSVでしたら、表ファイルに変換するのではなく、
> 表に読み込んだ方が速いと思います。

これについては書き出す表の行制約式の関係、変換した表ファイルに項目属性変更コマンドで、
項目を追加している等の事情があるため、直接の読み込みとはしておりません。

項目属性変更2 追加,{"親番",整数,,,"#cond(#文字位置([地番],""-""),\
#num(#sstr([地番],1,#文字位置([地番],""-"")-1)),1,#num([地番]))"}

等ですが、ハイフン(-)をダブルクォーテーション2個でくくらなければいけないことに
気が付くのに1日かかってしまいました (^^;

>その他、
> >B町,C町それぞれの表ファイルに地番書き出し処理
>の意味が解りませんが、ここも何かしら単純化して速度アップができるのではと思うの
>ですが。どの程度のデータを読みのか、PCはどの程度の能力かが解りませんが、うまく
>作れば、1秒以下で処理できる事もあり得ると思います。

今回の作業は2年に分けて処理を行いますが、合計で約50万行、1年分で約25万行を予定しています。
2年間で1市全域という感じでしょうか。
これを地番区域(○○町○丁目)ごとに同じ構造のファイルでデータを蓄積し、その後の作業で使用します。
OCRで読みとる1枚分のデータはたかだか24行(640byte程度)ですが、
枚数が1万枚にも及ぶため、なんとかできないかと、今回の処理を思い立ちました。
データがあればこんな苦労はいらないのに(T_T)
以前は、手入力で地番を入力していたのですが、
オペレータの負担軽減も考えて・・・

>要するに自分自身で問題点を発見して改善する切っ掛けにするわけです。

仰るとおりですm(_ _)m

>●スキャナからOCR
>この部分はどうされていますか。シェル実行で「読んde!!ココ」を起動しても、その後
>の操作は手動になります。

これは、「読んで!!ココ」の事ではなく、30万円位〜(ランタイムは価格応談だったような・・・)の
OCRエンジンと呼ばれる別製品がありまして、
私はそのようなものを今まで使ったことがあるわけではないのですが、
言語からOCR機能を呼び出して使えるライブラリのようなものではないかと認識していたのですが
(もしかしたら違うかも(^^;)。
言語を覚えて使うのが本筋なのでしょうが、
桐でことによったらできないのかな〜と漠然と考えておりました。

今回、佐田さんにアドバイスいただいたおかげで、すこし高いハードルを
飛べるようになったような気がします。
また、お気づきの点がございましたら
ご指導いただきますようお願い致します。
ありがとうございました。

あたる

戻る