Announcement

Collapse
No announcement yet.

Word/Excel Dokumente/Sheets in Datenbank speichern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Word/Excel Dokumente/Sheets in Datenbank speichern

    Ist es möglich (wenn ja wie) zB. komplette Worddokumente oder Exceltabellen in einer z.B. MS SQL2000 Datentenbank über Delphi abzulegen. Bei Bedarf soll diese Datei/en wieder über Delphi/SQL2000 geöfnnet werden.
    Für Infos schon vielen Dank im voraus.

  • #2
    Hallo,

    ja - das geht.

    >..wenn ja wie..

    Es gibt mindestens 3 Alternativen. Am einfachsten ist der Weg über eine temporäre Datei, da das Worddokument oder die Excel-Tabelle als Dateiinhalt eingelesen und als BLOb in der Datenbank gespeichert werden kann.

    Ansonsten steht das <b>IDataObject</b>-Interface zur Verfügung, um den Inhalt des aktuellen Word-Dokuments im RTF-Formular abzurufen und in der Datenbank zu speichern.

    Die dritte Alternative greift auf einen OleContainer zu, um dort über <b>LoadFromStream</b> und <b>SaveToStream</b> das angezeigten OLE-Objekt (Word oder Excel) direkt aus der Datenbank zu laden.

    Auf der CDROM zu meinem Buch <i>COM/DCOM/COM+ mit Delphi</i> sind Beispielprojekte für alle 3 Alternativen zu finden: <br>
    1. Kapitel 11\RedSys\RedSys.dpr (OLE Component Document-Fassung) <br>
    2. Kapitel 11\IDataObject\Doc2Rtf\IDataObjectTest2.dpr <br>
    3. Kapitel 11\TOLEContainer\WordOLETest.dpr<br&gt

    Comment


    • #3
      Hallo,

      würde gern mal ein Codebeispiel sehen.

      Gruß
      Mathia

      Comment


      • #4
        Hallo,

        das folgende Beispiel demonstriert den TOleContainer-Weg:

        <pre>

        <font color="#003399"><i>{ ************************************************** **************
        Source File Name : WordOLETestFrm
        Typ : Formular-Unit
        Autor : Andreas Kosch
        Erstellt am : 28.12.1997
        Compiler : Delphi 4.02 UpdatePack#3
        Betriebssystem : Windows 98
        Beschreibung : Word-Dokument ueber OLEContainer in der
        Datenbanktabelle speichern.
        Die komplette Funktionalitaet ist im
        Datenmodul der Anwendung gekapselt.
        Revisionen : 12.09.1999 Delphi 4.02 + Word2000
        ************************************************** ************** }</i></font>

        <b>unit</b> WordOLETestFrm;

        <b>interface</b>

        <b>uses</b>
        Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
        Dialogs, DBCtrls, Db, Grids, DBGrids, DBTables, StdCtrls,
        Buttons, OleCtnrs, ExtCtrls, ComCtrls, Menus;

        <b>type</b>
        TFormMain = <b>class</b>(TForm)
        StatBar: TStatusBar;
        Panel1: TPanel;
        OleContainerWord: TOleContainer;
        DBGrid1: TDBGrid;
        DBNavigator1: TDBNavigator;
        MainMenu1: TMainMenu;
        Datei1: TMenuItem;
        Exit1: TMenuItem;
        MHelp: TMenuItem;
        MHAbout: TMenuItem;
        MemoVerb: TMemo;
        MWActivate: TMenuItem;
        N1: TMenuItem;
        MWExportRTF: TMenuItem;
        SaveDialog1: TSaveDialog;
        MWExportDOC: TMenuItem;
        <b>procedure</b> Exit1Click(Sender: TObject);
        <b>procedure</b> MHAboutClick(Sender: TObject);
        <b>procedure</b> FormCreate(Sender: TObject);
        <b>procedure</b> MWActivateClick(Sender: TObject);
        <b>procedure</b> MWExportRTFClick(Sender: TObject);
        <b>procedure</b> MWExportDOCClick(Sender: TObject);
        <b>private</b>
        <font color="#003399"><i>{ Private-Deklarationen }</i></font>
        <b>procedure</b> ActivateWordDocInContainer(Sender: TObject);
        <b>public</b>
        <font color="#003399"><i>{ Public-Deklarationen }</i></font>
        <b>end</b>;

        <b>var</b>
        FormMain: TFormMain;

        <b>implementation</b>

        <font color="#003399"><i>{$R *.DFM}</i></font>

        <b>uses</b> ComObj, ActiveX, WordOLETestDM;

        <font color="#003399"><i>// Neu: OLEContainer beim Aktivieren der Anwendung neu initialisieren</i></font>

        <b>procedure</b> TFormMain.FormCreate(Sender: TObject);
        <b>begin</b>
        Application.OnActivate := ActivateWordDocInContainer;
        <b>end</b>;

        <font color="#003399"><i>// Datenmodul-Methode aufrufen: Im Edit-Modus wird DoVerb(1) aufgerufen</i></font>

        <b>procedure</b> TFormMain.ActivateWordDocInContainer(Sender: TObject);
        <b>begin</b>
        DM.ActivateContainer
        <b>end</b>;

        <font color="#003399"><i>// Manuelle Aktivierung via Menuepunkt</i></font>

        <b>procedure</b> TFormMain.MWActivateClick(Sender: TObject);
        <b>begin</b>
        OleContainerWord.DoVerb(1);
        <b>end</b>;

        <b>procedure</b> TFormMain.Exit1Click(Sender: TObject);
        <b>begin</b>
        Close
        <b>end</b>;

        <b>procedure</b> TFormMain.MHAboutClick(Sender: TObject);
        <b>begin</b>
        MessageDlg(<font color="#9933CC">'Word-Dokument ueber TOLEContainer direkt aus '</font> + #13 +
        <font color="#9933CC">'der Datenbank einlesen bzw. dort speichern. '</font> + #13 +
        <font color="#9933CC">'Das Dokument wird ueber ZLib in komprimierter '</font> + #13 +
        <font color="#9933CC">'Form in der Datenbanktabelle gespeichert.'</font> + #13#13 +
        <font color="#9933CC">'&#169 Andreas Kosch 1998-1999'</font> , mtInformation, [mbOK], 0);
        <b>end</b>;

        <font color="#003399"><i>{ Fuer den Fall, dass ein eingebettetes OLE-Objekt nicht im speziellen
        Format des OleContainers gespeichert werden soll, sondern im
        urspruenglichen Dateiformat, kann der Automation-Zugriff bemueht
        werden. }</i></font>

        <b>procedure</b> TFormMain.MWExportDOCClick(Sender: TObject);
        <b>begin</b>
        <b>with</b> SaveDialog1 <b>do</b>
        <b>if</b> Execute <b>then</b>
        OleContainerWord.OLEObject.SaveAs(FileName:= FileName,
        FileFormat:= 0);
        <b>end</b>;

        <font color="#003399"><i>{ Fuer den Fall, dass ein eingebettetes OLE-Objekt nicht im speziellen
        Format des OleContainers gespeichert werden soll, sondern im
        urspruenglichen Dateiformat, kann das universelle IDataObject-Interface
        bemueht werden.
        In diesem Fall wird das gesuchte Format ueber seine Bezeichnung als
        Zeichenkette gesucht. }</i></font>

        <b>procedure</b> TFormMain.MWExportRTFClick(Sender: TObject);
        <b>const</b>
        RTF_NAME = <font color="#9933CC">'Rich Text Format'</font>;
        RTF_NAME_MAX = 254;
        <b>var</b>
        aDataObject : IDataObject;
        aEnumFmt : IEnumFORMATETC;
        aFormatEtc : TFormatEtc;
        aMedium : TStgMedium;
        pFmtName : PChar;
        bFmtFound : Boolean;
        pRTFData : PChar;
        OutputFile : TextFile;
        <b>begin</b>
        <font color="#003399"><i>// Zieldateiname definiert ?</i></font>
        <b>if</b> <b>not</b> SaveDialog1.Execute <b>then</b>
        Abort;
        bFmtFound := False;
        OleContainerWord.DoVerb(1);
        OleContainerWord.OLEObjectInterface.QueryInterface (IDataObject, aDataObject);
        <font color="#003399"><i>// IDataObject der Quelle ok ?</i></font>
        <b>if</b> aDataObject = <b>nil</b> <b>then</b>
        Abort;
        <font color="#003399"><i>// cfFormat-Wert fuer den RTF-Inhalt des Word-Dokuments ermitteln</i></font>
        OleCheck(aDataObject.EnumFormatEtc(DATADIR_GET, aEnumFmt));
        <b>while</b> (<b>not</b> bFmtFound) <b>and</b>
        (aEnumFmt.Next(1, aFormatEtc, <b>nil</b>) = S_OK) <b>do</b>
        <b>begin</b>
        pFmtName := AllocMem(RTF_NAME_MAX + 1);
        GetClipBoardFormatName(aFormatEtc.cfFormat, pFmtName, RTF_NAME_MAX);
        <b>if</b> (<b>String</b>(pFmtName) = RTF_NAME) <b>then</b>
        bFmtFound := True;
        FreeMem(pFmtName);
        <b>end</b>;
        <b>if</b> <b>not</b> bFmtFound <b>then</b>
        Abort;
        OleCheck(aDataObject.GetData(aFormatEtc, aMedium));
        <font color="#003399"><i>// RTF-Format wird ueber einen globalen Puffer uebergeben</i></font>
        pRTFData := GlobalLock(aMedium.hglobal);
        <b>try</b>
        AssignFile(OutputFile, SaveDialog1.Filename);
        <font color="#003399"><i>// Datei neu erstellen oder ueberschreiben</i></font>
        ReWrite(OutputFile);
        <b>try</b>
        WriteLn(OutputFile, pRTFData);
        <b>finally</b>
        CloseFile(OutputFile);
        <b>end</b>;
        <b>finally</b>
        GlobalUnlock(aMedium.hglobal);
        <b>end</b>;
        <b>end</b>;

        <b>end</b>.

        </pre>
        Das Datenmodul:

        <pre>

        <font color="#003399"><i>{ ************************************************** **************
        Source File Name : WordOLETestDM.pas
        Typ : Datenmodul
        Autor : Andreas Kosch
        Erstellt am : 31.01.1998
        Compiler : Delphi 3.02 / Delphi 4.02
        Betriebssystem : Windows 95
        Revisionen : 12.09.1999 Delphi 4 UpdatePack#3 + Word2000
        ************************************************** ************** }</i></font>

        <b>unit</b> WordOLETestDM;

        <b>interface</b>

        <b>uses</b>
        Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
        Dialogs, DB, DBTables;

        <b>type</b>
        TDM = <b>class</b>(TDataModule)
        TableWordOLE: TTable;
        TableWordOLERecNr: TAutoIncField;
        TableWordOLEDocName: TStringField;
        TableWordOLEDocData: TBlobField;
        DataSourceWordOLE: TDataSource;
        <b>procedure</b> DataSourceWordOLEDataChange(Sender: TObject; Field: TField);
        <b>procedure</b> TableWordOLEBeforePost(DataSet: TDataSet);
        <b>procedure</b> TableWordOLENewRecord(DataSet: TDataSet);
        <b>private</b>
        <font color="#003399"><i>{ Private-Deklarationen }</i></font>
        <b>procedure</b> ReadDocData;
        <b>procedure</b> WriteDocData;
        <b>procedure</b> WriteRTFDataFile;
        <b>public</b>
        <font color="#003399"><i>{ Public-Deklarationen }</i></font>
        <b>procedure</b> ActivateContainer;
        <b>end</b>;

        <b>var</b>
        DM: TDM;

        <b>implementation</b>

        <font color="#003399"><i>{$R *.DFM}</i></font>

        <b>uses</b> WordOLETestFrm, COMObj, ZLib;

        <b>const</b>
        ZLibBufferSize = 4096; <font color="#003399"><i>// ZLib</i></font>
        wdGoToBookmark = -1;
        wdGoToLine = 3;
        wdGoToRelative = 2;

        <b>var</b>
        ZLibBuffer: <b>array</b>[0..ZLibBufferSize - 1] <b>of</b> Byte;

        <b>resourcestring</b>
        cDocPath = <font color="#9933CC">'C:\temp\test.doc'</font>;
        cRTFPath = <font color="#9933CC">'C:\temp\test.rtf'</font>;
        cMsgStatus = <font color="#9933CC">'%d Bytes zu %d Bytes komprimiert.'</font> + #13 +
        <font color="#9933CC">'Komprimierte Daten: %d %% der Originalgroesse'</font>;

        <font color="#003399"><i>(* Ereignisbehandlungsmethode fuer OnDateChange reagiert auf
        3 Bedingungen:
        a) Tabelle noch nicht aktiv -&gt; Exit
        b) Benutzer waehlt einen anderen Datensatz aus -&gt; ReadDocData
        c) Benutzer editiert einen Datensatz -&gt; Word aktivieren *)</i></font>

        <b>procedure</b> TDM.DataSourceWordOLEDataChange(Sender: TObject; Field: TField);
        <b>begin</b>
        <b>with</b> TableWordOLE <b>do</b> <b>begin</b>
        <font color="#003399"><i>// Sicherheitsabfrage</i></font>
        <b>if</b> <b>not</b> Active <b>then</b> exit;
        <font color="#003399"><i>// Datensatz wird eingelesen</i></font>
        <b>if</b> State = dsBrowse
        <font color="#003399"><i>// Dokumentinhalt aus der Datenbank einlesen</i></font>
        <b>then</b> ReadDocData;
        <font color="#003399"><i>// Datensatz wird editiert</i></font>
        <b>if</b> State = dsEdit
        <font color="#003399"><i>// Word (Menuepunkt/Toolbar) aktivieren</i></font>
        <b>then</b> FormMain.OleContainerWord.DoVerb(1);
        <b>end</b>;
        <b>end</b>;

        <font color="#003399"><i>(* Immer dann, wenn ein neuer Datensatz eingefuegt werden soll,
        oeffnet der OLEContainer die Dokument-Vorlage, in der die
        Rohfassung des Dokuments steht. Anschliessend kann das
        Programm einige Server-Befehle ueber &#187DoVerb&#171 ausfuehren,
        wobei zur Information die gerade verfuegbaren Befehle in die
        TMemo-Instanz im Programmfenster geschrieben werden. *)</i></font>

        <b>procedure</b> TDM.TableWordOLENewRecord(DataSet: TDataSet);
        <b>var</b>
        aDoc : OLEVariant;
        iCnt : Integer;
        <b>begin</b>
        TableWordOLEDocName.Value := <font color="#9933CC">'Neu (unbenannt)'</font>;
        <font color="#003399"><i>// OLEContainer fuellen</i></font>
        FormMain.OLEContainerWord.CreateObjectFromFile(cDo cPath,False);
        <font color="#003399"><i>// Befehl &quot;Bearbeiten&quot; ausfuehren</i></font>
        FormMain.OLEContainerWord.DoVerb(1);
        <font color="#003399"><i>// zur Demonstration alle Befehle auflisten</i></font>
        <b>with</b> FormMain, MemoVerb.Lines <b>do</b> <b>begin</b>
        Clear;
        AddStrings(OLEContainerWord.ObjectVerbs);
        <b>end</b>;
        <font color="#003399"><i>// im Dokument koennen via VBA-Objekt Daten eingesetzt werden</i></font>
        aDoc := FormMain.OLEContainerWord.OLEObject;
        <b>try</b>
        <font color="#003399"><i>// fiktive Daten in formatierter Form schreiben</i></font>
        WriteRTFDataFile;
        <font color="#003399"><i>// Inhalt der RTF-Datei an die Cursorposition einfuegen</i></font>
        aDoc.Range.InsertFile(cRTFPath);
        aDoc.Paragraphs.Add;
        aDoc.Range.InsertAfter(Format(<font color="#9933CC">'Daten vom %s.'</font>,[DateTimeToStr(Now)]));
        <b>for</b> iCnt := 1 <b>to</b> 4 <b>do</b>
        aDoc.Paragraphs.Add;
        aDoc.Range.InsertAfter(<font color="#9933CC">'Unterschrift'</font>);
        <b>except</b>
        MessageBeep($FFFFFFFF);
        <b>end</b>;
        <b>end</b>;

        <font color="#003399"><i>(* Immer dann, wenn die Tabelle in den Editier-Modus geschaltet
        wurde, aktiviert das Programm Word im OLEContainer. Der Anwender
        kann somit AEnderungen im Dokument vornehmen. Aus diesem Grund
        schreibt das Programm den Dokumentinhalt in der Ereignis-
        behandlungsmethode &#187BeforePost&#171 in die Datenbank zurueck. *)</i></font>

        <b>procedure</b> TDM.TableWordOLEBeforePost(DataSet: TDataSet);
        <b>begin</b>
        WriteDocData;
        <b>end</b>;

        <font color="#003399"><i>{-----------------------------------------------------------}</i></font>
        <font color="#003399"><i>{ Private Methoden }</i></font>
        <font color="#003399"><i>{-----------------------------------------------------------}</i></font>

        <font color="#003399"><i>(* Der Dokumentinhalt soll aus der Datenbank eingelesen werden.
        Dazu wird eine temp. Stream-Instanz angelegt und mit dem
        Inhalt aus der Datenbank gefuellt. Anschliessend laedt der
        OLEContainer den Dokumentinhalt aus diesem Stream aus.

        TableWordOLEDocData = persistentes TField-Objekt fuer die
        Tabellenspalte &quot;DocData&quot; *)</i></font>

        <b>procedure</b> TDM.ReadDocData;
        <b>var</b>
        <font color="#003399"><i>//aBS : TBlobStream;</i></font>
        InData : TBlobStream; <font color="#003399"><i>// TFileStream fuer Dateiinhalt</i></font>
        OutData : TStream; <font color="#003399"><i>// Ziel fuer die Komprimierung</i></font>
        ZStream : TCustomZLibStream; <font color="#003399"><i>// Kompressor</i></font>
        iCount : Integer;
        <b>begin</b>
        InData := TBlobStream.Create(TableWordOLEDocData, bmRead);
        <font color="#003399"><i>// wurden Daten aus dem Blob-Feld gelesen ?</i></font>
        <b>if</b> InData.Size = 0 <b>then</b> <b>begin</b>
        InData.Free;
        Assert(InData.Size = 0, <font color="#9933CC">'InData-Stream ist leer'</font>);
        Exit;
        <b>end</b>;
        <font color="#003399"><i>// Blob-Daten sind vorhanden -&gt; los geht's</i></font>
        <b>try</b>
        <font color="#003399"><i>// UEbergabepuffer anlegen</i></font>
        OutData := TMemoryStream.Create;
        <b>try</b>
        <font color="#003399"><i>// komprimierte Blob-Daten entkomprimieren</i></font>
        ZStream := TDecompressionStream.Create(InData);
        <b>try</b>
        <font color="#003399"><i>// in 4096-Byte Haeppchen in die Datei schreiben</i></font>
        <b>while</b> True <b>do</b> <b>begin</b>
        iCount := ZStream.<b>Read</b>(ZLibBuffer, ZLibBufferSize);
        <b>if</b> iCount &lt;&gt; 0
        <b>then</b> OutData.WriteBuffer(ZLibBuffer,iCount)
        <b>else</b> Break;
        <b>end</b>;
        <b>finally</b>
        <font color="#003399"><i>// Free -&gt; Buffer wird geleert</i></font>
        ZStream.Free;
        <font color="#003399"><i>// es sind Daten im Stream -&gt; in den Container uebernehmen</i></font>
        OutData.Position := 0;
        FormMain.OleContainerWord.LoadFromStream(OutData);
        <b>end</b>;
        <b>finally</b>
        OutData.Free;
        <b>end</b>;
        <b>finally</b>
        InData.Free;
        <b>end</b>;
        <b>end</b>;

        <font color="#003399"><i>(* Der Dokumentinhalt soll in die Datenbank geschrieben werden.
        Dazu wird eine temp. Stream-Instanz angelegt und mit dem
        Inhalt aus dem OLEContainer gefuellt. Anschliessend laedt der
        OLEContainer den Dokumentinhalt aus diesem Stream aus.

        TableWordOLEDocData = persistentes TField-Objekt fuer die
        Tabellenspalte &quot;DocData&quot; *)</i></font>

        <b>procedure</b> TDM.WriteDocData;
        <b>var</b>
        InData : TStream; <font color="#003399"><i>// TFileStream fuer Dateiinhalt</i></font>
        OutData : TBlobStream; <font color="#003399"><i>// Ziel fuer die Komprimierung</i></font>
        ZStream : TCustomZLibStream; <font color="#003399"><i>// Kompressor</i></font>
        iReadByte, <font color="#003399"><i>// Hilfsvariable Statistik</i></font>
        iWriteByte: Integer; <font color="#003399"><i>// Hilfsvariable Statistik</i></font>
        <b>begin</b>
        iReadByte := 0;
        iWriteByte := 0;
        <b>with</b> TableWordOLE <b>do</b> <b>begin</b>
        <font color="#003399"><i>// Zwischenpuffer fuer die originalen (unkomprimierten) Daten</i></font>
        InData := TMemoryStream.Create;
        <b>try</b>
        <font color="#003399"><i>// Ziel fuer die komprimierten Daten</i></font>
        OutData := TBlobStream.Create(TableWordOLEDocData, bmWrite);
        <b>try</b>
        <font color="#003399"><i>// ZLIB-Komprimierer verwendet die schnellste Methode</i></font>
        ZStream := TCompressionStream.Create(clFastest, OutData);
        <b>try</b>
        <font color="#003399"><i>// originale Daten in den Zwischenpuffer ablegen</i></font>
        FormMain.OLEContainerWord.SaveToStream(InData);
        <font color="#003399"><i>// originale Datengroesse sichern</i></font>
        Inc(iReadByte, InData.Size);
        <font color="#003399"><i>// Daten komprimieren -&gt; stehen danach in OutData</i></font>
        ZStream.CopyFrom(InData, 0);
        <font color="#003399"><i>// Container deaktivieren</i></font>
        FormMain.OLEContainerWord.Close;
        TableWordOLEDocName.Value := <font color="#9933CC">'Gespeichert'</font>;
        <b>finally</b>
        <font color="#003399"><i>// erst nach Free wird der Buffer geleert !</i></font>
        ZStream.Free;
        <font color="#003399"><i>// Daten sind in OutData -&gt; Groesse sichern</i></font>
        Inc(iWriteByte, OutData.Size);
        <b>end</b>;
        <b>finally</b>
        OutData.Free;
        <b>end</b>;
        <b>finally</b>
        InData.Free;
        <b>end</b>;
        <b>end</b>;
        <font color="#003399"><i>// Komprimierungsergebnis in der Statuszeile anzeigen</i></font>
        FormMain.StatBar.SimpleText := Format(cMsgStatus,
        [iReadByte,iWriteByte,
        (iWriteByte * 100) <b>div</b> iReadByte]);
        <b>end</b>;

        <font color="#003399"><i>(* Diese RTF-Sequenzen wurden visuell (via WordPad) zusammengestellt
        und als RTF-Datei gespeichert. Wird die RTF-Datei anschliessend
        mit NotePad geoeffnet, liegen die RTF-Steuerzeichen als normaler
        ASCII-Text vor und koennen via Zwischenablage in das eigene
        Programm uebernommen werden. *)</i></font>

        <b>resourcestring</b>
        cRTF_1 = <font color="#9933CC">'{\rtf1\ansi\deff0\deftab720{\font tbl{\f0\fswiss\fprq2 Arial;}}'</font>;
        cRTF_2 = <font color="#9933CC">'{\colortbl\red0\green0\blue0;}'</font>;
        cRTF_3 = <font color="#9933CC">'\deflang1031\pard\tx284\tx4260\tx 6532\tx7668\'</font> +
        <font color="#9933CC">'tx8804\plain\f0\fs18'</font>;
        cRTF_4 = <font color="#9933CC">'\par }'</font>;
        cData = <font color="#9933CC">'\par\plain\f4\fs18\b %d.\tab %s\plain\f4\fs18\tab %s'</font>;

        <b>procedure</b> TDM.WriteRTFDataFile;
        <b>var</b>
        iCnt : Integer;
        OutputFile : TextFile;
        <b>begin</b>
        AssignFile(OutputFile, cRTFPath);
        <font color="#003399"><i>// Datei neu erstellen oder ueberschreiben</i></font>
        ReWrite(OutputFile);
        <b>try</b>
        WriteLn(OutputFile, cRTF_1);
        WriteLn(OutputFile, cRTF_2);
        WriteLn(OutputFile, cRTF_3);
        <font color="#003399"><i>// irgendwelche fiktive Daten schreiben</i></font>
        <b>for</b> iCnt := 1 <b>to</b> 10 <b>do</b> <b>begin</b>
        WriteLn(OutputFile, Format(cData,[iCnt,<font color="#9933CC">'Thema:'</font>,<font color="#9933CC">'Referent:'</font>]));
        <b>end</b>;
        WriteLn(OutputFile, cRTF_4);
        <b>finally</b>
        CloseFile(OutputFile);
        <b>end</b>;
        <b>end</b>;

        <b>procedure</b> TDM.ActivateContainer;
        <b>begin</b>
        <b>if</b> TableWordOLE.State = dsEdit <b>then</b>
        FormMain.OleContainerWord.DoVerb(1);
        <b>end</b>;

        <b>end</b>.

        </pre&gt

        Comment


        • #5
          Hallo!<br>
          Ich weiß Andreas ist immer sehr uneigennützig, aber das angegebene Buch sollte man definitiv im Schrank stehen haben!<br>
          <br>
          Bei Excel ist im Unterschied zu Word folgendes zu beachten:<br>
          Nicht das RTF Format verwenden, da dabei nur die "sichtbaren" Inhalte, aber nicht Formeln etc. gelesen werden. Stattdessen "Native" als Format verwenden. Die Größe des Buffers läßt sich dann NUR mit GlobalSize(aMedium.hglobal) bestimmen.<br>
          BYE BERN

          Comment

          Working...
          X