tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルIDEノーエラー,exeにてエラー。 その他1件
記事No16073
投稿日: 2015/01/30(Fri) 16:52
投稿者まさお
まさお と申します。 宜しくお願い致します。

 WinXP Pro SP3  VB6 SP6 です。

 下記コードはフォームモジュールに記述しました。

質問1)
 Sub Command1_Clickは統合開発環境(IDE)ではエラーになりません。
 しかし実行ファイル(.exeファイル)を作って実行するとエラー番号:10「配列が固定されているエラー」が発生します。
 回避方法は※βを※γに変更すれば良い、とは判っています。
 しかしIDEで出ないエラーが何故実行ファイルで出るのか? IDEで出すにはどうすれば良いか? を教えて戴きたくお願い致します。


質問2)
 ※αのRemを解除するとIDEでは問題ありませんが(エラーが出ないので)、実行ファイルでは無限ループに陥ります。
 1) Exit Sub or End Sub で「配列が固定されているエラー」が発生。
 2) On Error GoTo により ErrorSub にジャンプ。
 と、ここまでは判るのですが、ErrorSub にジャンプ後の End Sub で再度 ErrorSub にジャンプ,… を繰り返す事により無限ループに陥ります。
 Sub Command2_Click() のように On Error GoTo でジャンプした後に発生したエラーでは On Error GoTo は無効になるはずですのに、何故 On Error GoTo が効き続けるのか? を教えて戴きたくお願い致します。


蛇足
 Sub Test, f_Test の中身(何故こんな事をしているのか?)は無視してください。
 これはあるexeプログラムで無限ループが発生し『IDEでは発生しないが exe で発生する』の原因を探るためエラー発生とは無関係な部分を省略した結果ですので、省略部が無ければ何の意味の無いエラーが発生するだけのコードです。


以上、宜しくお願い申し上げます。

====================以下、フォームモジュール内コード
    Private Type Type_T
        flg As Boolean
    End Type

Private Sub Command1_Click()
    Call Test
    MsgBox "Comp"
End Sub

Private Sub Test()
    Dim Ct  As Long

    Rem     On Error GoTo ErrorSub  ※α
    '↑厳重注意! Rem解除するとExeにて無限ループに陥る。
    
    Dim DimTs(0) As Type_T
    Call f_Test(DimTs)
    
    Call SaveString("ExitSub")
    Exit Sub

ErrorSub:
    Ct = Ct + 1
    Call SaveString("ErrCt:" & CStr(Ct) & " " & Err.Description)
    '↑動作履歴を診る為に経過を保存。
End Sub

    Private Sub f_Test(ByRef DimTs() As Type_T)
        Dim i As Long
        
        DimTs(0).flg = True
        Do While True
            For i = 0 To UBound(DimTs)
                With DimTs(i)             '※β
                    If .flg Then Exit For '※β
                End With                  '※β
                Rem If DimTs(i).flg Then Exit For '※γ
            Next
            If UBound(DimTs) < i Then Exit Do
            DimTs(i).flg = False
        Loop
    End Sub

    Private Sub SaveString(ByVal sString As String)
        Dim FSO As New FileSystemObject
        With FSO.OpenTextFile("hoge.txt", ForAppending, True)
            .WriteLine sString
            .Close
        End With
    End Sub

Private Sub Command2_Click()
    Dim i   As Integer
    
    On Error GoTo ErrorSub
    i = CInt("123456789123456789") '<=オーバーフローエラー
    MsgBox "Comp2"
    Exit Sub
    
ErrorSub:
    MsgBox "Error!!!:" & Err.Description
    i = CInt("123456789123456789") '<=再度オーバーフローエラー ErrorSubには飛ばない

End Sub
====================以上、フォームモジュール内コード

[ツリー表示へ]
タイトルRe: IDEノーエラー,exeにてエラー。 その他1件
記事No16074
投稿日: 2015/01/31(Sat) 08:06
投稿者花ちゃん
実際の動作とコードを見て見ないとはっきりとは解りませんが?
投稿されたコードからだと。

>  回避方法は※βを※γに変更すれば良い、とは判っています。
違うのでは。

>     Dim DimTs(0) As Type_T
>     Call f_Test(DimTs)

1 個の配列しか宣言されていない(配列でないのと同じ)
従って、エラー番号:10「配列が固定されているエラー」

>                 With DimTs(i)             '※β

なのに、複数の配列を参照している。
IDE でもそこを複数回通るならエラーがでているはずです。

[ツリー表示へ]
タイトルRe^2: IDEノーエラー,exeにてエラー。 その他1件
記事No16075
投稿日: 2015/02/01(Sun) 21:32
投稿者まさお
花ちゃん さん、ありがとうございます。

> 違うのでは。
>
 イイエ。

