web-dev-qa-db-ja.com

VBAでグローバル変数を宣言する方法を教えてください。

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

Function find_results_idle()

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

そして私はエラーメッセージが表示されます。

「SubまたはFunctionの無効な属性」

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

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

私は関数自体を `Public 'として宣言しようとしましたが、それもまた良くありませんでした。

グローバル変数を作成するために何をする必要がありますか?

121
Nimrod

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

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1
165
SLaks

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

変数を関数の存続期間だけ存続させる場合は、関数またはsubの内部で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キーワードで宣言することで、特定のモジュール(またはクラス)内でのみアクセス可能な変数を持つこともできます。

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

111
Ben McCormack

グローバル変数を使用するには、VBAプロジェクトUIから新しいモジュールを挿入し、Globalを使用して変数を宣言します。

Global iRaw As Integer
Global iColumn As Integer
33
YOU

他の人がそれを置くように質問は本当に範囲についてです。

要するに、この "モジュール"を考えてください。

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ステートメントを使用できます。
15
FCastro

この関数がモジュール/クラスの中にある場合は、それらを関数の外側に書くだけでよいので、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
14
Zai

一般宣言で公開整数を作成します。

それからあなたの機能では、あなたはその値を毎回増やすことができます。例(電子メールの添付ファイルを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
1
Dan Bidner

パブリック/グローバル変数を作成する良い方法は、フォームをクラスオブジェクトのように扱い、プロパティを宣言し、PublicプロパティGet [変数]を使ってプロパティ/メソッドにアクセスすることです。また、インスタンス化されたFormモジュールへの参照を参照または渡す必要があるかもしれません。閉じられているフォーム/レポートのメソッドを呼び出すとエラーが発生します。
例: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

あなたがLate Bindingを使っているのであれば、私はいつもNull値とNothingのオブジェクトをチェックしてから処理を試みます。

0
Double E CPU

またあなたが使用することができます -

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

2010年のオフィスでテスト済み

0
SftAps