- PR -

subが2度呼ばれてしまう。

投稿者投稿内容
osa
会議室デビュー日: 2005/03/22
投稿数: 14
投稿日時: 2007-04-13 08:33
こんにちわ。
現在、業務で扱っているプログラムで動的配列を使っています。
そこで思いっきり行き詰まってしまったので、皆さんのお知恵をお借りしたく書き込みました。
久々にVBに触れるという事もあり、言っている事があべこべでしたらご指摘お願い致します。

問題となっている点を下記に記載します。

エラー原因:FileCopy()処理が2度呼ばれる事によってエラーが発生する
エラーコード:53
エラーメッセージ:ファイルが見つかりません。

なお、要点のみ文章としてますので、回答にお困りの点がありましたら、
ご質問していただけるとありがたいです。

@ファイルオブジェクトシステム関数を使用し、
 指定したフォルダ内に存在するテキストファイルのみ検索。
 そのテキストファイル名を動的配列に入れます。
Aファイルオブジェクトシステムを解放
B動的配列(0)にテキストファイル名が入っていたら、
 動的配列に入っているテキストファイル名をfor文により、
 1つづつ抜き出し、ファイルコピー処理に引数として渡す。
Cファイルコピー処理が正常に終了後、テキストファイル内に書かれたデータを
 データベースに正常登録後、テキストファイルを削除。


下記にソースを掲載致します。

====================================================
 ' ファイルシステムオブジェクト
 Dim fs As New FileSystemObject
 Dim f As File

 ' 動的配列の宣言
 Dim aryFileName() As String
 ReDim aryFileName(0)

 ' 指定したパスのフォルダに含まれるtxtファイルを挿入
 For Each f In fs.GetFolder("PATH").Files
   If UCase(fs.GetExtensionName(f.Name)) = "TXT" Then
     aryFileName(i) = f.Name

     ' 動的配列の添え字を増やす
     ReDim Preserve aryFileName(UBound(aryFileName) + 1)
     i = i + 1
   End If
 Next f

 ' ファイルオブジェクトの解放
 Set fs = Nothing
 Set f = Nothing

 If aryFileName(0) <> "" Then
   ' 動的配列の再定義
   ReDim Preserve aryFileName(UBound(aryFileName) - 1)

   ' クィックソート実行
   quicksort aryFileName, 0, UBound(aryFileName)

   ' 動的配列に挿入されたtxtファイル分、コピー&登録処理を行なう。
   For i = 0 To UBound(aryFileName)
     Call DataCopy(aryFileName(i)) ← この処理内でエラーが発生する。
   Next i
 End If

 ' 動的配列に使用したメモリの解放
 Erase aryFileName
====================================================

Bのfor文にて、ブレイクポイントを設定しデバッグモードで実行してみると
正常に終わり、ブレイクポイント無しで実行&実行ファイル(.exe)だと
エラーが発生するという状態です。

私なりに調べた事ですが、1回目の流れで問題なくテキストファイル名が引数として渡され、
コピー処理を行いデータベース登録後、コピー元のテキストファイルを削除された後
もう一度同じパスでファイルコピーを行なおうとしているようです。

急いで書いたもので説明不足な点があるかもしれませんが、
ご意見お待ちしております。
osa
会議室デビュー日: 2005/03/22
投稿数: 14
投稿日時: 2007-04-13 09:09
すみません。
開発環境について、書き込むのを忘れてしまいました。
追記致します。

開発ソフト:VB6
使用データベース:MSDE
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2007-04-13 09:13
引用:

osaさんの書き込み (2007-04-13 08:33) より:
私なりに調べた事ですが、1回目の流れで問題なくテキストファイル名が引数として渡され、
コピー処理を行いデータベース登録後、コピー元のテキストファイルを削除された後
もう一度同じパスでファイルコピーを行なおうとしているようです。


ってここまでわかっているならバグだということは認識できてるよね?
デバッグしなよ。配列の中身が君の思ったとおりになってなきゃバグでしょ?

ステップ実行によるデバッグができるんだからウォッチ式とか使って調べなよ。

[ メッセージ編集済み 編集者: ぶさいくろう 編集日時 2007-04-13 09:14 ]
osa
会議室デビュー日: 2005/03/22
投稿数: 14
投稿日時: 2007-04-13 11:14
引用:

ぶさいくろうさんの書き込み (2007-04-13 09:13) より:
ってここまでわかっているならバグだということは認識できてるよね?
デバッグしなよ。配列の中身が君の思ったとおりになってなきゃバグでしょ?

ステップ実行によるデバッグができるんだからウォッチ式とか使って調べなよ。

[ メッセージ編集済み 編集者: ぶさいくろう 編集日時 2007-04-13 09:14 ]



ご意見ありがとうございます。
配列の中身は、私の想定した通りの内容が入っています。
コピー&登録処理についても、エラー処理を施し問題が発生すれば、イミディエイトに表示する形にしていました。
ぶさいくろうさんのおっしゃっていたウォッチ式を試してみたのですが、
こちらを使ってみましても、同じような現象が発生していました。

