過去の桐井戸端BBS (桐ver.9)
25330 「#ファイル検索」関数でファイル名を取得しようとしましたがうまくいかない 大野達郎 2004/03/09-16:53
#ファイル検索の挙動についての質問です。
一括ファイルあるフォルダの一つ下に「納品」フォルダがあり、その中にtblがいくつかあるとします。
そのtblを扱う、以下の様な一括を組みました。

1:&件数=0
2:繰り返し
3: &件数 = &件数 + 1
4: &STR = #ファイル検索("納品\*.TBL", &件数)
5:*メッセージボックス #str(&件数, 2), &STR
6: 条件( &STR = #未定義 ) 繰り返し中止
7: 表 &STR, 表番号 = 1
8: 終了 表 1
9:繰り返し終了

この結果、&件数=2 の時に&STRが未定義になりループを抜けてしまいます。
(5行目のメッセージボックスによる確認)
なぜ、#ファイル検索で&STRに2個目以降のファイル名が埋まってくれないのでしょうか?

後、不思議なことに7行目と8行目をコメントアウトすると&STRの中身は正常に埋まり、
ループは納品フォルダの中のtblの数だけ回るようです。

業務的には7行目と8行目の間で色々処理を行いたいのですが・・・
ご協力、お願い致します。

25333 Re:#ファイル検索の挙動 T.Samura 2004/03/09-18:21
記事番号25330へのコメント
 大野達郎さん、こんにちは。

 私もこれで失敗しました。
 >7: 表 &STR, 表番号 = 1
 >8: 終了 表 1
これがファイル操作にあたりファイルの並び順が変わり、以降の#ファイル検索()の動作は
新たな並び順にそった返り値なので最初の並び順とは違ってきます。
不定値と言ってもよいと思います。

 どうすれば良いかというとファイルリストを作る処理とリストされたファイルに対する処理を分けます。
 一括処理の詳細は省きますが、まず別フォルダにリスト用の表を用意し#ファイル検索()の結果を全て記録します。
その後リスト用の表を1コードずつ読んで該当表を開いて処理をします。

25341 Re:#ファイル検索の挙動 悲しげ 2004/03/09-22:42
記事番号25333へのコメント
私は次のようなやり方をすることがあります。こうすれば、
ずれないし且つ別フォルダを使う必要もなさそうです。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
&i=1,&TBLs=""
繰り返し
 &TBL=#ファイル検索("*.TBL",&i)
 cond(&TBL="") 繰り返し中止
 &TBLs=&TBLs+","+&TBL
 &i=&i+1
繰り返し中止
if(&TBLs)
 &TBLs=#sstr(&TBLs,2),&i=1
 繰り返し
  &TBL=#対応文字列(&TBLs,&i)
  cond(&TBL="") 繰り返し中止
  表 &TBL
  &表No=#is表  /*編集表の変更があり得るのなら*/
  ・・・・
  終了 表 編集対象表 /*または 終了 表 &表No */
  &i=&i+1
 繰り返し終了
end
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

難点は、フォルダの階層が深く(と云うかパス名が長大で)且つ
表ファイル数が多すぎたら、変数「&TBLs」が文字数オーバーで
パンクしてしまうこと。(^^;)

25342 Re:#ファイル検索の挙動 悲しげ 2004/03/09-22:48
記事番号25341へのコメント
訂正。

> ・・・・・
> &TBLs=&TBLs+","+&TBL
> &i=&i+1
>繰り返し中止  ← 「繰り返し終了」ですた。(^^;)
>if(&TBLs)
> ・・・・・

他にも不具合はあるかもしれませんが、とりあえず。(^^;)
25343 Re:#ファイル検索の挙動 うにん 2004/03/09-22:55
記事番号25341へのコメント

>繰り返し
> &TBL=#ファイル検索("*.TBL",&i)
> cond(&TBL="") 繰り返し中止
> &TBLs=&TBLs+","+&TBL
> &i=&i+1
>繰り返し中止

こういうときに、#文字置換(&TBLs,&i,&TBL)という形式が使えます。
(効率がいいかは別として^^;)

>難点は、フォルダの階層が深く(と云うかパス名が長大で)且つ
>表ファイル数が多すぎたら、変数「&TBLs」が文字数オーバーで
>パンクしてしまうこと。(^^;)

あとは、#対応文字列はパス名に「,」が入ってる場合まずいですね。

25351 Re:#ファイル検索の挙動 佐田 守弘 2004/03/10-00:03
記事番号25333へのコメント
大野達郎さん、T.Samuraさん

私もこれで悩まされた一人です(詳しくは後述)。
原因と対策はT.Samuraさんが書いている通りですが、少し補足します。

関数「#ファイル検索」の戻り値となるファイル名は、名前などで整列された順序での
指定番号のファイル名ではなく、OSが管理しているファイル一覧に
登録されている順序での指定番号のファイル名です。

桐の場合、バックアップありで開くと、元の表からテンポラリファイルを作ります。
そして表を閉じる時に、以前のバックアップ(.bak)を削除し、
元の表をバックアップにリネームしてからテンポラリファイルを表ファイルにリネームします。

つまり、編集の前後で同じファイル名であっても、別のファイルですから、
ファイル一覧の登録場所は変化します。

対策としてもT.Samuraさんが書いているとおり、予め全ファイルをリストアップし、
リスト表に書き出すか、配列変数に書き込んでおいて、
順に処理するのが良いかと思います。
悲しげさんの方法も、記録の方法が違うだけで、同じ考え方ですね。

佐田守弘(KS-00119)

ps:私の失敗談
写真ファイルの一覧を#ファイル検索関数を使って、上から順に所定のファイル名にリネームしようとしました。
しかし何と、ファイルの一部しかリネームされていませんでした。
なぜかある個数飛びにリネームができていたので、最初考えた原因は、
リネームに時間が掛って、飛ばされてしまうのではないか、でした。
遅延コマンドで遅延時間を入れても改善されず、ようやくたどり着いた結論が、
ファイル操作をすると順序が変わってしまうらしいという事でした。
管理工学に確認した結果、上記の様にOSが管理する順序でファイル名を取得しているとの事でした。

この関数に第2のパラメータを指定すれば、ファイル名順、作成日時順などでソートした順番で
ファイル名を取得できるようにして欲しいですね。
25367 Re:#ファイル検索の挙動 大野達郎 2004/03/10-14:57
記事番号25330へのコメント
T.Samuraさん、悲しげさん、うにんさん、佐田 守弘さん
毎度ながらすばらしく早いレス、本当にありがとうございます。

結論として、先にリストを作成するのがベストのようですね。
こちらは配列変数を用意してそこに格納する形をとりました。

色々書き方を微妙に変えて分かったことが、一つあります。

> 1:&件数=0
> 2:繰り返し
> 3: &件数 = &件数 + 1
> 4: &STR = #ファイル検索("納品\*.TBL", &件数)
> 5:*メッセージボックス #str(&件数, 2), &STR
> 6: 条件( &STR = #未定義 ) 繰り返し中止
> 7: 表 &STR, 表番号 = 1
> 8: 終了 表 1
> 9:繰り返し終了

4行目にてファイル検索の指定を相対パスで指定していましたが、
これだと、7行目の時点でデータパスが変化してします。
よって、2回目のループでの4行目の検索は
「納品」フォルダ内の「納品」フォルダを調べようとしているようで
当然、無い為、&STR は未定義になるようです。
よって、パスを絶対パスにするか、
ループ終了時にでもデータパスを戻すとかすれば回避できるパターンもあるようです。
7行目、8行目をコメントアウトしてループが回るのはそのせいだったようです。

ですが、やはりファイルの増減、ファイル名変更とかには対応できないようなので
結局は皆様のようにリストを作るのが良い方法のようです。


戻る