2010-05-26 142 views
4

我試圖從一個已經從一個瀏覽器窗口複製過來的VBA宏中加載一個文件。VBA:從剪貼板中讀取文件

我可以很容易地使用DataObject :: GetFromClipboard從剪貼板獲取數據,但到DataObject的VBA接口似乎沒有處理純文本以外的任何其他格式的方法。只有GetText和SetText方法。

如果我無法直接從DataObject獲取文件流,文件名也可以,所以也許GetText可能會被迫返回放置在剪貼板上的文件的名稱?

對於任何地方的VBA,幾乎沒有文檔可以找到。 :(

也許有人會指出我的API包裝類VBA有這種功能?

回答

7

這適用於我(在一個模塊中);

Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal uFormat As Long) As Long 
Private Declare Function OpenClipboard Lib "user32" (ByVal Hwnd As Long) As Long 
Private Declare Function GetClipboardData Lib "user32" (ByVal uFormat As Long) As Long 
Private Declare Function CloseClipboard Lib "user32"() As Long 
Private Declare Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" (ByVal drop_handle As Long, ByVal UINT As Long, ByVal lpStr As String, ByVal ch As Long) As Long 

Private Const CF_HDROP As Long = 15 

Public Function GetFiles(ByRef fileCount As Long) As String() 
    Dim hDrop As Long, i As Long 
    Dim aFiles() As String, sFileName As String * 1024 

    fileCount = 0 

    If Not CBool(IsClipboardFormatAvailable(CF_HDROP)) Then Exit Function 
    If Not CBool(OpenClipboard(0&)) Then Exit Function 

    hDrop = GetClipboardData(CF_HDROP) 
    If Not CBool(hDrop) Then GoTo done 

    fileCount = DragQueryFile(hDrop, -1, vbNullString, 0) 

    ReDim aFiles(fileCount - 1) 
    For i = 0 To fileCount - 1 
     DragQueryFile hDrop, i, sFileName, Len(sFileName) 
     aFiles(i) = Left$(sFileName, InStr(sFileName, vbNullChar) - 1) 
    Next 
    GetFiles = aFiles 
done: 
    CloseClipboard 
End Function 

用途:

Sub wibble() 
    Dim a() As String, fileCount As Long, i As Long 
    a = GetFiles(fileCount) 
    If (fileCount = 0) Then 
     MsgBox "no files" 
    Else 
     For i = 0 To fileCount - 1 
      MsgBox "found " & a(i) 
     Next 
    End If 
End Sub 
+0

爲什麼有:'CF_HDROP As Long = 15'? – Qbik 2014-04-23 21:39:39

+1

@Qbik這是API的期望值; http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168(v=vs 0.85)的.aspx – 2014-04-24 10:09:27

2

似乎是一個奇怪的方式,試圖獲得在文本文件。該數據對象類是僅適用於工作文本字符串,然後從剪貼板

這裏是一個很好的資源:。 http://www.cpearson.com/excel/Clipboard.aspx

如果你想獲得一個文件,你可以看看FileSystemObject對象和文本流類的文件流

+1

如果我有文件名,讀取文件很簡單。我感興趣的是獲取放置在剪貼板上的文件的名稱,或者其他方式來讀取文件的內容(例如,如果它在磁盤上不可用)。 GetText不會簡單地如果剪貼板上有一個文件返回一個路徑(這本來不錯),它只是拋出一個異常。 但也許你可以強迫它?我讀了一些非常模糊的內容,將一種格式發送到新的DataObject上的SetText,以影響GetFromClipboard檢索的數據。 ?我不知道。文檔很難找到。 :( – ReturningTarzan 2010-05-26 14:14:19

0

保存,如果他們在剪貼板到目標文件夾中的文件。

Public Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long 

Public Const CF_HDROP  As Long = 15 

     Public Function SaveFilesFromClipboard(DestinationFolder As String) As Boolean 
      SaveFilesFromClipboard = False 
      If Not CBool(IsClipboardFormatAvailable(CF_HDROP)) Then Exit Function 
      CreateObject("Shell.Application").Namespace(CVar(DestinationFolder)).self.InvokeVerb "Paste" 
      SaveFilesFromClipboard = True 
     End Function