2017-02-15 2 views
1

Meine Frage ist, wie Sie den Autor eines bestimmten Word-Dokuments erhalten.Get File Author von Word-Dokument, VBA

Meine Funktion ist:

Public Function GetFileOwner(pFile As String) As String 

GetFileOwner = pFile.Owner 

End Function 

ich hier über 100 Dokumente durchkommen, ich habe bereits versucht .BuiltInDocmementProperties., aber das war viel zu langsam ...

auch die Shell.Application Funktion nicht funktionieren für mich, denn das funktioniert nur mit allen Dateien in einem Ordner, aber ich brauche es für bestimmte Dateien ..

Kennt jemand eine andere schnellere Lösung? Und gibt es auch einen Weg für PDF - Dokumente?

+0

Könnten Sie bitte auch die Codes für '.BuiltInDocmementProperties' und' Shell.Application', die Sie bereits ausprobiert haben, ausgeben und Fehler ausgeben. Wenn Sie auch eine Antwort auf PDF erhalten möchten, IMO besser Sie es zum Titel hinzufügen, und beide zu den Tags hinzufügen. – omegastripes

Antwort

0

Sie können dies in .NET ganz einfach tun, so schrieb ich eine kleine DLL mit nicht verwalteten Exporte:

using System; 
using System.IO; 
using System.Linq; 
using System.Runtime.InteropServices; 
using RGiesecke.DllExport; 
using System.IO.Compression; 
using System.Xml.Linq; 

namespace DocxProperties 
{ 
    public class DocxPropertyGetter 
    { 
     [DllExport(nameof(GetDocxProp), CallingConvention.StdCall)] 
     [return: MarshalAs(UnmanagedType.AnsiBStr)] 
     public static string GetDocxProp([MarshalAs(UnmanagedType.AnsiBStr)] string wordPath, [MarshalAs(UnmanagedType.AnsiBStr)] string propName) 
     { 
      try 
      { 
       using (var fileStream = File.Open(wordPath, FileMode.Open)) 
       using (var parentArchive = new ZipArchive(fileStream)) 
       { 
        return GetPropName(parentArchive, propName); 
       } 
      } 
      catch (Exception ex) 
      { 
       return ex.ToString(); 
      } 
     } 

     private static string GetPropName(ZipArchive parentArchive, string propName) 
     { 
      var core = parentArchive.Entries.FirstOrDefault(e => e.FullName == "docProps/core.xml"); 

      using (var coreStream = core.Open()) 
      { 
       var doc = XDocument.Load(coreStream); 

       foreach (var descendant in doc.Descendants()) 
       { 
        if (descendant.Name.LocalName.Equals(propName, StringComparison.InvariantCultureIgnoreCase)) 
        { 
         return descendant.Value; 
        } 
       } 
      } 

      return string.Empty; 
     } 

    } 
} 

Der Code etwas ausführlicher ist als notwendig, um einige merkwürdige Fehler in RGiesecke.DllExport zu vermeiden wenn ich .FirstOrDefault() oder .GetEntry() verwendet habe;

Diese DLL kann wiederum von VBA wie folgt aufgerufen werden:

Option Explicit 

#If Win64 Then 
    Private Declare PtrSafe Function LoadLibraryA Lib "kernel32" (ByVal lpLibFileName As String) As Long 
    Private Declare PtrSafe Function GetDocxProp Lib "DocxProperties64.dll" (ByVal wordPath As String, ByVal propName As String) As String 
#Else 
    Private Declare Function LoadLibraryA Lib "kernel32" (ByVal lpLibFileName As String) As Long 
    Private Declare Function GetDocxProp Lib "DocxProperties64.dll" (ByVal wordPath As String, ByVal propName As String) As String 
#End If 

Sub TestAuthorName() 
    Dim dllPath As String 

    #If Win64 Then 
     dllPath = "DocxProperties64.dll" 
    #Else 
     dllPath = "DocxProperties32.dll" 
    #End If 

    Call LoadLibrary(dllPath) 

    Debug.Print GetDocxProp(ThisWorkbook.path & "\EmptyDoc.docx", "creator") 

End Sub 

Private Function LoadLibrary(dllName As String) As Long 
    Dim path As String 
    path = ThisWorkbook.path & "\" & dllName 
    LoadLibrary = LoadLibraryA(path) 
End Function 

Sorry, wenn ich das erklärt für 32-Bit falsch verstanden ... Ich habe keine 32-Version von MS Office mit testen .