Woher weiß ich, dass "ThisWorkbook" ein "Arbeitsbuch" ist?

8

Ich arbeite mit der VBIDE-API und kann nicht davon ausgehen, dass die Host-Anwendung entweder Excel oder eine beliebige Office-Anwendung ist.

Also alles, was ich weiß, ist, dass ich ein VBComponent betrachte, und dass sein Type vbext_ct_document ist.

Im VBE unmittelbaren Bereich kann ich diese Ausgabe erhalten:

%Vor%

Aber das Objekt Sheet1 existiert nur in der Laufzeitumgebung, also wenn ich ein C # Add-In bin, sehe ich es nicht einmal.

Das einzige, was mir nahe kommt, ist über die Eigenschaften Parent und Next der Komponente:

%Vor%

Das bringt mir die Typnamen, nach denen ich suche ... aber auf der falschen Komponente! Und für ThisWorkbook , welches das oberste Dokumentobjekt ist, bekomme ich das Application Objekt als Parent :

%Vor%

Der Ansatz ist potenziell nützlich, aber nur, wenn ich die hostspezifische Logik fest codiere , die weiß, dass die Komponente "Parent" vom Typ "Application" ist. ist eine Workbook -Instanz, wenn die Host-Anwendung Excel ist ... und es gibt keine Garantie, dass andere Dokument-Module in anderen Hosts sogar diese "Parent" -Eigenschaft haben, also bin ich ziemlich ratlos.

Ich bin offen für buchstäblich alles - von p / invoke Calls und Low-Level COM "Reflection" Magie (die ITypeInfo Art von Magie) zu ... zu ... I weiß nicht - unsafe code mit funky Zeigern, die // here be dragons comments - alle Leads benötigen, die möglicherweise zu einer funktionierenden Lösung führen können, ist willkommen.

AFAIK das VBE-Add-In lebt im selben Prozess wie der Host, also irgendwo gibt es einen Zeiger auf ThisWorkbook und Sheet1 und was auch immer der andere Dokumenttyp VBComponent in der VBA Projekt.

%Vor%

Ich denke, ich muss den Zeiger irgendwie ergreifen und ich werde da sein, wo ich sein muss.

    
Mathieu Guindon 06.05.2016, 18:19
quelle

1 Antwort

7

Leider sind die Werte / Objekte der vbComponent-Properties-Auflistung nur eine Reflektion der CoClass-Instanzwerte, sodass sie nicht über alle VBA-Hosts hinweg zuverlässig sind. Beispielsweise können Sie wissen nicht, dass die Parent -Eigenschaft in der Properties-Auflistung vorhanden ist.

Wenn ein Host Dokumenttypkomponenten unterstützt, muss der Host die GUID der Schnittstelle definieren, die das Dokument unterstützt. Der Host ist normalerweise auch für das Erstellen / Entfernen des eigentlichen Dokuments verantwortlich, so wie nur das Excel-Objektmodell ein Arbeitsblatt zu einem Arbeitsblatt hinzufügen kann, während dies bei VBIDE nicht möglich ist.

Sie haben über Arbeitsmappen und Arbeitsblätter gesprochen, also werde ich beide hinzufügen ....

Leider verbirgt VBIDE einige Details über dokumentartige Komponenten, und beim Exportieren eines Moduls werden diese Details bewusst weggelassen, und sogar das exportierte dokumentartige Modul wird in Klassenmodulen konvertiert, wie dies Worksheet genannt Sheet1 , damit nicht als dokumentartiges Modul erneut importiert werden kann:

%Vor%

Vergleichen Sie den obigen Text mit dem Dokument-Modul-Text, der tatsächlich (in komprimiertem Format) im Modul Sheet1 gespeichert ist:

%Vor%

Beachten Sie die 3 zusätzlichen Attribute, die im realen -Modul-Text vorhanden sind:

%Vor%

Die GUID 0 {00020820-0000-0000-C000-000000000046} ist eine genaue Übereinstimmung für CoClass Worksheet , gemäß OleViewer:

%Vor%

Das gleiche Verhalten tritt bei dem Arbeitsmappenmodul auf. Hier ist der von VBIDE exportierte Text:

%Vor%

Und der rohe Text aus dem IStream in der VBA-Binärdatei:

%Vor%

Diesmal ist die GUID 0{00020819-0000-0000-C000-000000000046} erwartungsgemäß eine Arbeitsmappen-CoClass:

%Vor%

Das Obige ist alles gut zu wissen, aber es löst Ihr Problem nicht, es sei denn, Sie können einen Griff zu den IStreams im Speicher für die Komponenten bekommen, was ich nicht für möglich halte. Wenn Sie mit dem Laden der Details aus der letzten gespeicherten Version des Host-Dokuments auskommen, können Sie die Details aus dem zugrunde liegenden Dokument laden, aber ich glaube nicht, dass Sie das wollen, und könnte es am Ende Host-spezifisch sein (bedenken Sie, wie Access VBA in einer Tabelle speichert.)

Das VBIDE macht jedoch einen Hinweis auf die CoClass. Die Eigenschaftensammlung für die vbComponent gibt die genaue Anzahl von Eigenschaften zurück, die in der CoClass vorhanden sind. Wenn Sie die Namen, Parameter und Typen dieser Eigenschaften überprüfen, werden sie genau stimmen die Mitglieder der entsprechenden CoClass bis in die Reihenfolge ab, in der sie in der CoClass-Definition vorkommen.

Zum Beispiel sind die ersten 10 Eigenschaften eines Worksheets vbComponent:

%Vor%

Und die entsprechenden propget (und propput ) Einträge aus dem dispinterface _Worksheet in CoClass Worksheet (mit entfernten Methoden):

%Vor%

Wenn Sie über die CoClasses der Host-Typbibliothek nachdenken und die Eigenschaft Namen hashen können (vielleicht verwenden Sie einfach die Propget-Namen), können Sie den Hash mit den Namen der VBIDE-Komponenten.Properties vergleichen Sammlung.

Es ist eine runde Sache, den Typ zu bekommen, aber ohne Zugang zum IStream denke ich wird es dein einziger Weg sein.

    
ThunderFrame 07.05.2016, 06:27
quelle

Tags und Links