Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


2011 / 13645 ツリー ←次へ | 前へ→

【70498】ループ中のDIM ふねふね 11/11/21(月) 13:08 質問[未読]
【70500】Re:ループ中のDIM UO3 11/11/21(月) 15:25 発言[未読]
【70501】Re:ループ中のDIM ふねふね 11/11/21(月) 17:24 発言[未読]
【70502】Re:ループ中のDIM ichinose 11/11/21(月) 17:42 発言[未読]
【70503】Re:ループ中のDIM 追伸 ichinose 11/11/21(月) 17:53 発言[未読]
【70507】Re:ループ中のDIM 追伸 ふねふね 11/11/22(火) 9:27 お礼[未読]
【70522】Re:ループ中のDIM 追伸 ichinose 11/11/24(木) 8:54 発言[未読]

【70498】ループ中のDIM
質問  ふねふね  - 11/11/21(月) 13:08 -

引用なし
パスワード
   先日、他人のプログラムを読む機会がありました。
その中で、

Dim i as integer

For i = 1 to 100

Dim s as string

Next i

のようなコードに出くわしました。
かなり単純に書いていますが基本的にはこれと同じ。
コンパイルも実行時もエラーが出ませんでした。

ためしに、

Dim i as integer
Dim s as string

For i = 1 to 100

Dim s as string

Next i

と書いてみると、コンパイルエラーとなりました。

後者はエラーは2回定義している。というものなのであたりまえと思いますが。
なぜ前者はエラーが出ずに、後者のみエラーとなるのでしょうか?

どなたか解説いただけないでしょうか?

【70500】Re:ループ中のDIM
発言  UO3  - 11/11/21(月) 15:25 -

引用なし
パスワード
   ▼ふねふね さん:

▼ふねふね さん:

>先日、他人のプログラムを読む機会がありました。

まず、あまりよくないコードサンプルだと思います。

基本的には、Dim(変数宣言)は「実行コード」ではなく、変数を、どこかに確保してくださいという「依頼文」ですので
実行コードの中で登場しても、エラーの要因になはりません。

しかしながら、プロシジャ内で宣言する変数は、全てを、最初の位置にもっていったほうが可読性に優れています。

さらに、アップされたコードでは変数sの規定の前に、sを実際に使っていないので
エラーにはなっていないのですが

Sub Errorです()
Dim i As Integer

s = "ABC"
MsgBox s

For i = 1 To 100

Dim s As String
Next i


End Sub

このコードのような構えであれば、Option Explict あり、なし、いずれもエラーになります。
(エラー原因は異なりますけど)

【70501】Re:ループ中のDIM
発言  ふねふね  - 11/11/21(月) 17:24 -

引用なし
パスワード
   ▼UO3 さん:

返信ありがとうございます。

なぜその方がそういうコードを書かれたのかわかりませんが、
エラーが出なかったのが不思議だったので、質問させて
いただきました。

正確には、ループの中で、その変数を使用しているのです。
外で一回定義しておくべきだとは思うのですが。^^;


Sub Errorです()

Dim i As Integer

For i = 1 To 100

 Dim s As String
 s = "aaa"

 msgbox s

Next i

end sub

【70502】Re:ループ中のDIM
発言  ichinose  - 11/11/21(月) 17:42 -

引用なし
パスワード
   こんばんは。

>
>なぜその方がそういうコードを書かれたのかわかりませんが、
>エラーが出なかったのが不思議だったので、質問させて
>いただきました。

Sub test()
  Dim g0 As Long
  Dim a As String
  For g0 = 1 To 10
    Dim a As String
    a = a & "1"
  Next
  MsgBox a
End Sub

これで発生するエラーって、コンパイルエラーですよね?

つまり、コードを実行前に行う文法チェックの結果発生するエラーです。
2度同じ変数が宣言されているのですから、文法エラーになります。

Sub test1()
  Dim g0 As Long
  For g0 = 1 To 10
    Dim a As String
    a = a & "1"
  Next
  MsgBox a
End Sub

↑これは、あくまでも aの宣言は、一度しか記述されていませんから、
文法的に問題がない、というよりそこまで文法的にチェックはしていない
と言うことなんです。

Dim a As Stringという記述から実行時には、最初に領域として確保されていますから、
実際には無視されるということです。

test1は、1111111111 と表示されますよね?

【70503】Re:ループ中のDIM 追伸
発言  ichinose  - 11/11/21(月) 17:53 -

引用なし
パスワード
   こういうのは、自分がこのコンパイラーとインタープリタを作る身になってみると、
何となく分かるんです。

ループ処理内での宣言まで文法チェックしたら、大変だから・・・、
というよりできないから・・・。

 For g0=1 to 1
  dim a as string
 next

これは、OK
b=1
For g0=1 to b
  dim a as string
next

これも OKですよね? 実行前にチェックは出来ませんよね?

【70507】Re:ループ中のDIM 追伸
お礼  ふねふね  - 11/11/22(火) 9:27 -

引用なし
パスワード
   ▼ichinose さん:

なるほど!
実行時に、エラーとするか、無視するか、
VBAの仕様ということですね。^^

【70522】Re:ループ中のDIM 追伸
発言  ichinose  - 11/11/24(木) 8:54 -

引用なし
パスワード
   おはようございます。

私の拙い記述でもある程度のご理解は、して頂いたと思うのですが・・・、
>実行時に、エラーとするか、無視するか、
>VBAの仕様ということですね。^^
実行時にエラーとすること等できない仕様になっていることが
以下のコードがエラーにならないことでご理解頂けると思います。

Sub test()
  Dim g0 As Long
  For g0 = 1 To 10
    If g0 >= 6 Then
     Dim a As String
    End If
    a = a & "1"
  Next
  MsgBox a
End Sub


上記コードだと、
g0が6以上なって、Dim宣言ステーとメンとを実行している というように
みえますが、そうだとすると、エラーになりますが、実際にはエラーとは
ならず、aは 1111111111 と表示されます。

私たちが記述した  --->コンパイル--------->中間コード--------------------
VBAコード        文法チェックと    この時点で
            中間コード作成    変数aがローカルに
                      作成するコードが作成

--------------------->インタプリタで実行
           プロシジャー実行時の最初で
           変数aの領域は認知

よって、上記のtestが正常に作動しているのだと思われます。

2011 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free