2017-02-15 14 views
1

私の質問は、特定のWord文書の著者名を取得する方法です。Word文書、VBAの作成者

My機能は次のとおりです。

Public Function GetFileOwner(pFile As String) As String 

GetFileOwner = pFile.Owner 

End Function 

私はすでに.BuiltInDocmementProperties.を試してみましたが、これはあまりにも遅かった、てここに約100の文書を取得...

もShell.Application機能がありませんこれはフォルダ内のすべてのファイルでのみ機能するため、私にとってはうまく動作しますが、特定のファイル用に必要です。

誰かが他のより高速な解決法を知っていますか?そして、PDF文書のための方法もありますか?

+0

既に試した '.BuiltInDocmementProperties'と' Shell.Application'のコードを出力してください。 PDFの回答も取得したい場合は、タイトルに追加することをお勧めします。両方ともタグに追加してください。 – omegastripes

答えて

0

あなたは.NETで非常に簡単にこれを行うことができますので、私は管理されていない輸出の小さなDLLを書いた:

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; 
     } 

    } 
} 

RGiesecke.DllExportでいくつかの好奇心のエラーを回避するために、必要以上にあるやや冗長なコード.FirstOrDefault()または.GetEntry()を使用した場合、

は このDLLは順番に次のようにVBAから呼び出すことができ

:私は32ビットのために間違って宣言し得た場合

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 

申し訳ありませんが...私はしてテストするためのMS Officeの任意の32バージョンを持っていません。

関連する問題