VBAでグローバル変数を宣言するにはどうすればよいですか?


132

私は次のコードを書きました:

Function find_results_idle()

    Public iRaw As Integer
    Public iColumn As Integer
    iRaw = 1
    iColumn = 1

そして、私はエラーメッセージを受け取ります:

「サブまたは関数の無効な属性」

私が間違ったことを知っていますか?

Global代わりに使用しようとしましPublicたが、同じ問題が発生しました。

関数自体を「公開」として宣言しようとしましたが、それもうまくいきませんでした。

グローバル変数を作成するにはどうすればよいですか?

回答:


177

関数の外で変数を宣言する必要があります:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1

配列をパブリックとして宣言しようとすると、配列とユーザー定義のデータ型をパブリックとして宣言できません。
kapilddit

外側だけでなく、最初のFunction/のSub「モジュールレベルの変数は、最初のプロシージャ定義の上のモジュールの上部にあるDimまたはPrivateステートメントで宣言できます。」Visual Basic for Applicationsの変数のスコープから)
Nickolay

119

これはスコープについての質問です。

変数を関数の存続期間のみ存続させる場合は、関数またはサブルーチン内でDimDimensionの略)を使用して変数を宣言します。

Function AddSomeNumbers() As Integer
    Dim intA As Integer
    Dim intB As Integer
    intA = 2
    intB = 3
    AddSomeNumbers = intA + intB
End Function
'intA and intB are no longer available since the function ended

グローバル変数は、(SLaksが指摘したように)を使用して外部関数の宣言されているPublicキーワード。この変数は、実行中のアプリケーションの存続期間中に使用できます。Excelの場合、これは、その特定のExcelブックが開いている限り、変数を使用できることを意味します。

Public intA As Integer
Private intB As Integer

Function AddSomeNumbers() As Integer
    intA = 2
    intB = 3
    AddSomeNumbers = intA + intB
End Function
'intA and intB are still both available.  However, because intA is public,  '
'it can also be referenced from code in other modules. Because intB is private,'
'it will be hidden from other modules.

Privateキーワードで宣言することにより、特定のモジュール(またはクラス)内でのみアクセス可能な変数を持つこともできます。

大きなアプリケーションを構築していて、グローバル変数を使用する必要があると感じた場合は、グローバル変数専用の別のモジュールを作成することをお勧めします。これにより、それらを1か所で追跡できます。


4
+1 7年後もまだ役に立ちます。しかし、オブジェクト変数とデータ変数の関係について、いくつかのニュアンスがありますか?オブジェクト変数のスコープに関する問題が発生し、新しい質問が表示されました。ご覧いただく時間をいただければ幸いです。stackoverflow.com/q/46058096/5457466
Egalth

2
VBAでの変数宣言の簡潔な説明。
PhillipOReilly、2018年

「スコープ」に関する他のすべての提案を試しましたが、どれもうまくいきませんでした。機能したのは、グローバル変数専用の新しいモジュールだけでした。
Fandango68


18

他の人が言ったように、問題は本当にスコープに関するものです。

要するに、この「モジュール」を考えてみましょう:

Public Var1 As variant     'Var1 can be used in all
                           'modules, class modules and userforms of 
                           'thisworkbook and will preserve any values
                           'assigned to it until either the workbook
                           'is closed or the project is reset.

Dim Var2 As Variant        'Var2 and Var3 can be used anywhere on the
Private Var3 As Variant    ''current module and will preserve any values
                           ''they're assigned until either the workbook
                           ''is closed or the project is reset.

Sub MySub()                'Var4 can only be used within the procedure MySub
    Dim Var4 as Variant    ''and will only store values until the procedure 
End Sub                    ''ends.

Sub MyOtherSub()           'You can even declare another Var4 within a
    Dim Var4 as Variant    ''different procedure without generating an
End Sub                    ''error (only possible confusion). 

変数宣言の詳細については、このMSDNリファレンスを確認し、変数がスコープから外れる方法の詳細については、この他のスタックオーバーフローの質問を確認してください。

