我需要检索几千个单元格的背景属性(Range.Interior.Color
)。由于COM-Interop限制,单独循环每个单元格非常慢。
是否可以从一次调用中包含多个单元格的.Text
中检索不是.Value
,.Value2
或Range
的单元格属性?
答案 0 :(得分:0)
你可以做到这一点,但这不是微不足道的,所以我不确定它是否值得尝试模仿类似行为的麻烦。
基本上你需要在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 Function
答案 1 :(得分:0)
我会尝试以下内容(用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#程序可以获取此位图并获取单个像素,因为行和列具有相同的高度和宽度,因此可以轻松计算单元格的位置。
我知道这只是一种解决方法,但我认为没有更好的解决方案。它只是一种方式(不能写,只读),很难扩展到其他属性(可能是边框和字体颜色)。