2012-10-21 5 views
0

하나의 서브 루틴에서 다른 서브 루틴으로 변수를 전달하는 데 문제가 있습니다. 나는 그들을 공개한다고 선언했지만 아직 효과가없는 것으로 보인다. 서브 루틴이 범위를 벗어났습니다. 내가 필요한 것은 내 두 번째 서브 루틴에서 varUnique (배열) 및 firstIndex를 사용하는 것입니다. 이 작업을 수행하려면 무엇을해야합니까?VBA 서브 루틴이 변수를 전달할 수 없습니다.

Public fistIndex As Integer 
Public varUnique As Variant 
Sub FindUnique() 

    Dim varIn As Variant 
    Dim iInCol As Long 
    Dim iInRow As Long 
    Dim iUnique As Long 
    Dim nUnique As Long 
    Dim isUnique As Boolean 
    Dim lastIndex As Integer 

    varIn = Range("List") 
    ReDim varUnique(1 To UBound(varIn, 1) * UBound(varIn, 2)) 

    nUnique = 0 
    For iInRow = LBound(varIn, 1) To UBound(varIn, 1) 
     For iInCol = LBound(varIn, 2) To UBound(varIn, 2) 

      isUnique = True 
      For iUnique = 1 To nUnique 
       If varIn(iInRow, iInCol) = varUnique(iUnique) Then 
        isUnique = False 
        Exit For 
       End If 
      Next iUnique 

      If isUnique = True Then 
       nUnique = nUnique + 1 
       varUnique(nUnique) = varIn(iInRow, iInCol) 
      End If 

     Next iInCol 
    Next iInRow 
    '// varUnique now contains only the unique values. 
    '// Trim off the empty elements: 
    ReDim Preserve varUnique(1 To nUnique) 
    firstIndex = LBound(varUnique) 
    lastIndex = UBound(varUnique) 


create: 
    If Not varUnique(firstIndex) = "Sub-Total" Then 
    Worksheets.Add.Name = varUnique(firstIndex) 
    Call Ledge(varUnique, firstIndex) 
    Else 
    End 
    End If 
    If Not firstIndex = lastIndex Then 
    firstIndex = firstIndex + 1 
    ActiveCell.Offset(1, 0).Select 
    GoTo create 
    Else 
    End If 
End Sub 
Sub Ledge(varUnique, firstIndex) 
' 

' 

'Define Variables 
Dim Account_type As String 
Dim Debit As Long 
Dim Credit As Long 


'Select Journal and Cell B4 
    Sheets("Journal").Select 
    Range("B4").Select 

Account_Search: 
'Make that cell= account_type 
    Account_type = ActiveCell.Value 
'If that cell= cash then save the values adjecent 
    If Account_type = varUnique(firstIndex) Then 
     ActiveCell.Offset(0, 1).Select 
     Debit = ActiveCell.Value 
     ActiveCell.Offset(0, 1).Select 
     Credit = ActiveCell.Value 
'Then go back to where you began 
     ActiveCell.Offset(0, -2).Select 
'Select Cash and Cell A2 
     Sheets(varUnique(firstIndex)).Select 
     Range("A2").Select 
Search: 
'If both cells are empy 
      If ActiveCell.Value = "" And ActiveCell.Offset(0, 1).Value = "" Then 
'Then write values and indicate you have done so 
       ActiveCell.Value = Debit 
       ActiveCell.Offset(0, 1).Select 
       ActiveCell.Value = Credit 
       Else 
'If they are not empty go down one cell and search again 
       ActiveCell.Offset(1, 0).Select 
       GoTo Search 
      End If 
'Once it is recorded go to Journal again and go down one more cell 
       Sheets("Journal").Select 
       ActiveCell.Offset(1, 0).Select 
'If it wasn't cash then go down one 
    Else 
     ActiveCell.Offset(1, 0).Select 
    End If 
'Record that cell value and check to see if it is not sub-total 
    Account_type = ActiveCell.Value 
    If Not Account_type = "Sub-Total" Then 
