在单个调用中从Excel中检索多个单元格属性
本文关键字:单元格 属性 检索 Excel 单个 调用 | 更新日期: 2023-09-27 18:05:01
我需要检索几千个单元格的背景属性(Range.Interior.Color
)。由于COM-Interop的限制,单独遍历每个单元非常慢。
是否有可能检索细胞属性,不是.Text
, .Value
或.Value2
从Range
包含一个以上的细胞在一个单独的调用?
我会尝试以下(在VBA中编写,但可以转换为c#):
Public Sub GetColors()
Dim ewsTarget As Worksheet: Set ewsTarget = ActiveWorkbook.Worksheets(1)
ewsTarget.Copy , ewsTarget.Parent.Worksheets(ewsTarget.Parent.Worksheets.Count)
Dim ewsCopy As Worksheet: Set ewsCopy = ewsTarget.Parent.Worksheets(ewsTarget.Parent.Worksheets.Count)
ewsCopy.UsedRange.ClearContents
ewsCopy.UsedRange.Columns.EntireColumn.ColumnWidth = 0.5
ewsCopy.UsedRange.Rows.EntireRow.RowHeight = 5#
ewsCopy.UsedRange.CopyPicture xlScreen, xlBitmap
ewsCopy.Delete
End Sub
这段代码在剪贴板上放置了一个位图。此位图是从工作表的副本创建的,但是,单元格内容被删除,因此您将只看到单元格的背景,而且行和列具有相同的高度和长度。然后你的c#程序可以获取这个位图,并考虑到单元格的位置可以很容易地计算出来,因为行和列具有相同的高度和宽度。
我知道这只是一个权宜之计,但我不认为有更好的解决方案。它是单向的(不能写,只能读),并且很难扩展到其他属性(可能是边框和字体颜色)。
您可以这样做,但这不是微不足道的,所以我不确定是否值得尝试模仿类似的行为。
基本上你需要在Excel中创建一个宏来为你做这项工作,然后在宏完成后简单地把结果带回来。这基本上模拟了Value
的行为。我真的不确定为什么微软决定不实现Range
中的所有属性以相同的方式表现,奇怪。
为了做到这一点,你需要引用Microsoft Visual Basic for Application Extensibility 5.3
COM库。这为您提供了动态构建宏并将宏添加到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
值得注意的事情;我有时得到一个奇怪的错误时,执行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