在excel VBA中“粘贴”字符串变量而不是剪贴板的内容?

时间:2011-01-18 16:16:13

标签: excel vba paste

我有一个字符串变量,其中包含excel VBA中的HTML表。我知道当这个表存储在剪贴板中并且我调用.PasteSpecial时,Excel会进行一些漂亮的预处理,并以与它们在表中显示的方式相同的方式填充当前工作表中的单元格。

但是,如果我只是将单元格/范围的.Value设置为字符串变量,则不会进行此类预处理,并且整个字符串,HTML标记和所有字符串都会转储到单元格中。我想要前一个结果,但我不能使用剪贴板,因为它被其他地方的应用程序使用,并且不能保证我不会覆盖关键数据。它也被异步使用,所以我不能简单地保存剪贴板的当前内容,使用剪贴板,然后恢复剪贴板的先前内容。

那么,在设置带有格式化字符串的范围的值时,有没有办法让“粘贴预处理”发生?

3 个答案:

答案 0 :(得分:0)

如果有人知道,我仍然很想知道答案,但我决定继续放弃将表格存储在工作表中的想法。相反,我自己解析表并使用InStr函数找到我需要的值(因为它们通常是相邻的键=值对),这对我的应用程序来说并不是非常慢。

答案 1 :(得分:0)

无论如何我都想不到在没有剪贴板的情况下调用Excel的预处理器。对于解析,您可能需要查看“拆分”功能。这是一个例子。

Sub ParseTable()

    Dim sHtmlTable As String
    Dim vaTable As Variant
    Dim i As Long

    Const STDSTART = "<td"
    Const STDEND = "</td"

    sHtmlTable = "<table border=""1""><tr><td>row 1, cell 1</td><td>row 1, cell 2</td></tr><tr><td>row 2, cell 1</td><td>row 2, cell 2</td></tr></table>"

    vaTable = Split(sHtmlTable, ">")

    For i = LBound(vaTable) To UBound(vaTable)
        If vaTable(i) = STDSTART Then
            Debug.Print Replace(vaTable(i + 1), STDEND, "")
        End If
    Next i

End Sub

答案 2 :(得分:0)

这只是一个评论(stackeoverflow不允许我评论propper方式)。

您可能可以按照自己想要的方式使用某些API。

很久以前我玩过它(寻找某种方法来欺骗MS Word)我记得你可以将任何内容存储到剪贴板,只要你输入内容类型的正确id(如纯文本) ,格式化文本, html 等)。存储内容后,您必须使用相应的API函数再次粘贴正确类型的内容。

我没有像我预期的那样快速进步,而且时间不够,所以我放弃了这个想法。如果您想给它一个机会,请查询MSDN以获取API调用(我现在没有它,否则我会马上给你)。

编辑:我找到了代码。以下所有代码都应保存在一个模块中:

' Clipboard functions:
Private Declare Function OpenClipboard Lib "USER32" (ByVal hWnd As Long) As Long
Private Declare Function CloseClipboard Lib "USER32" () As Long
Private Declare Function GetClipboardData Lib "USER32" (ByVal wFormat As Long) As Long
Private Declare Function IsClipboardFormatAvailable Lib "USER32" (ByVal wFormat As Long) As Long
Private Declare Function RegisterClipboardFormat Lib "USER32" Alias "RegisterClipboardFormatA" (ByVal lpString As String) As Long
' Memory functions:
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)

Public Function GetClipboardIDForCustomFormat(ByVal sName As String) As Long
Dim wFormat As Long
    wFormat = RegisterClipboardFormat(sName & Chr$(0))
    If (wFormat > &HC000&) Then
        GetClipboardIDForCustomFormat = wFormat
    End If
End Function

Public Function GetClipboardDataAsString(ByVal lFormatID As Long) As String
'Public Function GetClipboardDataAsString(ByVal hWndOwner As Long, ByVal lFormatID As Long) As String
Dim bData() As Byte
Dim hMem As Long
Dim lSize As Long
Dim lPtr As Long

    ' Open the clipboard for access:
    If (OpenClipboard(0&)) Then
'    If (OpenClipboard(hWndOwner)) Then
        ' Check if this data format is available:
        If (IsClipboardFormatAvailable(lFormatID) <> 0) Then
            ' Get the memory handle to the data:
            hMem = GetClipboardData(lFormatID)
            If (hMem <> 0) Then
                ' Get the size of this memory block:
                lSize = GlobalSize(hMem)
                If (lSize > 0) Then
                    ' Get a pointer to the memory:
                    lPtr = GlobalLock(hMem)
                    If (lPtr <> 0) Then
                        ' Resize the byte array to hold the data:
                        ReDim bData(0 To lSize - 1) As Byte
                        ' Copy from the pointer into the array:
                        CopyMemory bData(0), ByVal lPtr, lSize
                        ' Unlock the memory block:
                        GlobalUnlock hMem

                        ' Now return the data as a string:
                        GetClipboardDataAsString = StrConv(bData, vbUnicode)

                    End If
                End If
            End If
        End If
        CloseClipboard
    End If
End Function