我正在尝试将多个单元格中的值复制到一个单元格中。如果我只想合并单元格的值,则可以使用
Dim str as string = My.Computer.ClipBoard.GetText
oxlapp.ActiveCell.Value = str
但是
在这种情况下,我需要包括html标记以创建表,并且还希望包括粗体,斜体和带下划线的格式。因此,我不仅要了解剪贴板中的文本,还需要了解一些单元格属性。
我知道它们应该在那里,因为您当然可以复制/粘贴整个单元格。
到目前为止,我尝试通过使用获取Excel单元格
My.Computer.Clipboard.GetData(XlClipboardFormat.xlClipboardFormatTable)
和
My.Computer.Clipboard.GetData(XlClipboardFormat.xlClipboardFormatCSV)
但是在调试时,我注意到它们都返回了Nothing
。
有人知道我如何从剪贴板中获取所有单元格属性吗?
为了更清楚一点,我想要这个
要变成这个:
如果使用剪贴板以外的其他方法,我很乐意尝试。
答案 0 :(得分:1)
您需要使用剪贴板中的另一种格式-XML Spreadsheet
。复制的数据包含在具有其自身结构和属性的特殊XML中。让我们获取以下工作表的数据:
如您所见,每个单元格都有一些格式。此数据的XML如下:
<ss:Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<ss:Styles>
<ss:Style ss:ID="Default" ss:Name="Normal">
<ss:Alignment ss:Vertical="Bottom"/>
<ss:Borders/>
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
<ss:Interior/>
<ss:NumberFormat/>
<ss:Protection/>
</ss:Style>
<ss:Style ss:ID="s62">
<ss:Interior ss:Color="#FFFF00" ss:Pattern="Solid"/>
</ss:Style>
<ss:Style ss:ID="s63">
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#000000" ss:Bold="1"/>
</ss:Style>
<ss:Style ss:ID="s64">
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#0000FF"/>
</ss:Style>
<ss:Style ss:ID="s65">
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#000000" ss:Italic="1"/>
</ss:Style>
</ss:Styles>
<ss:Worksheet ss:Name="Sheet1">
<ss:Table ss:ExpandedColumnCount="2" ss:ExpandedRowCount="2" ss:DefaultRowHeight="15">
<ss:Row>
<ss:Cell ss:StyleID="s62">
<ss:Data ss:Type="String">A</ss:Data>
</ss:Cell>
<ss:Cell ss:StyleID="s63">
<ss:Data ss:Type="String">1</ss:Data>
</ss:Cell>
</ss:Row>
<ss:Row>
<ss:Cell ss:StyleID="s64">
<ss:Data ss:Type="String">B</ss:Data>
</ss:Cell>
<ss:Cell ss:StyleID="s65">
<ss:Data ss:Type="String">2</ss:Data>
</ss:Cell>
</ss:Row>
</ss:Table>
</ss:Worksheet>
</ss:Workbook>
如您所见,您具有有关以相应样式进行格式设置的所有信息。对于实例,A
单元格中的值A1
具有样式s62
(StyleID
属性)-您可以在{{1 }}节点。此XML中的行和列结构是隐式的-也就是说,您不会看到行和列的索引-您需要自己计算它们。例如,第一个Style
节点中的第二个Styles
节点是第一行第二列。
以下代码在上图中生成数据,并检索要操作的适当元素。
注意事项1。如果仔细观察,Cell
节点具有两个 Row
命名空间:第一个是默认名称,第二个是第二个是前缀Workbook
。请记住-您始终需要使用urn:schemas-microsoft-com:office:spreadsheet
前缀!
请注意2。。此方法有一个缺点-它无法理解隐藏的行(手动或通过自动过滤器)和列!它也包括隐藏的行/列!
ss
实际上,您不需要使用剪贴板来获取此XML-您只需要使用ss
属性的Imports <xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
Imports <xmlns:x="urn:schemas-microsoft-com:office:excel">
Sub GetCellsWithFormat()
'// Create new Excel app
Dim xlApp = New Excel.Application With {.Visible = True}
Dim book = xlApp.Workbooks.Add()
Dim sheet = DirectCast(book.Sheets(1), Excel.Worksheet)
'// Apply some formatting
With sheet
.Range("A1").Interior.Color = Excel.XlRgbColor.rgbYellow
.Range("B1").Font.Bold = True
.Range("A2").Font.Color = Excel.XlRgbColor.rgbBlue
.Range("B2").Font.Italic = True
'// Add some values
Dim arr = Array.CreateInstance(GetType(String), {2, 2}, {1, 1})
arr(1, 1) = "A" : arr(1, 2) = "1"
arr(2, 1) = "B" : arr(2, 2) = "2"
With .Range("A1:B2")
.Value = arr
.Copy() '//Copy cells to clipboard
End With
Dim xml As XElement
Using xml_stream = DirectCast(Clipboard.GetData("XML Spreadsheet"), Stream)
'// Get rid of last character (new line) to avoid parsing error
xml_stream.SetLength(xml_stream.Length - 1)
xml = XElement.Load(xml_stream)
End Using
'// Get any element you need
Dim styles = xml.<ss:Styles>(0)
Dim table = xml.<ss:Worksheet>.<ss:Table>(0)
Dim rows = table.<ss:Row>
'// Do something with this data
End With
End Sub
值:
xlRangeValueXMLSpreadsheet
答案 1 :(得分:0)
当我想允许从Excel复制到我编写的自定义Windows应用程序中的数据时,我使用GetText()而不是GetData()。
将ClipboardText设为字符串=什么都没有
ClipboardText = My.Computer.Clipboard.GetText()
如果是从Excel复制到剪贴板的多个单元格,则根据选择,可以用vbTab和vbCrLf分隔它们。