2010-05-26 7 views
4

Я пытаюсь загрузить файл в макросе VBA, который был скопирован, скажем, из окна проводника.VBA: Прочитать файл из буфера обмена

Я могу легко получить данные из буфера обмена с помощью DataObject :: GetFromClipboard, но интерфейс VBA для DataObject, похоже, не имеет методов работы с любыми другими форматами, чем обычный текст. Существуют только методы 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

+1

@Qbik - это значение, которое ожидает API; http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168(v=vs +0,85) .aspx –

2

Кажется странным способом, чтобы попытаться получить в текстовом файле. Класс DataObject только для работы с текстовые строки и из буфера обмена

Вот очень хороший ресурс, что:.. http://www.cpearson.com/excel/Clipboard.aspx

Если ваше желание получить файл поток файла, который вы можете посмотреть в классы FileSystemObject и TextStream

+1

Достаточно легко прочитать файл, если у меня есть имя файла. Меня интересует имя файла, который был помещен в буфер обмена, или какой-либо другой способ прочитать содержимое файла (например, если он недоступен на диске.) GetText не просто верните путь, если в буфере обмена есть файл (это было бы неплохо), он просто генерирует исключение. Но, может быть, вы можете заставить это? Я прочитал что-то очень неопределенное относительно отправки формата в SetText в новом DataObject, чтобы повлиять на то, какие данные извлекаются GetFromClipboard. ? Не знаю. Документов трудно найти. :( – ReturningTarzan

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 
Смежные вопросы