在一次调用中从Excel中检索多个单元格属性?

max*_*axp 5 c# excel com-interop ms-office

我需要检索Range.Interior.Color几千个单元格的背景属性().由于COM-Interop限制,单独循环每个单元格非常慢.

是否有可能检索不在单元格属性.Text,.Value.Value2从一个Range包含多个单元格在一个单一的电话吗?

InB*_*een 0

你可以做到这一点,但这并不简单,所以我不确定是否值得尝试模仿类似的行为。

基本上,您需要在 Excel 中创建一个为您完成工作的宏,然后在宏完成后简单地返回结果。这基本上模仿了 的行为Value。我不太确定为什么 MS 决定不以Range相同的方式实现所有属性,很奇怪。

为此,您需要引用Microsoft Visual Basic for Application Extensibility 5.3COM 库。这为您提供了动态构建宏并将其添加到 Excel 工作簿所需的工具。

第一步是创建一个方法,将模块和所需的宏添加到您正在交互的工作簿中(如果您在打开和关闭的不同工作表上使用该功能,您也可以打开一个空白工作簿并在其中创建宏) )。

以下示例添加一个宏,该宏返回一个数组,其中包含指定范围内的所有单元格颜色。这是用 VBA 编写的,我没有 VS,但 C# 版本应该非常容易移植。

Sub AddCode()
   Dim wb As Workbook
   Dim xPro As VBIDE.VBProject
   Dim xCom As VBIDE.VBComponent
   Dim xMod As VBIDE.CodeModule

   Set wb = ActiveWorkbook

   With wb
       Set xPro = .VBProject
       Set xCom = xPro.VBComponents.Add(vbext_ct_StdModule)
       Set xMod = xCom.CodeModule

       With xMod
           .AddFromString "Public Function GetInteriorColors(r As Range) As Variant" & vbCrLf & _
                          "    Dim colors() As Long" & vbCrLf & _
                          "    Dim row As Integer" & vbCrLf & _
                          "    Dim column As Integer" & vbCrLf & _
                          "    ReDim colors(r.Rows.Count - 1, r.Columns.Count - 1)" & vbCrLf & _
                          "    For row = 1 To r.Rows.Count" & vbCrLf & _
                          "        For column = 1 To r.Columns.Count" & vbCrLf & _
                          "            colors(row - 1, column - 1) = r.Cells(row, column).Interior.Color" & vbCrLf & _
                          "        Next" & vbCrLf & _
                          "    Next" & vbCrLf & _
                          "    GetInteriorColors = colors" & vbCrLf & _
                          "End Function"
       End With
   End With
End Sub
Run Code Online (Sandbox Code Playgroud)

需要注意的事项;我有时在执行时会遇到奇怪的错误AddFromString。宏代码已正确添加到模块中,但有时会出现错误;吞咽它似乎没有害处,但如果你有同样的问题,我会调查一下。

现在,一旦有了宏,返回结果就很容易了(同样,用 VBA 编写):

Public Function GetColors(r As Range) As Long()
    //Note the absolute path to the macro; this is probably needed if the macro is in a different workbook.
    GetColors = Application.Run(ActiveWorkbook.Name & "!GetInteriorColors", r)
End Function
Run Code Online (Sandbox Code Playgroud)