'Now see if it is cash 
     GoTo Account_Search 
    Else 
    End If 
End Sub 
+5

** a) ** 함수는 'Sub'내에서 전역 변수를 설정하는 대신 값을 반환합니다. 좋은 코드에는 전역 변수가 없습니다. ** b) ** 때때로 'fistIndex'가 아닌 'firstIndex' 변수를 모든 곳에서 호출해야합니다. 'Option Explicit'을 사용하여 무슨 일이 일어나는 지보십시오. 실제로 모든 VBA 코드에서 사용해야합니다. – Tomalak

+8

@Tomalak 사람들에게 좋은 코드에는 전역 변수가 없다는 이야기는 도움이되지 않습니다. 아니면 사실. 전역 변수를 꺼도 나쁜 코드는 좋지 않으며 전역에 퍼팅해도 코드가 좋지 않습니다. 또한'Option Explicit'에 대해서도 완벽합니다. –

+2

@Seith 네, 골볼 변수에 대한 부분은 약간 논쟁 거리였습니다. 어쨌든, 저는 특히 초보자로서 그리고 특히 위의 상황과 같은 상황에서, 전역 변수에 상태를 유지하지 않는 것이 좋은 습관이라고 생각합니다. 모든 것을 위해 전역 변수를 사용하는 것은 너무 쉽고 유혹적이며, 그로부터 거의 이익을 얻을 수 없습니다. – Tomalak

답변

0

나는 varUnique 배열에 누락 된 항목을 가리키는 firstIndex에서 수 있었다 "범위를 벗어난 첨자"하지만 오류가 있기 때문에 통과 매개 변수로 생각하지 않습니다. 코드에 대한

몇 가지 생각 : 일반적으로

  • , 당신은 배열에 올 때 그들이 편리 할 수 ​​있지만, 변형을 방지한다. 대신 형식화 된 배열 (이 경우에는 문자열 배열, Dim varUnique() as String을 대신 사용하십시오) 또는 컬렉션
  • 질문에 대한 의견에서 언급 한대로 가능한 공용 또는 전역 변수를 피하십시오. 위의 코드에서 그들은 꼭 필요한 것은 아닙니다.
  • Option Explicit을 사용하십시오. 이 방법으로 컴파일 할 때 많은 오류가 발생합니다 (그렇지 않은 경우 매우 찾기 어려울 수있는 오류가 발생합니다).
  • 함수를 사용하여 호출 하위로 값을 전달합니다. - 당신은 내가

마지막으로 통과 매개 변수의 몇 가지 예 잠수정 내가 일을 알고 기능을 betweens 말할 수까지 firstIndex을 변경하지 않지만, 내가 말했듯이, 나는 그 곳을 생각하지 않습니다 문제가 있습니다.

Option Explicit 

Sub OuterSub() 
    Dim varUnique As Variant 
    Dim firstIndex As Integer 
    Dim returnedInt As Integer 

    '***** Create array 
    varUnique = Array("String#1", "String#2", "String#3", "String#4", "String#5", "String#6") 

    '***** Get first index 
    firstIndex = LBound(varUnique) 

    '***** Pass variables to second sub 
    Call InnerSub(varUnique, firstIndex) 

    '***** Pass variables to and from function 
    returnedInt = InnerFunction(varUnique, firstIndex) 

    Debug.Print "returnedInt=" & returnedInt & ", varUnique(returnedInt)=" & varUnique(returnedInt) 
End Sub 

Sub InnerSub(pvIn As Variant, piIndex As Integer) 
    '***** Do something with the paramterers, like 
    '***** checking to see if pvIn is an array 
    If IsArray(pvIn) Then 
     Debug.Print pvIn(piIndex) 
    Else 
     Debug.Print "pvIn not an array..." 
    End If 
End Sub 

Function InnerFunction(pvIn As Variant, piIndex As Integer) As Integer 
    '***** Return Integer 
    InnerFunction = piIndex + 1 
End Function 
관련 문제