2012-12-25 135 views
1

我試圖對輸出變量進行軟編碼,以便每次需要修改輸出時都不必修改VBA代碼。將字符串引用轉換爲變量名稱

這是工作

Sub Working() 
    Dim cat(1 To 10) 
    Dim bat(1 To 10) 

    For i = 1 To 10 
     cat(i) = i * 10 
     bat(i) = i * 5 
    Next i 

    Sheet2.Range("A2:A11") = Application.Transpose(cat()) 
    Sheet2.Range("B2:B11") = Application.Transpose(bat()) 
End Sub 

這是我希望寫的理想方式的代碼,但不工作

Sub not_working() 
    Dim cat(1 To 10) 
    Dim bat(1 To 10) 

    For i = 1 To 10 
     cat(i) = i * 10 
     bat(i) = i * 5 
    Next i 

    a = 3 
    Do While Sheet1.Cells(a, 1) <> "" 
     OutVar = Sheet1.cells(a, 1) & "()" 
     Sheet3.Range(_ 
      Cells(2, a - 2).Address, Cells(11, a - 2).Address _ 
     ) = Application.Transpose(Outvar) 
     a = a + 1 
    Loop 
End Sub 

' Sheet1.cells(3,1) = cat - these cells contain the variable names 
' Sheet1.cells(4,1) = bat - these cells contain the variable names 

可有人請建議如果有可能這樣做?

+0

你的標題表示將'String reference'轉換爲'variable name'。你是通過String引用引用一個String數組嗎?你的代碼只是通過'Transpose'將一個數組輸出到表單中。你能解釋這個問題嗎? – bonCodigo

+0

謝謝你的評論。上面有兩段代碼,「sub working」和「sub not_working」。程序「working」中的代碼很好,除了輸出變量(cat&bat)在代碼中被硬編碼之外。我想引用輸出變量,就像我在過程「not_working」中所做的那樣。輸出變量的名稱可以被稱爲字符串引用。我的問題是讓代碼明白它是我所指的數組變量... – user1927820

+0

我分享bonCodigo的困惑,因爲當我支持時,這是最困難的問題類型。你告訴我們你想要存在的技術;你沒有告訴我們你爲什麼要使用該技術。我喜歡在工作表中保存參數,告訴我的程序今天我希望將這些數據移到那裏。在這兩個版本中,您都會編寫兩個數組的創建代碼;只有目的地會有所不同。你期望添加第三個和第四個數組嗎?你期望什麼樣的未來要求,並希望做好準備? –

回答

-1

如果我正確理解您的要求,一個破舊的數組將會遇到它。

如果您有Variant類型的變量,您可以將該變量設置爲例如整數,實數,字符串,布爾值或數組。

如果您有一個Variant類型的數組,您可以將該數組的每個元素設置爲不同類型的值。

在我的代碼下面,我有變體數組Main。我設置:

  • 主(0)爲一維數組,
  • 主(1)到更大的一維數組,
  • 主(2)的2D陣列,
  • 主(3)到一個整數,
  • 主要(4)到工作表的使用範圍。

這被稱爲不規則數組,因爲每個元素都是不同的大小。

在用數組加載數組後,我使用一個常規例程根據其本質輸出Main的每個元素。

您的每個200-300變量都將成爲Main的一個元素。

看看我的代碼。這只是簡要介紹變體陣列可以實現的功能。如果你認爲我正朝着正確的方向前進,但還沒有走得夠遠,請回過頭來提問。

Option Explicit 
Sub DemoRaggedArray() 

    Dim InxDim As Long 
    Dim InxMain As Long 
    Dim InxWCol As Long 
    Dim InxWRow As Long 
    Dim Main() As Variant 
    Dim NumOfDim As Long 
    Dim Work() As Variant 

    ReDim Main(0 To 5) 

    Work = Array(1, "A", True) 

    Main(0) = Work 

    Main(1) = Array(2, "B", False, 1.2) 

    ReDim Work(1 To 2, 1 To 3) 

    Work(1, 1) = 1 
    Work(1, 2) = 2.5 
    Work(1, 3) = DateSerial(2012, 12, 27) 
    Work(2, 1) = True 
    Work(2, 2) = "String" 

    Main(2) = Work 

    Main(3) = 27 

    ' Cells A1:C4 of the worksheet have been set to their addresses 
    Main(4) = WorksheetFunction.Transpose(Worksheets("Sheet2").UsedRange.Value) 

    For InxMain = LBound(Main) To UBound(Main) 
    Debug.Print "Type of Main(" & InxMain & ") is " & VarTypeName(Main(InxMain)) 
    Select Case VarType(Main(InxMain)) 
     Case vbEmpty, vbNull 
     ' No value 
     Case Is >= vbArray 
     ' Array 
     NumOfDim = NumDim(Main(InxMain)) 
     Debug.Print " Main(" & InxMain & ") is dimensioned as: ("; 
     For InxDim = 1 To NumOfDim 
      Debug.Print LBound(Main(InxMain), InxDim) & " To " & _ 
                UBound(Main(InxMain), InxDim); 
      If InxDim < NumOfDim Then 
      Debug.Print ", "; 
      End If 
     Next 
     Debug.Print ")" 
     Select Case NumOfDim 
      Case 1 
      For InxWCol = LBound(Main(InxMain)) To UBound(Main(InxMain)) 
       Debug.Print " (" & InxWCol & ")[" & _ 
             VarTypeName(Main(InxMain)(InxWCol)) & "]"; 
       Select Case VarType(Main(InxMain)(InxWCol)) 
       Case vbEmpty, vbNull, vbArray 
        ' No code to handle these types 
       Case Else 
        Debug.Print "=" & Main(InxMain)(InxWCol); 
       End Select 
      Next 
      Debug.Print 
      Case 2 
      For InxWRow = LBound(Main(InxMain), 2) To UBound(Main(InxMain), 2) 
       For InxWCol = LBound(Main(InxMain), 1) To UBound(Main(InxMain), 1) 

       Debug.Print " (" & InxWCol & "," & InxWRow & ")[" & _ 
          VarTypeName(Main(InxMain)(InxWCol, InxWRow)) & "]"; 
       Select Case VarType(Main(InxMain)(InxWCol, InxWRow)) 
        Case vbEmpty, vbNull, vbArray 
        ' No code to handle these types 
        Case Else 
        Debug.Print "=" & Main(InxMain)(InxWCol, InxWRow); 
       End Select 
       Next 
       Debug.Print 
      Next 
      Case Else 
      Debug.Print " There is no display code for this number of dimensions" 
     End Select 
     Case Else 
     ' Single variable 
     Debug.Print " Value = " & Main(InxMain) 
    End Select 
    Next 

End Sub 
Public Function NumDim(ParamArray TestArray() As Variant) As Integer 

    ' Returns the number of dimensions of TestArray. 

    ' If there is an official way of determining the number of dimensions, I cannot find it. 

    ' This routine tests for dimension 1, 2, 3 and so on until it get a failure. 
    ' By trapping that failure it can determine the last test that did not fail. 

    ' Coded June 2010. Documentation added July 2010. 

    ' * TestArray() is a ParamArray because it allows the passing of arrays of any type. 
    ' * The array to be tested in not TestArray but TestArray(LBound(TestArray)). 
    ' * The routine does not validate that TestArray(LBound(TestArray)) is an array. If 
    ' it is not an array, the routine return 0. 
    ' * The routine does not check for more than one parameter. If the call was 
    ' NumDim(MyArray1, MyArray2), it would ignore MyArray2. 

    Dim TestDim     As Integer 
    Dim TestResult    As Integer 

    On Error GoTo Finish 

    TestDim = 1 
    Do While True 
    TestResult = LBound(TestArray(LBound(TestArray)), TestDim) 
    TestDim = TestDim + 1 
    Loop 

Finish: 

    NumDim = TestDim - 1 

End Function 
Function VarTypeName(Var As Variant) 

    Dim Name As String 
    Dim TypeOfVar As Long 

    TypeOfVar = VarType(Var) 

    If TypeOfVar >= vbArray Then 
    Name = "Array of type " 
    TypeOfVar = TypeOfVar - vbArray 
    Else 
    Name = "" 
    End If 

    Select Case TypeOfVar 
    Case vbEmpty 
     Name = Name & "Uninitialised" 
    Case vbNull 
     Name = Name & "Contains no valid data" 
    Case vbInteger 
     Name = Name & "Integer" 
    Case vbLong 
     Name = Name & "Long integer" 
    Case vbSingle 
     Name = Name & "Single-precision floating-point number" 
    Case vbDouble 
     Name = Name & "Double-precision floating-point number" 
    Case vbCurrency 
     Name = Name & "Currency" 
    Case vbDate 
     Name = Name & "Date" 
    Case vbString 
     Name = Name & "String" 
    Case vbObject 
     Name = Name & "Object" 
    Case vbError 
     Name = Name & "Error" 
    Case vbBoolean 
     Name = Name & "Boolean" 
    Case vbVariant 
     Name = Name & "Variant" 
    Case vbDataObject 
     Name = Name & "Data access object" 
    Case vbDecimal 
     Name = Name & "Decimal" 
    Case vbByte 
     Name = Name & "Byte" 
    Case vbUserDefinedType 
     Name = Name & "Variants that contain user-defined types" 
    Case Else 
     Name = Name & "Unknown type " & TypeOfVar 
    End Select 

    VarTypeName = Name 

End Function 

輸出DemoRaggedArray

Type of Main(0) is Array of type Variant 
    Main(0) is dimensioned as: (0 To 2) 
    (0)[Integer]=1 (1)[String]=A (2)[Boolean]=True 
Type of Main(1) is Array of type Variant 
    Main(1) is dimensioned as: (0 To 3) 
    (0)[Integer]=2 (1)[String]=B (2)[Boolean]=False (3)[Double-precision floating-point number]=1.2 
Type of Main(2) is Array of type Variant 
    Main(2) is dimensioned as: (1 To 2, 1 To 3) 
    (1,1)[Integer]=1 (2,1)[Boolean]=True 
    (1,2)[Double-precision floating-point number]=2.5 (2,2)[String]=String 
    (1,3)[Date]=27/12/2012 (2,3)[Uninitialised] 
Type of Main(3) is Integer 
    Value = 27 
Type of Main(4) is Array of type Variant 
    Main(4) is dimensioned as: (1 To 3, 1 To 4) 
    (1,1)[String]=A1 (2,1)[String]=B1 (3,1)[String]=C1 
    (1,2)[String]=A2 (2,2)[String]=B2 (3,2)[String]=C2 
    (1,3)[String]=A3 (2,3)[String]=B3 (3,3)[String]=C3 
    (1,4)[String]=A4 (2,4)[String]=B4 (3,4)[String]=C4 
Type of Main(5) is Uninitialised 

注日期顯示爲 「27/12/2012」,因爲這是我的國家的默認日期格式。如果您運行此代碼,它將以您所在國家/地區的默認格式顯示。