2010-05-26 143 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