OLE und Word in Delphi7

Hallo NG.
Ich habe das folgende Problem:
Ich muss ein Word-Dokument mit Delphi bearbeiten: Alle in dem Dokument vorhandenen InlineShapes müssen in Shapes umgewandelt werden.
Folgender Quellcode funktioniert - jedoch nur für die erste Seite des Dokuments. Auf allen folgenden Seiten bleiben die Shapes unangetastet.

Word := CreateOLEObject(‚Word.Application‘);
TRY
Word.Documents.Open(‚C:\KIM\SonoGebBrief.doc‘, ReadOnly := FALSE);
iDummy := Word.ActiveDocument.InlineShapes.Count;
Container.UpdateObject;

FOR iAnz := 1 TO iDummy DO
BEGIN
TRY
Word.ActiveDocument.InlineShapes.Item(1).ConvertToShape;
EXCEPT
Container.UpdateObject;
END;
END;

Container.UpdateObject;

Der Count auf die InlineShapes bringt mir die korrekte Anzahl zurück, aber beim ersten InlineShape auf der zweiten Seite, läuft die Schleife in die Exeption.
Kann mir einer sagen was ich falsch mache bzw. wie es richtig ist???
Besten Dank schon mal für die Hilfe und - Frohe Weihnachten Euch allen!

Lothar

Hi Lothar,

ich arbeite zwar nicht mit OLEObjecten bei meinen Programmen, aber ich denke du solltest dir die Zeile

Word.ActiveDocument.InlineShapes.Item(1).ConvertToShape;

ansehen. Wenn ich es richtig verstehe möchtest du hier nacheinander die einzelnen Shapes konvertieren. Ich denke du musst die 1 durch iAnz ersetzen. Sprich

Word.ActiveDocument.InlineShapes.Item(iAnz).ConvertToShape;

bei einer 1 versucht das Programm das erste Shape nach der Konvertierung nochmal zu konvertieren. Da der Objecttyp beim zweiten Durchlauf bereits Shape ist kann die Konvertierung nicht mehr durchgeführt werden und es kommt zu einer Exception.

Wie gesagt, ich kann nicht 100% sagen ob es daran liegt, der Logik nach sollte dies aber das Problem sein.

Gruß

Michi

Hallo Michael.

Danke für Deinen Tipp, aber daran liegt es definitiv nicht.
Dieser OLE-Container verhält sich etwas sonderbar - anscheinend konvertiert er die erste Grafik, zählt neu durch (jetzt fällt die schon konvertierte Grafik raus, da sie ja schon nicht mehr InlineShape ist und somit wird die nächste Grafik wieder zur ersten).
Mit .Item(1) durchläuft er wirklich alle Grafiken auf der ersten Seite. Das Programm stoppt erst mit der Konvertierung auf der zweiten Seite (das ist dann meine 23. Grafik in meinem Testdokument).

Danke für den Versuch mir zu helfen! Komm gut nach 2006!

Gruß Lothar

Hallo Lothar,

Möglicherweise funktioniert es, wenn Du die Schleife für iAnz rückwärts zählen lässt (also von iDummy runter bis 1).

Gruß,
Jochen

Danke Jochen.

Ich habe auf meinem Weg zu Lösung wirklich alles mögliche und unmögliche ausprobiert. Ich war schon so weit, dass ich ein Voodoo-Püppchen einbauen wollte :wink:

Das Problem lag an Word. Word ist anscheinend zu langsam für Delphi.
Ich habe ein paar Sleeps eingebaut und schon läuft die Sache.

FOR iAnz := 1 TO iDummy DO
BEGIN
TRY
Word.ActiveDocument.InlineShapes.Item(1).ConvertToShape;
sleep(150); // ohne diese Verzögerung funktioniert es nicht!!!
EXCEPT
inc(iSeite);
Word.Selection.GoTo( What:=wdGoToPage, Name:=iSeite);
END;
END;

Wenn Du noch ein Idee hast (der sleep ist ja nur ein workaround), dann lass es mich bitte wissen.

Danke nochmal und
beste Grüße
Lothar

Hallo,

Ich habe auf meinem Weg zu Lösung wirklich alles mögliche und
unmögliche ausprobiert. Ich war schon so weit, dass ich ein
Voodoo-Püppchen einbauen wollte :wink:

Das kenn’ ich!

Das Problem lag an Word. Word ist anscheinend zu langsam für
Delphi.
Wenn Du noch ein Idee hast (der sleep ist ja nur ein
workaround), dann lass es mich bitte wissen.

Eine Idee, leider keine sehr konkrete:

Vielleicht gibt es beim OLE ja eine Art Rück-Meldung, wann das OLE-Objekt eine Aktion ausgefürht hat bzw. wann es im „idle“-Modus ist. Vielleicht gibt es auch eine Funktion wie object.isIdle() oder so. Wahrscheinlich ist es aber komplizierter…

Wenn Du sowas findest, baust du diese Abfrage in eine Repeat-Schleife. In der Schleife machst du die Abfrage und gibst Windows gelegenheit, Botschaften abzuarbeiten (am einfachsten mit „Application.ProcessMessages“). Das würde ich auch statt des „sleeps“ bevorzugen, mit dem du die Botschaftsbearbeitung ja mitunter zig-mal hintereinander für je 150ms lahmlegst. Du kannst mit „getTickCount“ einen Wert abfragen, der jede ms um eins größer wird. Merk dir den Wert bei Eintritt in die Schleife und frag ihn in der Schleife ab. Wenn der neue Wert um 150 größer ist als der Startwert, sind 150 ms vorbei.

Gruß,

Jochen