2012-10-21 149 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