«Вставить» строковую переменную в Excel VBA вместо содержимого буфера обмена? - PullRequest
1 голос
/ 18 января 2011

У меня есть строковая переменная, которая содержит таблицу HTML в Excel VBA.Я знаю, что когда эта таблица хранится в буфере обмена, и я вызываю .PasteSpecial, Excel выполняет изящную предварительную обработку и заполняет ячейки на текущем листе так же, как они отображаются в таблице.

Однако, еслиЯ просто устанавливаю .Value ячейки / диапазона в строковую переменную, никакой такой предварительной обработки не происходит, и вся строка, теги HTML и все, выгружаются в ячейку.Мне нужен первый результат, но я не могу использовать буфер обмена, потому что он используется этим приложением в другом месте, и нет никакой гарантии, что я не перезаписал бы критические данные.Он также используется асинхронно, поэтому я не могу просто сохранить текущее содержимое буфера обмена, использовать буфер обмена, а затем восстановить предыдущее содержимое буфера обмена.

Итак, есть ли способ получить «предварительную обработку вставки»"произойти при установке значения для диапазона с отформатированной строкой?

Ответы [ 3 ]

0 голосов
/ 19 января 2011

В любом случае, я не могу вспомнить, чтобы вызвать препроцессор 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
0 голосов
/ 19 января 2011

Это просто комментарий (stackeoverflow пока не позволяет мне комментировать корректный способ).

Вы, вероятно, можете сделать это так, как хотите, используя некоторый API.

Долгое времяназад я поиграл с ним (искал какой-нибудь способ обмануть MS Word) и помню, что вы можете хранить любой контент в буфере обмена, если вы введете правильный идентификатор типа контента (например, чистый текст, форматированный текст, * 1005).* 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
0 голосов
/ 18 января 2011

Мне все равно было бы любопытно узнать ответ, если у кого-нибудь он есть, но я решил просто пойти дальше и отказаться от идеи хранить таблицу на рабочем листе.Вместо этого я сам анализирую таблицу и нахожу нужные мне значения с помощью функции InStr (так как они в основном являются смежными парами ключ = значение), что не слишком медленно для моего приложения.

...