2009-10-07 53 views
2

我遇到了VSTO解決方案的性能問題,我相信其原因主要是cellColor逐個單元格設置的方式。如何將數組從C#(VSTO)項目傳遞到VBA宏

這取決於記錄集中的數據,因此每次都有所不同。 (我不能從另一行/列使用copyFormats)

它類似於填充值的範圍,只爲那個有幾種方法。

我考慮先在存儲器中創建C#中的整個事情(一個XlColorIndex [,]數組),我通過給VBA方法類似於下面的一個:

Sub fillInterior(ByRef rg As Range, a As Variant) 
    //a is a double array that represents the colors for the spreadsheet 
    Dim r As Long, c As Long 
    Dim tmpRg As Range 
    r = 1 
    c = 1 
    For Each Row In a 
     For Each colorIdx In Row 
      Set tmpRg = rg(r, c) 
      With tmpRg.Interior 
       .ColorIndex = colorIdx 
       .PatternColorIndex = xlAutomatic 
       .PatternColor = xlSolid 
      End With 
      c = c + 1 
     Next 
     c = 1 
     r = r + 1 
    Next 
End Sub 

我一直試圖執行這個宏在下面的方法,但都沒有取得成功呢,任何指針是極大的讚賞:

  Excel.Range rg = this.Range[this.Cells[5, 3], this.Cells[6, 4]]; 

      object[,] test2 = new object[2, 2]; 
      test2[0, 0] = 15; 
      test2[0, 1] = 15; 
      test2[1, 0] = 15; 
      test2[1, 1] = 15; 

      this.Application.Run("Sheet1.fillInterior", rg, test2, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing); 

我試過INT [,] -

我沒有得到一個不同的ER ROR當我試圖可空int或double: 雙[,](可空雙陣列):

The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG)) 

如果我不嘗試空類型,我得到了以下HRESULT錯誤

(類型missmatch?)
Exception from HRESULT: 0x800A000D 
+0

突然出現類型不匹配發生在我的VBA代碼進入雙ForEach時,這不適用於我從C#傳遞的數組。 – 2009-10-08 04:29:36

回答

2

好的,我應該更好地閱讀this:變體應該避免,所以如果我有選擇寫我的VBA,我最好沒有變體,但有一個適當的數組。

其次,我用VBA陣列錯了,我應該做的多維數組以下(source):

我的VBA代碼現在看起來是這樣的:

Sub fillInteriorMulti(rg As Range, Arr() As Long) 
    Dim N As Long, Ndx1 As Long, Ndx2 As Long 
    Dim icol As Long 
    Dim irow As Long 
    Dim NumDims As Long 


    // Custom Function: Get the number of array dimensions. 
    // NumberOfArrayDimensions will return 0 
    // if the array is not allocated. 

    NumDims = NumberOfArrayDimensions(Arr:=Arr) 
    Select Case NumDims 
     Case 0 
      // unallocated array 
      Exit Sub 
     Case 1 
      // single dimensional array 
      For N = LBound(Arr) To UBound(Arr) 
       With rg(N, 1).Interior 
        .ColorIndex = Arr(N) 
        .PatternColorIndex = xlAutomatic 
        .PatternColor = xlSolid 
       End With 
      Next N 
     Case 2 
      // 2 dimensional array 
      For Ndx1 = LBound(Arr, 1) To UBound(Arr, 1) 
       For Ndx2 = LBound(Arr, 2) To UBound(Arr, 2) 
        With rg(Ndx1, Ndx2).Interior 
         .ColorIndex = Arr(Ndx1, Ndx2) 
         .PatternColorIndex = xlAutomatic 
         .PatternColor = xlSolid 
        End With 
       Next Ndx2 
      Next Ndx1 
     Case Else 
      // Too many dimensions - Do Nothing 
    End Select 
End Sub 

Public Function NumberOfArrayDimensions(Arr As Variant) As Integer 
    // NumberOfArrayDimensions 
    // This function returns the number of dimensions of an array. An unallocated dynamic array 
    // has 0 dimensions. This condition can also be tested with IsArrayEmpty. 

    Dim Ndx As Integer 
    Dim Res As Integer 
    On Error Resume Next 
    // Loop, increasing the dimension index Ndx, until an error occurs. 
    // An error will occur when Ndx exceeds the number of dimension 
    // in the array. Return Ndx - 1. 
    Do 
     Ndx = Ndx + 1 
     Res = UBound(Arr, Ndx) 
    Loop Until Err.Number <> 0 

    NumberOfArrayDimensions = Ndx - 1 
End Function 

最後的C#代碼測試這個:

  int[] test3 = new int[3]; 
      test3[0] = 15; 
      test3[1] = 15; 
      test3[2] = 48; 

      int[,] test4 = new int[2, 2]; 
      test4[0, 0] = 15; 
      test4[0, 1] = 15; 
      test4[1, 0] = 15; 
      test4[1, 1] = 15; 

      this.Application.Run("Sheet1.fillInteriorMulti", rg, test4, 
       missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, 
       missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, 
       missing, missing, missing, missing, missing, missing, missing, missing); 
+0

如果您不滿意,請讓我知道原因 – 2012-05-15 03:52:39

0

醜陋的黑客或概念證明,將雙數組轉換爲字符串。傳遞字符串。

Sub fillInteriorString(rg As Range, str As String) 
    Dim i As Long, j As Long 
    i = 1 
    j = 1 
    a = Split(str, "@") 
    For Each part In a 
     b = Split(part, ",") 
     For Each colorIdx In b 
      With rg(i, j).Interior 
       .ColorIndex = colorIdx 
       .PatternColorIndex = xlAutomatic 
       .PatternColor = xlSolid 
      End With 
      j = j + 1 
     Next 
     j = 1 
     i = i + 1 
    Next 
End Sub 

C#代碼:

  string testString = "15,15,[email protected],48,15"; 


      this.Application.Run("Sheet1.fillInteriorString", rg, testString, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, 
       System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing); 

反正,我知道它的工作原理 - 我現在正在研究,希望SAFEARRAYS我仍然可以通過數組,而不是一個字符串。