itsource

프로그래밍 방식으로 Excel 사용자 정의 문서 속성 액세스

mycopycode 2023. 8. 10. 18:48
반응형

프로그래밍 방식으로 Excel 사용자 정의 문서 속성 액세스

프로그래밍 방식으로 만든 워크북에 사용자 지정 속성을 추가하려고 합니다.속성을 가져오고 설정할 수 있는 방법이 있지만 문제는 워크북에서 사용자 지정 문서 속성에 대해 null을 반환하고 있다는 것입니다.워크북에서 속성을 추가하고 검색할 수 있도록 이 속성을 초기화하는 방법을 알 수 없습니다.마이크로소프트.사무실.Core.DocumentProperties는 인터페이스이므로 다음 작업을 수행할 수 없습니다.

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

다음은 내가 가져와 속성을 설정해야 하는 코드입니다.

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

    }

선 속성 = workBk.사용자 정의 문서 등록 정보를 문서 등록 정보로 지정합니다. 항상 속성을 null로 설정합니다.

이것은 Microsoft를 사용하는 것입니다.사무실.Core v12.0.0.0 및 마이크로소프트.사무실.인터럽트.Excellent v12.0.0.0(Office 2007)

만약 당신이 타겟이 된다면요.NET 4.0을 사용할 수 있습니다.dynamic늦게 바인딩하는 키워드

 Document doc = GetActiveDocument();
 if ( doc != null )
 {
     dynamic properties = doc.CustomDocumentProperties;
     foreach (dynamic p in properties)
     {
         Console.WriteLine( p.Name + " " + p.Value);
     }
 }

제 코드를 보니 늦은 바인딩을 사용하여 속성에 액세스하는 것을 확인할 수 있습니다.이유는 기억이 안 나지만, 도움이 될 경우를 대비해 코드를 올리겠습니다.

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 2: 동적 키워드를 사용하는 Jimbojones의 답변이 더 나은 솔루션입니다(사용의 성능 오버헤드보다 사용 편의성을 중요시한다면).dynamic).

여기서 해결책을 찾았습니다.

여기 제가 만든 코드가 있습니다.

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

검색 시 속성이 존재하지 않는 경우 일부 예외 처리가 필요합니다.

이 질문에 대한 답변이 늦었지만, 나중에 누군가에게 유용할 수 있는 사용자 지정 문서 속성을 추가하는 더 간단한 방법을 생각해냈습니다.

시스템에서 제공하는 시스템 유형으로 Add() 메서드를 호출하는 것이 문제였습니다.끈.GetType()이 COME 예외를 트리거했습니다.형식이 일치하지 않습니다.이전 답변의 링크를 참조하면, 이 방법은 Office별 유형을 예상하는 것이 분명하므로, 제가 사용할 수 있게 된 코드는 다음과 같습니다.

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

사용자 지정 문서 속성 사무소에서는 사용자 지정 속성을 쉽게 추가할 수 있지만, 사용자 지정 문서 속성이 존재하지 않을 때 존재 여부를 확인하거나 값을 확인해야 하는 경우 시스템을 검색해야 합니다.논쟁예외.

편집

Oliver Bock의 논평에서 지적한 바와 같이, 이것은 Office 2007이자 유일한 솔루션입니다.

언급URL : https://stackoverflow.com/questions/1137763/accessing-excel-custom-document-properties-programmatically

반응형