その後、コンパイルの方法を変更してみる事を試してみたのですが、
下記@の状態をAに変更しましたら、プログラムが正常処理されるようになりました。
何か関係があるのでしょうか?

@エラーが発生時
 ネイティブ コード コンパイル
  コードの実行速度を最適化を選択

A正常処理時
 ネイティブ コード コンパイル
  コードのサイズを最適化を選択

ご意見お待ちしております。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-04-13 11:35
引用:

osaさんの書き込み (2007-04-13 08:33) より:
   ' クィックソート実行
   quicksort aryFileName, 0, UBound(aryFileName)

   ' 動的配列に挿入されたtxtファイル分、コピー&登録処理を行なう。
   For i = 0 To UBound(aryFileName)
     Call DataCopy(aryFileName(i)) ← この処理内でエラーが発生する。
   Next i


引用:

osaさんの書き込み (2007-04-13 11:14) より:
その後、コンパイルの方法を変更してみる事を試してみたのですが、


コンパイラーの最適化のバグ?とも一瞬思ったのですが、怪しいところはほかにもありそうに思います。アプリケーションコードのバグを疑うとすると、「クィックソート実行」がもっとも怪しいです。クイックソートの実行結果が、最適化の有無で異なっているのではないでしょうか?なんらかの方法で、クイックソートとそれ以外を切り分けてみてはどうでしょうか。たとえば、クイックソートの結果を Debug.Print するなどしてみて、最適化の有無で結果が異なるかをみるなどです。

また、件名には「subが2度呼ばれてしまう。」と書かれていますが、問題としては、意図しないのに sub がいつのまにか2度呼ばれてしまうのか、それとも sub に同じ引数を渡して明示的に2度呼んでいる(結果的に同じ引数で2度呼ばれてしまう)のか、のどちらでしょうか?

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
osa
会議室デビュー日: 2005/03/22
投稿数: 14
投稿日時: 2007-04-13 11:45
引用:

unibonさんの書き込み (2007-04-13 11:35) より:
コンパイラーの最適化のバグ?とも一瞬思ったのですが、怪しいところはほかにもありそうに思います。アプリケーションコードのバグを疑うとすると、「クィックソート実行」がもっとも怪しいです。クイックソートの実行結果が、最適化の有無で異なっているのではないでしょうか?なんらかの方法で、クイックソートとそれ以外を切り分けてみてはどうでしょうか。たとえば、クイックソートの結果を Debug.Print するなどしてみて、最適化の有無で結果が異なるかをみるなどです。

また、件名には「subが2度呼ばれてしまう。」と書かれていますが、問題としては、意図しないのに sub がいつのまにか2度呼ばれてしまうのか、それとも sub に同じ引数を渡して明示的に2度呼んでいる(結果的に同じ引数で2度呼ばれてしまう)のか、のどちらでしょうか?

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}



ご意見ありがとうございます。

まず、ご質問にお答えします。
「意図しないのに sub がいつのまにか2度呼ばれてしまう」が私の見解です。

unibonさんの怪しいと思われているクィックソートは会社でのテンプレートを
そのまま、このプログラムに当てはめているので私としてもノーマークでした。
調べてみますので、結果は後ほど書き込みます。
osa
会議室デビュー日: 2005/03/22
投稿数: 14
投稿日時: 2007-04-13 13:36
unibonさん、お待たせしました。
クイックソートの検証の結果、問題ないと思います。
念のため、コードを掲載しておきます。

=========================================================================
' クィックソート処理
Function quicksort(strArray() As String, first As Integer, last As Integer)
Dim point, f, l, tmp
point = strArray(first)
f = first: l = last
Do
While strArray(f) < point: f = f + 1: Wend
While strArray(l) > point: l = l - 1: Wend
If f >= l Then Exit Do
tmp = strArray(f): strArray(f) = strArray(l): strArray(l) = tmp
f = f + 1: l = l - 1
Loop
If first < f - 1 Then quicksort strArray, first, f - 1
If l + 1 < last Then quicksort strArray, l + 1, last
End Function
=========================================================================

会社のテンプレートと書きましたが、どこにでもあるサンプルだと思います。
もし、何かお気づきの点がありましたら、ご意見お待ちしております。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2007-04-13 13:51
>私なりに調べた事ですが、1回目の流れで問題なくテキストファイル名が引数として渡され、
>コピー処理を行いデータベース登録後、コピー元のテキストファイルを削除された後
>もう一度同じパスでファイルコピーを行なおうとしているようです。

とあったのでああやって書いたんだけど・・・
普通こんなので考えられるのって配列の中身が意図していないか。
はたまた自分の思ったとおりの制御フローを通っていないかでしょ?
実際のところどういう経路で2回実行されるのか書いた方がいいんじゃない?

P.S.
デバッグ実行しているならコンパイラの最適化による不具合の心配はないと思われ。

スキルアップ/キャリアアップ(JOB@IT)