2010-05-26 4 views
4

Je suis en train de charger un fichier dans une macro VBA qui a été copié à partir, par exemple, une fenêtre Explorer.VBA: Lire fichier du presse-papiers

Je peux facilement obtenir les données à partir du presse-papiers en utilisant DataObject :: GetFromClipboard, mais l'interface VBA à DataObject ne semble pas avoir de méthodes pour travailler avec d'autres formats que le texte brut. Il existe uniquement des méthodes GetText et SetText.

Si je ne peux pas obtenir un flux de fichier directement à partir du DataObject, le (s) nom (s) de fichier le feront également, alors peut-être que GetText pourrait être forcé à retourner le nom d'un fichier placé dans le presse-papier?

Il y a très peu de documentation à trouver pour VBA partout. :(

Peut-être que quelqu'un pourrait me pointer vers une classe wrapper API pour VBA qui a ce genre de fonctionnalité?

Répondre

7

Cela fonctionne pour moi (dans un module);

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 

Utilisation:

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

pourquoi il est: 'CF_HDROP As Long = 15' – Qbik

+1

@Qbik qui est la valeur de l'API attend; http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168(v=vs .85) .aspx –

2

On dirait une étrange façon d'essayer d'obtenir au textfile. La classe DataObject est seulement pour travailler avec chaînes de texte depuis et vers le presse-papiers

Voici une très bonne ressource de ce qui suit:.. http://www.cpearson.com/excel/Clipboard.aspx

Si votre désir d'obtenir un flux de fichier d'un fichier que vous pouvez regarder dans les classes FileSystemObject et textstream

+1

Il est assez facile de lire un fichier si j'ai le nom de fichier. Ce que je suis intéressé est d'obtenir le nom du fichier qui a été mis sur le presse-papiers, ou d'une autre façon de lire le contenu du fichier (par exemple, si elle est pas disponible sur le disque.) GetText ne se contente pas retourne un chemin s'il y a un fichier dans le presse-papiers (ça aurait été sympa), il y a juste une exception. Mais peut-être que vous pouvez le forcer? J'ai lu quelque chose de très vague sur l'envoi d'un format à SetText sur un DataObject nouveau pour influencer quelles données sont récupérées par GetFromClipboard. ? Je ne sais pas. Les documents sont difficiles à trouver. :( – ReturningTarzan

0

Enregistrer les fichiers s'ils sont dans le presse-papiers dans le dossier de destination.

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