> > Dim DimTs(0) As Type_T
> >
 にて配列個数 1つにしたのには意味はありません。
 DimTs(1) でも DimTs(9) でも DimTs( ... ) でもこのエラーは発生します。


 『これはあるexeプログラムで無限ループが発生し … エラー発生とは無関係な部分を省略した結果』と書きましたが、元プログラムでは配列個数は数百のレベルです。


引き続きアドバイス戴ければありがたいです。

[ツリー表示へ]
タイトルRe^3: IDEノーエラー,exeにてエラー。 その他1件
記事No16076
投稿日: 2015/02/02(Mon) 07:33
投稿者花ちゃん
> イイエ。
Do While True 元々のコードと同じなら IDE 上でも無限ループに
            If UBound(DimTs) < i Then Exit Do  '意味がない
            DimTs(i).flg = False           '目的は


>  DimTs(1) でも DimTs(9) でも DimTs( ... ) でもこのエラーは発生します。

Private Sub f_Test(ByRef DimTs() As Type_T)

の部分も変更していますか?(宣言したのと違いますが、固定配列/動的配列)

間違いだらけのコードを掲載されても判断のしようがありません。
エラーを発生させたいのならそのようなコードを書かないといけないし、文法間違いのコードでは。
(Err.Raise メソッドを使用するとか)

そもそも、間違っているから、配列が固定されているエラーがでているのでは?
(ReDim ステートメント等を使って宣言し直ししていないようだし)

事象が再現できるコードか、元のコードを投稿して頂かないと、そこは関係ないと言われても。
私には、あなたの VB 歴も解らないし、コードの転記間違いなのか、元々のコードなのか判断できませんので。

EXE だけの問題なら、どのようにコンパイルされているのでしょうか? 一度 P-Code コンパイルで
どうなるか試して見て下さい。

[ツリー表示へ]
タイトルRe^4: IDEノーエラー,exeにてエラー。 その他1件
記事No16077
投稿日: 2015/02/02(Mon) 11:30
投稿者まさお
花ちゃん さん、ありがとうございます。

>  Do While True 元々のコードと同じなら IDE 上でも無限ループに
>             If UBound(DimTs) < i Then Exit Do  '意味がない
>
 イイエ。 IDE上でもexeファイル上でもここでは無限ループになりません。
 下記@を確認願います。

>             DimTs(i).flg = False           '目的は
>
 下記Aを確認願います。


  Do While True '<=一見無限ループに見えますが違います。※β参照。
     For i = 0 To UBound(DimTs)
        With DimTs(i)
          If .flg Then Exit For '※α
            '↑DimTs(i).flg=TrueならForループからExitします。
            ' DimTs(i).flg=Trueが無ければForループからExitせず
            ' Forループが完了します。

        End With
     Next
     '↑Forループが完了すると UBound(DimTs) < i になります。

     If UBound(DimTs) < i Then Exit Do '※β
       '@↑Forループが完了すると(※αでExitしていなければ
       '( つまり DimTs(i).flg=True が無ければ)
       'UBound(DimTs) < i が成立するので Exit Do します。
       '従って Do While True は無限ループになりません。
    
     DimTs(i).flg = False
       '↑※αでExitしていたら、その配列要素.flg=Falseにします。
       'A従っていつかは全ての配列要素.flg=Falseになります。
       '従って※βの If文 はいつかは必ず成立します。
      
  Loop

> Private Sub f_Test(ByRef DimTs() As Type_T)
> の部分も変更していますか?(宣言したのと違いますが、固定配列/動的配列)
>
 ご指摘の意味が良く判りません。
  Private Sub Test()
    Dim DimTs(0) As Type_T '<=固定配列にしたら…
    Call f_Test(DimTs)
  End Sub
  Private Sub f_Test(ByRef DimTs(0) As Type_T) '<=仮引数も固定配列にすべき ※γ
    …
  End Sub
 という意味ではありませんよね。
 ※γにするとコンパイルエラーになりますので。
 申し訳ありませんが、ご指摘の意味を教えて下さるとありがたいです。

> 間違いだらけのコードを掲載されても判断のしようがありません。
>
 どこがどのように間違っているのかを知りたく質問させて戴いています。

> エラーを発生させたいのならそのようなコードを書かないといけないし、
 …
> 事象が再現できるコードか、元のコードを投稿して頂かないと、…
>
 少なくとも私の環境では掲示したコードでIDEでは問題なくexeファイルだけでエラーが発生します。
 つまり「事象を再現できます」。

> 文法間違いのコードでは。
>
 「文法間違い」とはコンパイルエラーではなく「論理(フロー)間違い」との事だと思います。
 具体的にはどこに間違いがありますでしょうか?