他の2つの簡単なこと:

  1. ワークブックレベルの変数を使用するときは整理して、コードが混乱しないようにします。優先機能(適切なデータ型を持つ)または渡す引数をBYREF
  2. 変数が呼び出し間でその値を保持するようにしたい場合は、Staticステートメントを使用できます。

グローバル変数をさまざまなワークブックで使用できることを確信していますか?うまくいかない
Seb

いい視点ね!その情報を入手した場所への参照を追加していないことに気づきました...それもまた見つかりませんでした。答えを編集した方がいい...:/ああ、そしてSebに感謝します。
FCastro

14

この関数はモジュール/クラス内にある場合、それは持っているので、あなただけの、機能のその外側を書くことができますGlobal Scope。グローバルスコープとは、同じモジュール/クラスの別の関数から変数にアクセスできることを意味します(dim宣言ステートメントとして使用するpublic場合は、すべてのモジュールのすべての関数から変数にアクセスできるようにする場合に使用します)。

Dim iRaw As Integer
Dim iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1
End Function

Function this_can_access_global()
    iRaw = 2
    iColumn = 2
End Function

1

一般宣言でパブリック整数を作成します。

次に、関数でその値を毎回増やすことができます。例(メールの添付ファイルをCSVとして保存する機能)を参照してください。

Public Numerator As Integer

Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim FileName As String

saveFolder = "c:\temp\"

     For Each objAtt In itm.Attachments
            FileName = objAtt.DisplayName & "_" & Numerator & "_" & Format(Now, "yyyy-mm-dd H-mm-ss") & ".CSV"
                      objAtt.SaveAsFile saveFolder & "\" & FileName
                      Numerator = Numerator + 1

          Set objAtt = Nothing
     Next
End Sub

0

Public / Global変数を作成する良い方法は、フォームをクラスオブジェクトのように扱い、プロパティを宣言し、Public Property Get [変数]を使用してプロパティ/メソッドにアクセスすることです。また、インスタンス化されたフォームモジュールへの参照を参照または渡す必要がある場合があります。閉じているフォーム/レポートのメソッドを呼び出すと、エラーが発生します。
例:Me.Form.Module.Parentをフォーム内ではなくsub / functionに渡します。

Option Compare Database 
Option Explicit
''***********************************''
' Name: Date: Created Date Author: Name 
' Current Version: 1.0
' Called by: 
''***********************************''
' Notes: Explain Who what when why... 
' This code Example requires properties to be filled in 
''***********************************''
' Global Variables
Public GlobalData As Variant
''***********************************''
' Private Variables
Private ObjectReference As Object
Private ExampleVariable As Variant
Private ExampleData As Variant
''***********************************''
' Public properties
Public Property Get ObjectVariable() As Object
   Set ObjectVariable = ObjectReference
End Property 
Public Property Get Variable1() As Variant 
  'Recommend using variants to avoid data errors
  Variable1 = ExampleVariable
End property
''***********************************''
' Public Functions that return values
Public Function DataReturn (Input As Variant) As Variant
   DataReturn = ExampleData + Input
End Function 
''***********************************''
' Public Sub Routines
Public Sub GlobalMethod() 
   'call local Functions/Subs outside of form
   Me.Form.Refresh
End Sub
''***********************************''
' Private Functions/Subs used not visible outside 
''***********************************''
End Code

したがって、他のモジュールでは、次のようにアクセスできます。

Public Sub Method1(objForm as Object)
   'read/write data value
   objForm.GlobalData
   'Get object reference (need to add Public Property Set to change reference object)
   objForm.ObjectVariable
   'read only (needs Public property Let to change value)
   objForm.Variable1
   'Gets result of function with input
   objForm.DataReturn([Input])
   'runs sub/function from outside of normal scope
   objForm.GlobalMethod
End Sub

私のように遅延バインディングを使用する場合は、処理を行う前に、常にNull値とNothingのオブジェクトを確認してください。


0

また、あなたは使うことができます-

Private Const SrlNumber As Integer = 910

Private Sub Workbook_Open()
    If SrlNumber > 900 Then
        MsgBox "This serial number is valid"
    Else
        MsgBox "This serial number is not valid"
    End If
End Sub

Office 2010でテスト済み

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.