VBA에서 전역 변수를 어떻게 선언합니까?


132

다음 코드를 작성했습니다.

Function find_results_idle()

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

그리고 오류 메시지가 나타납니다.

"하위 또는 함수의 유효하지 않은 속성"

내가 뭘 잘못했는지 알아?

Global대신 사용하려고했지만 Public같은 문제가 발생했습니다.

나는 함수 자체를`Public '으로 선언하려고 시도했지만 그다지 좋지 않았다.

전역 변수를 만들려면 어떻게해야합니까?

답변:


177

함수 외부에서 변수를 선언해야합니다.

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1

배열을 공용으로 선언하려고하면 배열과 사용자 정의 데이터 형식을 공용으로 선언 할 수 없습니다.
kapilddit

위의 첫 번째 Function/ Sub뿐만 아니라 외부 : "모듈 수준 변수는 어둡거나 최초의 프로 시저 정의 위의 모듈의 상단에 개인 문으로 선언 할 수 있습니다." ( Visual Basic for Applications의 변수 범위에서 )
Nickolay

119

이것은 scope 에 관한 질문 입니다.

변수가 함수의 수명 동안 만 지속되도록 하려면 함수 또는 sub 안에 ( Dimension의Dim 줄임말)을 사용 하여 변수를 선언하십시오.

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키워드 로 선언하여 특정 모듈 (또는 클래스) 내에서만 액세스 할 수있는 변수를 가질 수도 있습니다 .

큰 응용 프로그램을 작성하고 전역 변수를 사용해야 할 필요가 있다면 전역 변수에 대해서만 별도의 모듈을 만드는 것이 좋습니다. 이를 통해 한 곳에서 추적 할 수 있습니다.


4
+1 7 년 후에도 여전히 유용합니다. 그러나 객체 변수와 데이터 변수에 관한 추가 뉘앙스가 있습니까? 새로운 질문을 유발하는 객체 변수 범위 지정과 관련된 문제가 발생했습니다. 살펴볼 시간이 있다면 대단히 감사합니다. stackoverflow.com/q/46058096/5457466
Egalth

2
VBA에서 변수 선언에 대한 간결한 설명.
PhillipOReilly

"scope"에 대한 다른 모든 제안을 시도했지만 아무것도 작동하지 않았습니다. 작동 한 유일한 것은 글로벌 변수를위한 새로운 모듈이었고 작동했습니다!
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 참조 를 참조하고 변수 가 범위를 벗어나는 방법에 대한 자세한 내용은 다른 스택 오버플로 질문 을 참조하십시오.

다른 두 가지 빠른 것 :

  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

퍼블릭 / 글로벌 변수를 생성하는 좋은 방법은 폼을 클래스 객체처럼 취급하고 속성을 선언하고 퍼블릭 속성 가져 오기 [변수]를 사용하여 속성 / 메서드에 액세스하는 것입니다. 또한 인스턴스화 된 양식 모듈에 대한 참조를 참조하거나 전달해야 할 수도 있습니다. 닫힌 양식 / 보고서에 메소드를 호출하면 오류가 발생합니다.
예 : Me.Form.Module.Parent를 양식이 아닌 하위 / 함수로 전달하십시오.

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 값과 아무것도없는 객체를 확인합니다.


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

사무실 2010에서 테스트

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.