• ベストアンサー

変数iもjも同じく値を保持できるからどちらを使って

このサンプルコードは、 変数iもjも同じく値を保持できるから、test1を使ってもtest2を使っても一緒なのでしょうか? Option Explicit Dim i As Integer Sub test1() Static j As Integer j = j + 1 Debug.Print j End Sub Sub test2() i = i + 1 Debug.Print i End Sub ご回答よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.5

>test2では、jが「変数の宣言がされてない」と、コンパイルエラーになりました。 それはご質問とは直接関係ない(こともない)、「Option Explicit」の宣言によって、プロシジャの中でスコープのない(定義されていない、もしくはパブリックが届いていない)変数を使おうとしているというコンパイルの警告です。

jklafdsoui
質問者

お礼

ありがとうございました。

その他の回答 (4)

回答No.4

> 「後者には初期化するタイミング」とはどういうことでしょう? グローバル変数であるiは、test3()などという関数内でも 初期化可能だということです。 > Sub test1() > > Static j As Integer > > j = 0 > > j = j + 1 > Debug.Print j > End Sub > > は初期化できてる事になりますか? これはつまり、staticにする意味がありません。

jklafdsoui
質問者

お礼

ありがとうございました。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.3

そのマクロに限って言えば、同じような結果にはなりますね。 でも。 jはtest1の中でStaticです。つまり、値が保持されているのはあくまでもtest1の中だけです。 iはパブリックです。したがって、test1の中でも、test2の中でも値が保持されています。 dim i sub test1() static j j = j + 1 debug.print i debug.print j end sub sub test2() i = i + 1 debug.print i ’debug.print j ’jはtest2の中でスコープに無い=参照できないのでエラーになる end sub test2を何回か実行した後にtest1を複数回実行する。あるいは交互に実行する。

jklafdsoui
質問者

お礼

2さんもおっしゃる通り、スコープの違いですね。 頂いたコードを実行してみたところ、 test2では、jが「変数の宣言がされてない」と、コンパイルエラーになりました。

  • uruz
  • ベストアンサー率49% (417/840)
回答No.2

test1、 test2ともに同じ結果となりますが、変数のスコープが異なります。 jはtest1プロシージャの中だけしか参照できません。iは同一モジュール内で参照が可能となります。 コードモジュールであれば Public i as Integer とすればプロジェクト全体から参照可能となります。

jklafdsoui
質問者

お礼

Static j As Integer は、プローシージャ内だけしか有効ではないのですか。ありがとうございました。

回答No.1

一緒でしょうが、後者には初期化するタイミングを自由に作れます。 前者はそうはいきません。 個人的にstaticは嫌いです。 宣言が現れた時点で値が初期化されていないというのは扱いづらいです。 値が変化されるものならば、引数として外部から受け取る形にします。 結局そのjは何らかの契機で変化し、何らかの処理で利用されるわけですから 責任範疇を切り分ければstaticは使わなくなります。

jklafdsoui
質問者

お礼

「後者には初期化するタイミング」とはどういうことでしょう? Sub test1() Static j As Integer j = 0 j = j + 1 Debug.Print j End Sub は初期化できてる事になりますか? Static(スタティック)はあまり使う機会がなかったので質問しました。 使いにくいのですね。私もあまり使って行こうとは思えません。ありがとうございました。

