2009-07-16 38 views
12

Tôi đang cố gắng thêm thuộc tính tùy chỉnh vào sổ làm việc mà tôi đã tạo theo chương trình. Tôi có một phương thức để nhận và thiết lập các thuộc tính, nhưng vấn đề là sổ làm việc trả về null cho thuộc tính CustomDocumentProperties. Tôi không thể tìm ra cách khởi tạo thuộc tính này để tôi có thể thêm và lấy các thuộc tính từ sổ làm việc. Microsoft.Office.Core.DocumentProperties là một giao diện, vì vậy tôi không thể đi và làm như sauTruy cập các thuộc tính tài liệu tùy chỉnh Excel theo lập trình

if(workbook.CustomDocumentProperties == null) 
    workbook.CustomDocumentProperties = new DocumentProperties; 

Đây là mã tôi phải có được và thiết lập các thuộc tính:

 private object GetDocumentProperty(string propertyName, MsoDocProperties type) 
    { 
     object returnVal = null; 

     Microsoft.Office.Core.DocumentProperties properties; 
     properties = (Microsoft.Office.Core.DocumentProperties)workBk.CustomDocumentProperties; 

     foreach (Microsoft.Office.Core.DocumentProperty property in properties) 
     { 
      if (property.Name == propertyName && property.Type == type) 
      { 
       returnVal = property.Value; 
      } 
      DisposeComObject(property); 
     } 

     DisposeComObject(properties); 

     return returnVal; 
    } 

    protected void SetDocumentProperty(string propertyName, string propertyValue) 
    { 
     DocumentProperties properties; 
     properties = workBk.CustomDocumentProperties as DocumentProperties; 

     bool propertyExists = false; 
     foreach (DocumentProperty prop in properties) 
     { 
      if (prop.Name == propertyName) 
      { 
       prop.Value = propertyValue; 
       propertyExists = true; 
      } 
      DisposeComObject(prop); 

      if(propertyExists) break; 
     } 

     if (!propertyExists) 
     { 
      properties.Add(propertyName, false, MsoDocProperties.msoPropertyTypeString, propertyValue, Type.Missing); 
     } 

     DisposeComObject(propertyExists); 

    } 

Dòng tính = workBk.CustomDocumentProperties dưới dạng DocumentProperties; luôn đặt thuộc tính thành rỗng.

này được sử dụng Microsoft.Office.Core v12.0.0.0 và Microsoft.Office.Interop.Excell v12.0.0.0 (Office 2007)

Trả lời

10

Tôi nhìn mã riêng của tôi và có thể thấy rằng tôi truy cập các thuộc tính sử dụng kết buộc muộn. Tôi không thể nhớ tại sao, nhưng tôi sẽ đăng một số mã trong trường hợp nó giúp.

object properties = workBk.GetType().InvokeMember("CustomDocumentProperties", BindingFlags.Default | BindingFlags.GetProperty, null, workBk, null); 

object property = properties.GetType().InvokeMember("Item", BindingFlags.Default | BindingFlags.GetProperty, null, properties, new object[] { propertyIndex }); 

object propertyValue = property.GetType().InvokeMember("Value", BindingFlags.Default | BindingFlags.GetProperty, null, propertyWrapper.Object, null); 

EDIT: ah, bây giờ tôi nhớ why. :-)

CHỈNH SỬA 2: Trả lời của Jimbojones - để sử dụng từ khóa động - là một giải pháp tốt hơn (nếu bạn coi trọng tính dễ sử dụng trên chi phí hiệu suất khi sử dụng dynamic).

+0

Chính xác liên kết tôi tìm thấy và tôi đã đăng mã của tôi khi bạn đăng bài này. +1 và được chấp nhận cho bạn :-) –

+0

Cập nhật để liên kết về "lý do": https://support.microsoft.com/en-us/kb/303296 –

7

Tôi đã tìm thấy giải pháp here.