> そもそも、間違っているから、配列が固定されているエラーがでているのでは?
>
 間違っている箇所は判っています。
  For i = 0 To UBound(DimTs)
    With DimTs(i)
      If .flg Then Exit For
    End With
  Next
 にてWith 〜 End With の中でループからExitしているからです。
    ※End With を実行する前に Exit For で抜けているので配列が固定されている、と推測しています。
 元投稿に記しましたが With 〜 End With の三行を If DimTs(i).flg Then Exit For の一行に変えればエラーは発生しません。
 私が知りたいのは
 1)何故Exeでだけエラーになるのか?
 2)何故On Error Goto 文以降のエラーで無限ループになるのか?
 なのです。

> (ReDim ステートメント等を使って宣言し直ししていないようだし)
>
 ReDimステートメントの必要性が判りませんが、あるいは別プロシージャに仮引数として渡す配列は、実引数では固定配列ではなく動的配列にすべき、という意味でしょうか?
 固定配列/動的配列のどちらでも本エラーは発生します。
  Sub Test
    Dim DimTs(0) As Type_T
を、
    Dim DimTs() As Type_T
    ReDim DimTs(x)   xは'0','1','9' 等なんでもOK
に変えても本エラーは発生します。

> EXE だけの問題なら、どのようにコンパイルされているのでしょうか?
>
 単純に メニュー > ファイル(&F) > ….exe の作成(&K) を実行しています。

> 一度 P-Code コンパイルでどうなるか試して見て下さい。
>
 「P-Code コンパイル」を実行したことが無いので良く判りません。
 方法等、調べてから試行してみます。


引き続きアドバイス戴ければありがたいです。

[ツリー表示へ]
タイトルRe^5: IDEノーエラー,exeにてエラー。 その他1件
記事No16078
投稿日: 2015/02/02(Mon) 13:46
投稿者まさお
蛇足だと思いますが追記します。

>  間違っている箇所は判っています。
>   For i = 0 To UBound(DimTs)
>     With DimTs(i)
>       If .flg Then Exit For
>     End With
>   Next
>  にてWith 〜 End With の中でループからExitしているからです。
>
 しかしこれだけではエラーにはなりません。

Private Sub f_Test(ByRef DimTs() As Type_T)
    Dim i As Long
    
    DimTs(0).flg = True
    For i = 0 To UBound(DimTs)
       With DimTs(i)
          If .flg Then Exit For
       End With
    Next
End Sub
に変えると「配列が固定されている」エラーにはなりません。

このエラーは
  Do While True
    For i = 0 To UBound(DimTs)
      With DimTs(i)
        If .flg Then Exit For
      End With
    Next
    If UBound(DimTs) < i Then Exit Do
    DimTs(i).flg = False
  Loop
のように DoからExitすると発生します。

しかし「DoからExitする」だけでは発生しません。
  Do While True
    For i = 0 To UBound(DimTs)
      With DimTs(i)
        If .flg Then Exit For
      End With
    Next
    Exit Do
  Loop
のように単純にExit Doでもこのエラーはでません。

 掲示コードは意味不明に見えるとは思います。
 ただ、このエラーはこのようにしないと発生しないのでご容赦願います。

 参考として元ソースにより近いコードを掲示します。
 下記コードの方が何をしているのかは判り易いと思います。
 下記コードでは余分な情報が多いのでそれを省略して最初のコードを掲示しました。
  
 元ソースのタイプ文(抜粋)
    Private Type Type_T
      Strong As Boolean
      RDate  As Date
      flg    As Boolean
    End Type

 より元ソースに近いコード
    Dim IndexNewDay As Long, NewDay As Date
    Do While True
      IndexNewDay = -1
      NewDay = #1/1/2000#
      For i = 0 To UBound(DimTs)
        With DimTs(i)
          If Not .flg Then
            'Continue For
          ElseIf .Strong Then 'Strong最優先
            IndexNewDay = i
            Exit For
          ElseIf NewDay < .RDate Then 'RDate最新優先
            IndexNewDay = i
            NewDay = .RDate
          End If
        End With
      Next
      If UBound(DimTs) < i Then Exit Do
      
      '=====DimTs(IndexNewDay)に対する処理
      
      DimTs(IndexNewDay).flg = False
    Loop


以上です。

[ツリー表示へ]
タイトルRe^5: IDEノーエラー,exeにてエラー。 その他1件
記事No16079
投稿日: 2015/02/02(Mon) 14:01
投稿者まさお
>  「P-Code コンパイル」を実行したことが無いので良く判りません。
>  方法等、調べてから試行してみます。
>
 P-Codeコンパイル方法が判りました。
 そしてP-Codeコンパイルで作成したexeファイルではエラーは出ませんでした。

 つまり私の質問は正確には「IDE, P-Codeコンパイルexeではノーエラー、ネイティブコンパイルexeではエラー」の原因を知りたい。IDEで同じくエラーにするにはどうすれば良いでしょうか?

 という事になります。

[ツリー表示へ]