2012-10-21 153 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)**也許你應該把變量'firstIndex'稱爲變量,而不是有時調用它'fistIndex'。使用'Option Explicit'並查看會發生什麼。實際上你真的應該在你編寫的所有VBA代碼中使用它。 – Tomalak

+8

@Tomalak告訴人們,好的代碼沒有全局變量是沒有用的。或者是真的。將全局變量取出不會使糟糕的代碼變得更好,並且使用全局變量不會使代碼變得糟糕。另外,你對'Option Explicit'完全正確。 –

+2

@ Seith是的,關於golbal變量的部分有點爭論。無論如何,我認爲避免在全局變量中保持狀態是一個好習慣,特別是作爲初學者,特別是在上述情況下。對於所有事情來說,使用全局變量都很容易,也很誘人,而且可以從中得到一點好處。 – Tomalak

回答

0

我不認爲錯誤是因爲傳遞參數,儘管「下標越界」可能是從firstIndex指向缺失項目varUnique陣列英寸

關於代碼的一些想法:

  • 一般來說,你應該避免變種,即使他們能夠得心應手,當談到陣列。相反,使用鍵入數組(在這種情況下,字符串數組,請使用Dim varUnique() as String)或集合
  • 如果可能的話,您還應該避免使用公共或全局變量,正如您對問題的評論中所述。在你的代碼中,它們絕對沒有必要。
  • 使用Option Explicit,也在上面提到。編譯時會發現很多錯誤,這些錯誤可能很難找到(請參閱fistIndexfirstIndex
  • 使用函數將值傳遞迴調用子 - 我不認爲在您的示例中需要它 - 你不改變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