我需要检索几千个单元格的背景属性(Range.Interior.Color)。由于COM-Interop的限制,单独遍历每个单元的速度非常慢。
是否可以在一个调用中从包含多个单元格的Range中检索不是.Text、.Value或.Value2的单元格属性?
发布于 2016-11-18 00:45:31
我会尝试以下代码(用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#程序就可以获取这个位图并获得各个像素,因为单元格的位置很容易计算,因为行和列具有相同的高度和宽度。
我知道这只是一个变通办法,但我不认为有更好的解决方案。它只是一种方式(不能写,只能读),很难扩展到其他属性(可能是边框和字体颜色)。
发布于 2016-09-01 18:15:13
你可以做到这一点,但这不是微不足道的,所以我真的不确定是否值得费力去模仿类似的行为。
基本上,您需要在Excel中创建一个宏来为您完成这项工作,然后在宏完成后简单地返回结果。这基本上模拟了Value的行为。我真的不确定为什么MS决定不在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 Functionhttps://stackoverflow.com/questions/39265034
复制相似问题