関連するQ&A

  • なぜiは変数の値が保持されるのに、wは保持されない

    なぜiは変数の値が保持されるのに、wは保持されないのでしょうか? Sub test() Dim w As Worksheet Dim i As Long i = 1 For Each w In Worksheets i = i + 1 Next MsgBox i MsgBox w.Name End Sub -------------------------------------- を行うと、 MsgBox i は表示されるのに、 MsgBox w.Name は、 「オブジェクト変数または With ブロック変数が設定されていません。」になります。 wはオブジェクト変数だから、 For Each ステートメントを抜けると値が破棄されてしまうのでしょうか? でもvbaのヘルプの 「For Each...Next ステートメントの使い方」 を見ても 「ステートメントを抜けるとオブジェクト変数なら値が破棄されます」 と記載されていません。

  • iと言う変数の値が1から10の間にないならば

    「iと言う変数の値が1から10の間にないならば」、としたいのですが どのようなコードを書けばいいのでしょうか? Sub test1() Dim i As Integer i = 11 If 1 < i < 10 Then MsgBox i & "は1から10の間にはありません" End If End Sub だと、メッセージが表示されてしまいます。

  • 変数が増えてしまうのはなぜだか教えてください。

    こんにちは、マクロ初心者ではないつもりですが、基本ができていないのか、以下のSubで、変数の値が増えてしまいます。i = 3のままだと思っていたのですが、シートが移動するにつれてiの値が増えてしまうのは何故でしょうか。教えてください。 Sub tes() Dim i As Integer Dim ws As Worksheet i = 3 Debug.Print i For Each ws In Worksheets ws.Select For i = 1 To i Debug.Print i Cells(i, i) = i Next Next End Sub 新規のブックに書きました。Sheetは1~3です。

  • 変数を続けて宣言した場合はEmpty型になる?

    Sub test1() Dim Int1, Int2 As Long Debug.Print "---------- test1の実行結果 ----------" Debug.Print TypeName(Int1) Debug.Print TypeName(Int2) End Sub Sub test2() Dim Int1 As Long Dim Int2 As Long Debug.Print "---------- test2の実行結果 ----------" Debug.Print TypeName(Int1) Debug.Print TypeName(Int2) End Sub を実行すると、 ---------- test1の実行結果 ---------- Empty Long ---------- test2の実行結果 ---------- Long Long の結果が得られます。 test1のInt1がEmpty型になりますが、変数の型にEmptyはないですよね? どういうことなのでしょう???

  • グローバル変数などについて

    Option Explicit Dim str1 As String '・・・(1) Sub テスト() Dim str2 As String '・・・(2) str1 = "テスト1" str2 = "テスト2" MsgBox str1 MsgBox str2 End Sub (1)はグローバル変数と言うとの事ですが (2)は何変数と言うのでしょうか? ローカル変数ですか? また、(1)がdimではなく、 Public str1 As String となった場合でも、 プロシージャーの外にあれば、グローバル変数と言うのでしょうか?

  • 変数に保持している値はどうやったら確認できるの?

    Publicで宣言した変数はブックを閉じるまで値を保持すると言うけど、 その保持している値はどうやったら確認できるのですか? 例えば標準モジュールに ++++++++++++++++++++++++++++++ Option Explicit Public a As String Sub test() a = "こんにちは" End Sub ++++++++++++++++++++++++++++++ とした場合、 1回testを実行すると、a には "こんにちは"が入りますよね。 この時例えばトイレに行って、パソコンの前に戻ってきたときに、 「aに何の値がはいってたっけ?」ってどうやって確認すればいいのでしょうか? testを実行する前に、ウォッチ式にaを登録しましたが、 testを実行し終わるとaの値は「対象範囲外」になっています。 でもこの状態でもaの値は保持されてるのですよね? 発見したのは、testをF8でステップインをすると、 2行目のa = "こんにちは"を通過する前に、aにすでに値が入ってる事がわかりました。 こういう方法で確認するしかないのでしょうか?

  • 「Debug.Print i = i + 1」がFalseになる。

    Sub test() Dim i As Long i = 0 Debug.Print i = i + 1 End Sub を実行すると False がイミディエイトウインドウに表示されます。 理由が知りたいです。 よろしくお願いします。

  • プロシージャーの外で宣言した変数の値の破棄の仕

    プロシージャーの外で宣言した変数の値の破棄の仕方について教えてください。 ++++++++++++++++++ Dim i As Long Sub test() i = i + 10 MsgBox i End Sub ++++++++++++++++++ を実行すると、どんどん値が増えていきますが、 回避するには、 ++++++++++++++++++ Dim i As Long Sub test() i = i + 10 MsgBox i i = 0 End Sub ++++++++++++++++++ とするしかないのでしょうか? ++++++++++++++++++ Dim i As Long Sub test() i = i + 10 MsgBox i Set i = Nothing End Sub ++++++++++++++++++ としたら、エラーになりました。

  • 変数が勝手に変わります

    Dim i As Integer:Dim i2 As Integer:Dim card(5) As Integer:Dim expectPoint0card(1) As Integer '0枚のカードを交換する場合のすべての選択肢の期待値 Dim expectPoint1card(5) As Integer Sub porkerGame() card(1) = 1: card(2) = 2: card(3) = 3: card(4) = 4: card(5) = 5 getExpectPoint1card expectPoint1card End Sub Sub getExpectPoint1card(expectPoint1card() As Integer) Dim tesu1 As Integer:Dim sum1 As Integer For i = 1 To 5 getTesuSum1 i, tesu1, sum1 expectPoint1card(i) = sum1 / tesu1 Next i End Sub Sub getTesuSum1(rowNumber As Integer, tesu1 As Integer, sum1 As Integer) Dim card2(5) As Integer:tesu1 = 0:sum1 = 0 MsgBox rowNumber copy card, card2, 5 MsgBox rowNumber For i = 4 To 55 MsgBox rowNumber card2(rowNumber) = i addTesuSum card2, tesu1, sum1 Next i End Sub Sub copy(row() As Integer, row2() As Integer, i2 As Integer) For i = 1 To i2 row2(i) = row(i) Next i End Sub 上記のプログラムで、ウィンドウに1,6,4,5,6と表示され、その次には、エラーが表示します。僕は、ウィンドウに表示される変数RowNumberの値がしばらくの間は1のままであるようにプログラムを書いたつもりなのですが、変数rowNumberの値が変わるのは、どうしてでしょうか?教えてください。お願いします。

  • 変数を保持して呼び出す方法

    変数を保持する方法 2022/02/10 15:36 変数が受け継がれない 2022/02/10 15:24 sub A(),subB()と複数のプロシージャをModule1に配置。 Sub Aでターゲットファイル(T_File)を指定して Sub Bで同じT_Fileを呼び出そうとしたのですが Subの前に配列は宣言しているのでPrivateのハズなのに 変数が受け継がれません T_Fileが”””となります。 多分、Sub A()が終了した時点で一度マクロが終了して 新たにSub B()を呼び出すので上手く変数が受け継がれないのだと思います。 何処かのシートのセルに変数を保持して呼び出す方法が考えられますが そのほかに変数を保持する方法は有りませんか? (できればシートのセルに保持しない方法があれば教えて下さい。) 以下コード(コードが長いので必要と思われる所だけを記載しています。) ’------------------------------------ Option Explicit Dim dlg As FileDialog Dim T_File As String Sub A() Set dlg = Application.FileDialog(msoFileDialogFilePicker) If dlg.Show = False Then MsgBox "処理はキャンセルされました。" Exit Sub Else End If '指定テキストファイル読み込み T_File = dlg.SelectedItems(1) '(途中のコード省略) If rc = vbNo Then MsgBox "処理を中止します。", vbCritical Exit Sub Else MsgBox "処理が終了しました。", vbInformation End If End Sub Sub B() ’T_File = dlg.SelectedItems(1) Folder_Name = CreateObject("Scripting.FileSystemObject").GetParentFolderName(T_File) End Sub

専門家に質問してみよう