![]() |
OpenOffice und OLE, wie ?
ich hab folgendes probiert, häng jetzt aber an einer Access Violation und komm einfach nicht damit klar, weil mir nicht klar ist was falsch ist :(
Delphi-Quellcode:
ich bin nicht sicher ob der Pfad so richtig angegeben ist . Der Fehler kommt bei der Belegung von Doc, das mag er nicht, vielleicht bzw. wahrscheinlich sind einfach die Parameter falsch aber ich blick momentan nicht welcher der ganzen :(
procedure TForm1.Button1Click(Sender: TObject);
var oV_Word, stardesktop, Doc, x : OleVariant; feldname, feldinhalt, datei : String; begin feldname := 'zuersetzen'; feldinhalt := 'neuer Inhalt'; datei := 'file:///C:/test.sxw'; try oV_Word := CreateOleObject('com.sun.star.ServiceManager'); StarDesktop := ov_word.createInstance('com.sun.star.frame.desktop'); Doc := StarDesktop.LoadComponentFromurl(datei,'_blank',0,x); except showmessage('Geht noch nicht so richtig !'); end; end; als vorlage diente mir dies ![]() |
Re: OpenOffice und OLE, wie ?
Probier's mal mit
Delphi-Quellcode:
Du hast das x als nicht initialisierte Variable übergeben, und dann
Doc := StarDesktop.LoadComponentFromurl(datei,'_blank',0,nil);
noch vom Typ OleVariant. Ich weiss nicht, ob er dieses Argument in der Weise verträgt. Wenn Du explizit nichts übergibst dürfte er wenigstens nicht drüber stolpern. |
hmm,
joo, jetzt wo du es sagst, die OleVariant sind eigentlich völliger Unsinn, sollten normale Variants sein.
|
Re: OpenOffice und OLE, wie ?
OßpenOffice ist einfach klasse, frisst die alten Wordvorlagen und ersetzt die Bookmarks viel schneller als Word selbst :) Warum etwas für hunderte von Euro kaufen wenn es mit OpenSource viel schneller geht und dazu noch kostenlos ist !?
PS: Habt ihr schon die tolle Anzeige von Word gesehen => 1223 Zeichen. ( ein ungefährer Wert) :D :D Was nun 1223 Zeichen oder nicht ? :D :D |
Re: OpenOffice und OLE, wie ?
Hi JoelH !
Ich wäre Dir echt dankbar wenn du noch mal das Coding um eine Bookmark in OpenOffice zu ersetzen posten könntest! Ich bekomme bei mir immer noch ne AccessViolation :cry: Thx! |
hmm,
joo, ich hab die Klasse noch ein wenig erweitert, ich poste sie morgen nochmal hab den Kram auf der Arbeit und da bin ich schon raus :)
meinst du bei diesem Posting ? => ![]() Welche OO Version benutzt du denn ? Ich hab es nur mit 1.1rc getestet. Kompiliert mit D4 , ich denke mit höher muss man noch Variant einbinden aber dass ist dir sicher schon aufgefallen. |
hmm,
so , hier mein neuer Code :
Delphi-Quellcode:
zu beachten ist dass man den Doc Type noch selbst abfragen muss und sichern muss dass man nicht in Writerdocs auf Zellen zugreifen will sondern auf Bookmarks und in Calcsheets umgekehrt agiert.
unit OO_Handling;
// Eine kleine Klasse zum einfachsten Handling von OpenOffice Dokumenten // Sollte noch um viele Funktionen erweiterbar sein // hab mal erst nur die Wichtigsten eingebaut // Diese Funktionen funktionieren auch mit Word .dot Files, // Das ersetzen geht sogar mit OpenOffice schneller als mit Word selbst. interface uses Windows, SysUtils, comobj, Classes; type TOLE_OpenOffice = class(TObject) private p_Doc_Type : String; // Da OpenOffice Pfadangaben im Unixstyle haben will werden Backslashes umgewandelt function ToOOPfad(Pfad:String):String; procedure Setze_Doc_Type(s:string); protected // Das OLE-Objekt, die Desktopinstanz und das Dokument selbst. Service, Desktop, Document : Variant; public // Erstellt ein OLE Objekt; function Connect: boolean; // Oeffnet eine neues Dokument function Open:boolean;OVERLOAD; // Laden eines vorhandenen Dokuments function Open(datei:string):boolean;OVERLOAD; // Ein Bookmarkfeld ersetzen ( Nicht Case Sensitiv) function ErsetzeBookmark(name,inhalt:String):boolean; // Liste von allen Bookmarks als Stringlist; function HoleBookmarks:TStringlist; function HoleZellinhalt(sheet,zelle:String):String;OVERLOAD; function HoleZellinhalt(sheet:string;xpos,ypos:integer):String;OVERLOAD; function SchreibeZellinhalt(sheet,zelle,inhalt:String):boolean;OVERLOAD; function SchreibeZellinhalt(sheet:string;xpos,ypos:integer;inhalt:String):boolean;OVERLOAD; // Destruktor destructor Destroy;OVERRIDE; property Doc_Type:String read p_Doc_Type write Setze_Doc_Type; end; implementation destructor TOLE_OpenOffice.Destroy; begin Service := Unassigned; inherited Destroy; end; function TOLE_OpenOffice.Connect:boolean; var rueckgabe : boolean; begin try Service := CreateOleObject('com.sun.star.ServiceManager'); Desktop := Service.createInstance('com.sun.star.frame.Desktop'); rueckgabe := true; except rueckgabe := false; end; result := rueckgabe; end; function TOLE_OpenOffice.Open:boolean; var rueckgabe : boolean; begin try Document := Desktop.LoadComponentFromURL( 'private:factory/swriter', '_blank', 0, VarArrayCreate([0, - 1], varVariant)); rueckgabe := true; setze_Doc_Type('dummy'); except rueckgabe := false; end; result := rueckgabe; end; procedure TOLE_OpenOffice.Setze_Doc_Type(s:string); var rueckgabe:String; begin rueckgabe := ''; if (Document.SupportsService('com.sun.star.sheet.SpreadsheetDocument')) then rueckgabe := 'scalc'; if (Document.SupportsService('com.sun.star.text.TextDocument')) then rueckgabe := 'swriter'; if (Document.SupportsService('com.sun.star.drawing.DrawingDocument')) then rueckgabe := 'sdraw'; if (Document.SupportsService('com.sun.star.formula.FormulaProperties')) then rueckgabe := 'smath'; if (rueckgabe = '') then rueckgabe := 'unknown'; p_Doc_Type:= rueckgabe; // result:= rueckgabe; end; function TOLE_OpenOffice.Open(datei:string):boolean; var rueckgabe : boolean; begin datei := ToOOPfad(datei); try Document := Desktop.LoadComponentFromURL( datei, '_blank', 0, VarArrayCreate([0, - 1], varVariant)); rueckgabe := true; setze_Doc_Type('dummy'); except rueckgabe := false; end; result := rueckgabe; end; function TOLE_OpenOffice.ToOOPfad(Pfad:String):String; var rueckgabe : string; i : integer; begin rueckgabe := 'file:///'; while (POS('\',pfad)>0) do begin i := POS('\',pfad); delete(pfad,i,1); Insert('/',pfad,i); end; rueckgabe := rueckgabe + pfad; result := rueckgabe; end; function TOLE_OpenOffice.ErsetzeBookmark(name,inhalt:String):boolean; var objtext, tc, bm, li : Variant; i : integer; rueckgabe : boolean; begin rueckgabe := false; try objText := Document.getText; tc := objText.createTextcursor; li := Document.Bookmarks.getElementNames; for i := VarArrayLowBound(li,1) to VarArrayHighBound(li,1) do begin if (uppercase(li[i]) = uppercase(name)) then begin bm := Document.Bookmarks.getbyName(li[i]); tc := Document.Text.createTextCursorByRange(bm.Anchor); tc.string := inhalt; rueckgabe := true; end; end; except rueckgabe := false; end; result := rueckgabe; end; function TOLE_OpenOffice.HoleBookmarks:TStringlist; var liste : TStringlist; i : integer; li : Variant; begin liste := TStringlist.create; liste.Clear; li := Document.Bookmarks.getElementNames; for i := VarArrayLowBound(li,1) to VarArrayHighBound(li,1) do begin liste.add(li[i]); end; result := liste; end; function TOLE_OpenOffice.HoleZellinhalt(sheet,zelle:String):String; var sh,bm : Variant; begin sh := Document.Sheets.getByName(sheet); bm := sh.getCellRangebyName(zelle); result := bm.getString; end; function TOLE_OpenOffice.HoleZellinhalt(sheet:String;xpos,ypos:integer):String; var sh,bm : Variant; begin sh := Document.Sheets.getByName(sheet); bm := sh.getCellbyPosition(xpos,ypos); result := bm.getString; end; function TOLE_OpenOffice.SchreibeZellinhalt(sheet,zelle,inhalt:String):boolean; var sh,bm,tc : Variant; begin sh := Document.Sheets.getByName(sheet); bm := sh.getCellRangebyName(zelle); bm.setString(inhalt); end; function TOLE_OpenOffice.SchreibeZellinhalt(sheet:String;xpos,ypos:integer;inhalt:String):boolean; var sh,bm,tc : Variant; begin sh := Document.Sheets.getByName(sheet); bm := sh.getCellbyPosition(xpos,ypos); bm.setString(inhalt); end; end. To be continued.... |
Re: OpenOffice und OLE, wie ?
Hey Joel!
Danke für das Coding, hatte es mittlerweile schon selbst rausgefunden...aber du hast natürlich noch ein paar nette Sachen drin, die ich noch nicht wusste! Was ich aber unbedingt noch bräuchte, wären so grundlegende Sachen, wie Dokument speichern oder schliessen ! Hast du einen Plan wie man so was macht?!? Btw, gibt es mittlerweile mal ne vernünftige Doku wo die ganze API mit allen Funktionen beschrieben ist?!? Nachmals Danke für dein Coding! Ach so ich hab auch die 1.1 OO Version. |
Re: OpenOffice und OLE, wie ?
ich hab bisher nur das gefunden
![]() ist nichts tolles aber immerhin ist glaub ich alles drin was es so gibt. |
Re: OpenOffice und OLE, wie ?
jo auf die seite bin ich auch schon gestossen, aber ich finde da einfach nichts, wie ich so dummes dokument speichern und schliessen kann ! (vielleicht bin ich auch zu blind... ) :wink:
ich will nämlich das ganze nur im hintergrund machen - sprich vorlage x auf machen - bookmarks mit werten aus db ersetzen - dokument speichern - drucken - und schliessen! und das halt so das es der benutzer nicht merkt :wink: wie drucken geht, weiss ich schon, aber speichern und schliessen - kein plan :?: |
Re: OpenOffice und OLE, wie ?
Hallo!
Das Speichern eines Dokumentes mache ich immer mit der folgenden Methode:
Code:
procedure TSampleCode.SaveAs (name : string);
var saveparams : variant; begin SaveParams := VarArrayCreate([0, -1], varVariant); Document.StoreAsURL ('file:///'+name,saveparams); end; Das Schließen eines Dokumentes habe ich bisher noch nicht ausprobiert. Der Aufruf müßte aber recht ähnlich aussehen. MfG Daniel |
Re: OpenOffice und OLE, wie ?
Hallo,
Das Dokument schließen kann man mit: Document.close(); Und Staroffice lässt sich bei mir mit: Desktop.terminate; Jetzt habe ich nur noch das Problem wie ich auf Formfields zugreifen kann. Also den Inhalt von Textfeldern und Checkboxen lesen und setzen kann. Hat da jemand erfahrung? Ich komme irgendwie mit der Api Doku von Openoffice garnicht zurecht. Irgendwie ist immer alles querverlinkt und nicht besonders übersichtlich. gruß thaman |
Re: OpenOffice und OLE, wie ?
okay, das Laden geht ja jetzt ganz gut, aber wie minimiere ich OpenOffice direkt nach Laden des Dokuments, damit das Ding mir nicht den Bildschirm zuknallt, wenn ich mit dem eigenen Programm arbeiten will, das nur auf eine Tabelle von OO zugreift?
|
Re: OpenOffice und OLE, wie ?
Zitat:
Hallo, genau das gleiche Problem habe ich auch, ich kann einfach nicht auf die Feld-Inhalte zugreifen. mit
Code:
finde ich zwar die Felder anhand ihres Namens, aber kann deren Inhalt nicht ändern.
...
enum := Document.getTextFields.createEnumeration; while enum.hasMoreElements do begin if field.TextFieldMaster.Name = 'Name' then begin InputField := Document.createInstance('com.sun.star.text.TextField.Input'); InputField.Content := 'Inhalt'; end; end; ... Vielen Dank im Voraus! Grüße, Chris |
Re: hmm,
Zitat:
eines Automatisierungsobjekts oder Parameter für ein Automatisierungsmethode speichern möchtest. Der Typ OleVariant bezeichnet eine Variante, die ausschließlich COM-kompatible Typen enthält. Wenn ein Variant-Wert einem OleVariant-Wert zugewiesen wird, werden alle nichtkompatiblen Typen in ihre kompatiblen Entsprechungen umgewandelt. Wenn z.B. eine Variante, die einen AnsiString-Wert enthält, einem OleVariant-Wert zugewiesen wird, wird AnsiString in den Typ WideString konvertiert. Zitat:
![]() |
Re: OpenOffice und OLE, wie ?
Hallo nochmal,
habe das Problem leider immernoch nicht gelöst. Kann mir denn keiner von euch helfen :?: :cry: Grüße, Chris |
Re: OpenOffice und OLE, wie ?
Zitat:
ich habe nun in etwa das selbe Problem und konnte bisher im Netz so überhaupt keinen Lösungsansatz finden. Die Open Office API ist weiterhin eine totale Katastrophe. Den einzigen brauchbaren Lösungsansatz habe ich hier gefunden. Allerdings meckert er bei mir hier schon rum. Da mir unklar ist, welcher Datentyp enum, field und inputfield ist, habe ich ihn standardmäßig wie das meinste OO-Zeugs auf Variant gesetzt. An der Stelle "field" allerdings meldet sich auch schon der Compiler und sagt mir, Variante referenziert kein Automatisierungsobjekt. Was ist da wieder verkehrt? Kann jemand weiter helfen? Ist es jemanden schon gelungen, diese Placeholder zu manipulieren? |
Re: OpenOffice und OLE, wie ?
Zitat:
Ohne dieses Tool braucht du gar nicht anfangen. Die Variable "field" wird in deinem Sourcecode nicht initialisiert. Dann ist es logisch, dass zur Laufzeit die Exception "Variante referenziert kein Automatisierungsobjekt" kommt. Nur wenn eine Variantvariable ein IDispatch-Interface enthält, darf man mit dem Punkt-Operator eine Methode aufrufen oder auf ein Property zugreifen. Zur Verdeutlichung folgendes Beispiel:
Delphi-Quellcode:
Das heisst also, dass man zum Debuggen immer schauen sollte, welchen VarType eine Variantvariable hat.
var
test:OleVariant; begin test := ..... // irgendwas if VarType(test) <> varDispatch then ShowMessage('kein Dispatch-Interface vorhanden!') else begin test.MethodeAufrufen; test.Left := test.Left + 1; // Property lesen/schreiben end; |
Re: OpenOffice und OLE, wie ?
Nein, diesen OleViewer habe ich noch nicht installiert. Anhand der COM-Seite werde ich nicht wirklich schlau :( und es entzieht sich mir, welchen Nutzen der Viewer dann für mein Problem hat.
Stimmt, "field" ist nun initialisiert und ich kann zumindest erkennen, das Input-Felder im Dokument sind. Nach wie vor bleibt das Problem, diesen Feldern Test zu spendieren bzw. ganz zu löschen, das Problem, was laut Google sehr viele haben und noch niemand lösen konnte. |
Re: OpenOffice und OLE, wie ?
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo LokutusvB,
ich hatte das gleiche Problem und gebe Dir Recht, die Schnittstelle ist sehr umständlich. Nach langem Suchen im Internet habe ich folgendes gefunden: OpenOfficeDelphi_OOo_v12en.zip Anbei übersende ich noch einen Codeschnipsel, der zeigt, wie ich das ganze benutze: demo-codefragment.zip Anmerkung: In der Datei OOoTools.pas habe ich die Varianten-Variable "disp" gegenüber des Orginals global zur Verfügung gestellt; sonst habe ich, glaube ich, nichts geändert. Ich hoffe damit ist Dir geholfen. Mfg Markus |
Re: OpenOffice und OLE, wie ?
Schade, das kenne ich leider schon. So grundlege Sachen sind mir klar, wie Öffnen, Texte bei Textmarken einfügen, Dokument speichern und ein wenig Scalc. Was jedoch so überhaupt nicht klar ist, ist wie man Platzhalter manipuliert, z.B. mit Text füllt oder ganz löscht.
Ich gehe mal davon aus, das
Delphi-Quellcode:
Das ist so in etwa das Einzige, was man im netz finden kann. Wobei das nach meinem Verständnis auch nicht gehen kann, weil jeglicher Zusammenhang zwischen INputField und field fehlt. Oder geht das trotzdem irgendwie so?
enum := Document.getTextFields.createEnumeration;
while enum.hasMoreElements do begin field := enum.nextElement; if field.TextFieldMaster.Name = 'Name' then begin InputField := Document.createInstance('com.sun.star.text.TextField.Input'); // Löschen oder Text setzten end; end; |
Re: OpenOffice und OLE, wie ?
Liste der Anhänge anzeigen (Anzahl: 3)
Zitat:
Ich habe Open Office nicht installiert, deshalb zeige ich die Vorgehensweise mit Microsoft Word. 1.) OleView starten und links im Baum das Item "Type Libraries" aufklappen. Im 1. Screenshot sieht man, dass ich "Microsoft Word 11.0 Object Library" ausgewählt habe. Du wählst natürlich irgend etwas mit "Open Office" aus. 2.) Doppelklick darauf öffnet ein neues Fenster (2. Screenshot) Unter "Interfaces" sieht man die ganzen Schnittstellen. 3.) auch bei WinWord gibt es ein Interface "IField" Im 3. Screenshot sieht man rechts die Methoden dazu. Unter Anderem gibt es zweimal die Methode "Data" (Propget und Propput sagt aus, dass die Methoden an ein Property angebunden sind ) In diesem Fall (WinWord) könnte man also schreiben:
Delphi-Quellcode:
Mir hat natürlich niemand gesagt, dass das Property Data für den Inhalt des Feldes steht.
field.Data := 'der neue Inhalt';
Aber anhand des Namens erscheint das doch ziemlich logisch. Jetzt musst du nur noch das neue Wissen auf Open Office übertragen. |
Re: OpenOffice und OLE, wie ?
Ich habe den OLE/COM Object Viewer aus dem Resource Kid 2000 installiert und gestartet. IN den Type Libraries ist alles Mögliche drinn, von A bis Z, jedes noch so glitzekleine installierte Programm, allerdings kein Open Office. Dieser Viewer hat leider keine Such-Funktion. Ist nun mein Open Office fehlerhaft installiert oder was ist hier nun wieder los?
|
Re: OpenOffice und OLE, wie ?
Ich bin nun auch ohne diesen für OO anscheinend nicht funktionierenden Viewer ein Stückchen weiter gekommen. Meine 2 Hauptprobleme sind zum einen die für mich recht unverständliche
![]() Durch folgenden Quelltext konnte ich zumindest schon winzig kleine Teilerfolge ermitteln:
Delphi-Quellcode:
So konnte ich zumindest ersteinmal herausfinden, daß die Platzhalter (Feldtyp->Platzhalter, Format->Text). nicht vom Typ Input sind, wie bisher von mir angenommen. Nur von welchem Typ sind sie dann?
function TOLE_OpenOffice.EntfPlatzhalter(platzhalter: String): Boolean;
var enum, field, InputField: Variant; begin enum := Document.getTextFields.createEnumeration; while enum.hasMoreElements do begin field := enum.nextElement; // if VarType(field) <> varDispatch then ShowMessage('kein Dispatch-Interface vorhanden!'); if field.supportsService('com.sun.star.text.TextField.Input') then begin ShowMessage('Input'); ShowMessage(field.getPropertyValue('Hint')); ShowMessage(field.getPropertyValue('Content')); field.setPropertyValue('Content', 'Test-Content'); Document.TextFields.refresh; end; if field.supportsService('com.sun.star.text.TextField.User') then begin ShowMessage('User'); end; if field.supportsService('com.sun.star.text.TextField.InputUser') then begin ShowMessage('InputUser'); end; end; end; Daraufhin habe ich ein Benutzerfeld vom Typ Text angelegt, und siehe da, es handelt sich um ein User-Feld. Daraufhin habe ich mich in der API zu User durchgeklickt, in der Hoffnung hier die Methoden zur Bearbeitung zu finden, aber Pustekucken, da stehen nur die Eigenschaften drinn. Entweder ist es jetzt schon zu spät, um klare Gedanken zu fassen oder aber die Open Office API ist die Schlimmste, mit der ich bisher zu tun hatte. Kann jemand bei einem der beiden Probleme weiter helfen (also Methodensuche oder aber Felder und ihre bezeichnung in der API) oder sollte ich mich damit lieber an ein OO-Forum wenden? |
Re: OpenOffice und OLE, wie ?
Um das Ganze abzuschließen, mit folgendem Code kann man einfach den Content des Feldes (Funktionen -> Eingabefeld) ändern:
Delphi-Quellcode:
function EditInput(name, inhalt: String): Boolean;
var enum, field: Variant; begin Result := False; enum := Document.getTextFields.createEnumeration; while enum.hasMoreElements do begin field := enum.nextElement; if field.supportsService('com.sun.star.text.TextField.Input') then begin if (field.getPropertyValue('Hint') = name) then begin field.setPropertyValue('Content', inhalt); Document.TextFields.refresh; Result := True; end; end; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz