Arrays and Visual Studio Tools for Office
Arrays and Visual Studio Tools for Office
When developing solutions using Microsoft Visual Studio Tools for the Microsoft Office System, I (Paul Cornell) find it much easier to pass around intrinsic .NET object instead of Microsoft Office interop objects. Case in point: the Microsoft Office Excel Range object. One issue that always trips me up is that the Excel Range object is one-based, and .NET arrays are generally zero-based. There's nothing in my opinion that makes working with zero-based arrays any better than one-based arrays; it's just that .NET relies very heavily on zero-based arrays, and it's something I always need to be aware of when I'm developing Visual Studio Tools for Office solutions. To demonstrate, last night I wrote a helper function that takes a Range object and places its values into a .NET ArrayList object, as follows:
Private Function CreateArrayListFromRange _ 
    (ByRef Range As Excel.Range) _ 
    As ArrayList 
    ' Purpose: Given an Excel range, 
    ' returns a one-dimensional array of the range's values. 
    Dim arrayList As New ArrayList 
    For row As Integer = 1 To Range.Rows.Count 
        For column As Integer = 1 To Range.Columns.Count 
            arrayList.Add(CType(Range(row, column), _ 
                Excel.Range).Value2) 
        Next column 
    Next row 
    Return arrayList 
End Function 
You could call this function from a VSTO event in an Excel solution as follows:
Private Sub ThisWorkbook_Open() Handles ThisWorkbook.Open 
    ' Using one-dimensional array list. 
    ' Assumes you have a worksheet named "Sheet1" and a list 
    ' of values in the A2:C4 range on Sheet1. 
    Try 
        Dim arrayList As New ArrayList 
        arrayList = CreateArrayListFromRange _ 
            (CType(ThisWorkbook.Worksheets("Sheet1"), _ 
            Excel.Worksheet).Range("A2", "C4")) 
        For item As Integer = 0 To arrayList.Count - 1 
            MsgBox(arrayList.Item(item) & " (item " & item & ")") 
        Next item 
    Catch ex As Exception 
        MsgBox(ex.Message) 
    End Try 
End Sub 
Note that in the CreateArrayListFromRange function, I can simply iterate through the values using a one-based nomenclature and write the values to the ArrayList object. However, to read these values out of the ArrayList object in the ThisWorkbook_Open event, I need to use a zero-based nomenclature. If I didn't subtract one from arrayList.Count I would get an out-of-bounds exception.
Another issue with this code snippet is that an ArrayList object works fine if you're only concerned about a single row or single column of cell values. This code doesn't work well for a multidimensional cell array. What I really want is to use the good old Array object and make it mimic the multidimensional nature of a deeper range of cells. Here's how this morning I modified my earlier code to do this:
Private Function CreateArrayFromRange _ 
    (ByRef Range As Excel.Range, _ 
    ByVal rows As Integer, ByVal columns As Integer) As Array 
    ' Purpose: Given an Excel range, returns a multidimensional 
    ' array of the range's values. 
    Dim array As Array = array.CreateInstance _ 
        (GetType(Object), rows, columns) 
    For row As Integer = 1 To rows 
        For column As Integer = 1 To columns 
            array.SetValue((CType(Range(row, column), _ 
                Excel.Range).Value2), row - 1, column - 1) 
        Next column 
    Next row 
    Return array 
End Function 
Now I can call this function as follows:
Private Sub ThisWorkbook_Open() Handles ThisWorkbook.Open 
    ' Using multidimensional array list. 
    ' Assumes you have a worksheet named "Sheet1" and a list 
    ' of values in the A2:C4 range on Sheet1. 
    Try 
        Dim range As Excel.Range = _ 
            CType(ThisWorkbook.Worksheets("Sheet1"), _ 
            Excel.Worksheet).Range("A2", "C4") 
        Dim array As Array = _ 
            CreateArrayFromRange(range, range.Rows.Count, _ 
            range.Columns.Count) 
        For row As Integer = 0 To range.Rows.Count - 1 
            For column As Integer = 0 To range.Columns.Count - 1 
                MsgBox(array.GetValue(row, column) & _ 
                    " (item " & row & ", " & column & ")") 
            Next column 
        Next row 
    Catch ex As Exception 
        MsgBox(ex.Message) 
    End Try 
End Sub 
Notice that I have to be even more careful when I deal with one-based arrays and zero-based arrays, especially when it comes to the array.SetValue call in the CreateArrayFromRange function. 
详:http://blogs.msdn.com/vsto/archive/2003/11/25/39744.aspx 
                    
                
                
            
        
浙公网安备 33010602011771号