Đây là mã tôi đã kết thúc với:

public void SetDocumentProperty(string propertyName, string propertyValue) 
    { 
     object oDocCustomProps = workBk.CustomDocumentProperties; 
     Type typeDocCustomProps = oDocCustomProps.GetType(); 

     object[] oArgs = {propertyName,false, 
       MsoDocProperties.msoPropertyTypeString, 
       propertyValue}; 

     typeDocCustomProps.InvokeMember("Add", BindingFlags.Default | 
            BindingFlags.InvokeMethod, null, 
            oDocCustomProps, oArgs); 

    } 

    private object GetDocumentProperty(string propertyName, MsoDocProperties type) 
    { 
     object returnVal = null; 

     object oDocCustomProps = workBk.CustomDocumentProperties; 
     Type typeDocCustomProps = oDocCustomProps.GetType(); 


     object returned = typeDocCustomProps.InvokeMember("Item", 
            BindingFlags.Default | 
            BindingFlags.GetProperty, null, 
            oDocCustomProps, new object[] { propertyName }); 

     Type typeDocAuthorProp = returned.GetType(); 
     returnVal = typeDocAuthorProp.InvokeMember("Value", 
            BindingFlags.Default | 
            BindingFlags.GetProperty, 
            null, returned, 
            new object[] { }).ToString(); 

     return returnVal; 
    } 

Một số xử lý ngoại lệ là cần thiết để bàn nếu tài sản doesnt tồn tại khi lấy

3

Cuối câu trả lời cho câu hỏi này, nhưng tôi đã làm việc ra một đơn giản hơn phương pháp để thêm DocumentProperties tùy chỉnh có thể được sử dụng cho ai đó trong tương lai.

Vấn đề của tôi là gọi phương thức Add() với kiểu Hệ thống được cung cấp bởi System.String.GetType() đã kích hoạt một COMException: Loại không khớp. Đề cập đến các liên kết trong câu trả lời trước thì rõ ràng rằng phương pháp này hy vọng một loại văn phòng cụ thể, vì vậy mã mà kết thúc làm việc đối với tôi là:

var custProps = (Office.DocumentProperties)this.CustomDocumentProperties; 
custProps.Add("AProperty", false, MsoDocProperties.msoPropertyTypeString, "AStringProperty"); 

Bởi vì đó là một văn phòng CustomDocumentProperty sẽ thêm thuộc tính tùy chỉnh mà không gặp khó khăn , nhưng nếu bạn cần kiểm tra sự tồn tại hoặc xác nhận giá trị khi CustomDocumentProperty có thể không tồn tại, bạn sẽ phải nắm bắt một System.ArgumentException.

EDIT

Như đã chỉ ra trong bình luận của Oliver Bock, đây là một Office 2007 và chỉ chiếm giải pháp, như xa như tôi biết.

+1

Tôi tìm thấy (với Excel 2000) mà tôi không thể truyền bảng tính.CustomDocumentProperties tới Office.DocumentProperties. Tuy nhiên, mã phản chiếu trong các câu trả lời khác không hoạt động. –

+0

À, vâng - Tôi nên chú ý (và đã làm như vậy bây giờ) mà tôi tin rằng đây là một tính năng Office 2007 và chỉ lên (mặc dù nó có thể hoạt động vào năm 2003 - tôi không còn quyền truy cập vào đó để kiểm tra). Trong phòng thủ của tôi, đó là những gì các poster ban đầu đã được sử dụng. – cori

12

Nếu bạn đang nhắm mục tiêu .NET 4.0, bạn có thể sử dụng từ khóa dynamic cho ràng buộc muộn

Document doc = GetActiveDocument(); 
if (doc != null) 
{ 
    dynamic properties = doc.CustomDocumentProperties; 
    foreach (dynamic p in properties) 
    { 
     Console.WriteLine(p.Name + " " + p.Value); 
    } 
} 
Các vấn đề liên quan