Discussion:
Per OLE-Automatisierung Text in Kopfzeile
(zu alt für eine Antwort)
Meina Meist
2006-07-12 12:36:01 UTC
Permalink
Hi,

ich möchte ein Worddokument per OLE-Automatisierung aus Visual Basic .NET
oder C# mit Werten versehen.

Zunächst habe ich es mit Textmarken versucht. Aber leider muss der Name von
Textmarken eindeutig sein, sodass ich ein und denselben Wert nicht an
verschiedenen Stellen im Worddokument verwenden kann.

Daraufhin habe ich es mit Feldern (Formfields/Textformularfelder) versucht.
Diese bieten zwar die Möglichkeit, mehrfach in einem Dokument verwendet zu
werden, haben dafür aber den Nachteil, dass sie nicht in der Kopf- oder
Fusszeile positioniert werden können.

Ich brauche aber unbedingt beide Möglichkeiten:
- Mehrfache Verwendung eines Datenwertes unter gleichem Namen
- Per OLE-Automatisierung füllbare Felder in Kopf- und Fusszeile.

Die Verwendung durchnumerierterter Feldnamen (wie Name1, Name2, Name3...)
kommt nicht in Frage.

Kennt dafür jemand eine praktikable Lösung?

Vielen Dank und Viele Grüße.
Lisa Wilke-Thissen
2006-07-12 12:50:15 UTC
Permalink
Hallo,
Aber leider muss der Name von Textmarken eindeutig
sein, sodass ich ein und denselben Wert nicht an verschiedenen
Stellen im Worddokument verwenden kann.
man kann aber innerhalb eines Dokuments mehrfach auf den
Textmarkeninhalt verweisen (Einfügen/ Referenz/ Querverweis).
--
Viele Grüße

Lisa
MS MVP Word
Anwendertage Word, Excel, PowerPoint, Outlook: www.anwendertage.de
Meina Meist
2006-07-12 14:30:31 UTC
Permalink
man kann aber innerhalb eines Dokuments mehrfach auf den Textmarkeninhalt
verweisen (Einfügen/ Referenz/ Querverweis).
Danke für die schnelle Antwort! Den Menüpunkt habe ich gefunden. Jetzt gibt
es allerdings ein weiteres Problem.

Wenn ich den Text an der Textmarke geändert habe, dann ist die Textmarke
weg - einfach nicht mehr definiert.
Die Änderung der Textmarke nehme ich dabei per OLE vor: b.Range.Text = ...

Da die Textmarke nicht mehr da ist, kann auch die Referenz auf die Textmarke
nicht aktualisiert werden und ich erhalte stattdessen einen Fehlertext im
Dokument.
Lisa Wilke-Thissen
2006-07-12 15:03:48 UTC
Permalink
Hallo,

"Meina Meist" schrieb im Newsbeitrag news:44b50794$0$29129$***@newsread4.arcor-online.net...

[Einfügen/ Referenz/ Querverweis]
Den Menüpunkt habe ich gefunden. Jetzt gibt es allerdings ein
weiteres Problem.
Wenn ich den Text an der Textmarke geändert habe, dann ist die
Textmarke weg - einfach nicht mehr definiert.
Die Änderung der Textmarke nehme ich dabei per OLE vor: b.Range.Text = ...
für dein Crossposting hättest du besser
news:microsoft.public.de.word.vba gewählt.
Wenn dir folgender Link nicht weiterhilft, nimm die Word-NG bitte aus
deinem Verteiler heraus und wende dich an die VBA-Experten:

"VBA-technischer Umgang mit Textmarken"
http://mypage.bluewin.ch/reprobst/WordFAQ/TM.htm
--
Viele Grüße

Lisa
MS MVP Word
Anwendertage Word, Excel, PowerPoint, Outlook: www.anwendertage.de
Microsoft Excel - Die Expertentipps http://tinyurl.com/cmned
Marco von Frieling
2006-07-12 15:16:08 UTC
Permalink
Hallo Meina,
Post by Lisa Wilke-Thissen
Post by Meina Meist
Wenn ich den Text an der Textmarke geändert habe, dann ist die
Textmarke weg - einfach nicht mehr definiert.
Die Änderung der Textmarke nehme ich dabei per OLE vor: b.Range.Text = ...
für dein Crossposting hättest du besser
news:microsoft.public.de.word.vba gewählt.
Da hat Lisa recht. Ich finde es aber sehr merkwürdig, dass du in die
Framework-NG gepostet hast und von OLE-Automation sprichst. Das hat
nichts mit dem .NET Framework zu tun.
Wenn du .NET 2.0 verwendest, schau dir mal VSTO 2.0 (Visual Studio Tools
for Office) an. Damit kannst du das sicher auch lösen. Ich kann dir aber
gerade kein Beispiel geben, weil ich an diesem PC VSTO nicht installiert
und auch das Buch nicht zur Hand habe.

Gruß
Marco
Marco von Frieling
2006-07-16 17:07:05 UTC
Permalink
Hallo Meina,
Post by Meina Meist
Wenn ich den Text an der Textmarke geändert habe, dann ist die Textmarke
weg - einfach nicht mehr definiert.
Das ist so bei Design:
"Bookmarks provide you a way to name and keep track of a particular
Range. The user can even edit the Range and the modified Range will
still be accessible by it's name *unless the user completely deletes the
Range*. [...] For example, setting the Text property of the Range
associated with a bookmark replaces the Range and in the process deletes
the bookmark associated with the Range." (Zitat aus "Visual Studio Tools
for Office", ISBN 0-321-33488-4)

Wenn du allerdings VSTO 2.0 verwendest und dich dessen Bookmark
Host-Control bedienst statt dem Bookmark Objekt aus der PIA (das VSTO
Bookmark aggregiert das PIA Objekt), ist sichergestellt, dass beim
Setzen der Text-Property die Textmarke nicht gelöscht wird.
Post by Meina Meist
Da die Textmarke nicht mehr da ist, kann auch die Referenz auf die Textmarke
nicht aktualisiert werden und ich erhalte stattdessen einen Fehlertext im
Dokument.
Ggf. mit b.Name den Namen der Textmarke auslesen und b.Start sowie
b.Start + myText.Lenght als Start und Ende merken und nach dem Zuweisen
des Textes die Textmarke einfach neu erstellen. Hier ein kleines
Beispiel. Dazu brauchst du nur ein Worddokument mit einigen Bookmarks
drin. Zunächst einmal werden ein paar Hilfvariablen angelegt die wir
brauchen und das Dokument geöffnet:

object docFile = args[0]; // enthält den Dateipfad
object missing = Type.Missing;
Dictionary<string, Word.Bookmark> newBookmarks = new Dictionary<string,
Word.Bookmark>(); // hier speichern wir die neu anzulegenden Textmarken
zwischen, und zwar den Namen und Range.
int i = 0; // die nte Textmarke
string bmText = "Dies ist die {0}. Textmarke (Name: '{1}') im
Dokument."; // Der Formatstring den wir als neuen Text einfügen wollen

Word.Application app = new Word.Application();
Word.Document doc = app.Documents.Open(ref docFile,
ref missing, ref missing, ref missing, ref
missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref
missing, ref missing, ref missing, ref missing,
ref missing);
// missing = brauchen wir alles nicht, müssen es aber mit angeben.


Dann durlaufen wir in einer Schleife alle Textmarken, ändern ihren Text
und merken uns ihren Namen und neuen Range:


foreach (Word.Bookmark bm in doc.Bookmarks)
{
try
{
string neuerBmText = string.Format(bmText, i, bm.Name);
object start = bm.Range.Start; // Anfang der Textmarke
object end = (int)start + neuerBmText.Length;
// neues Ende
string name = bm.Name;
bm.Range.Text = neuerBmText;
// Wir überschreiben den Inhalt der Textmarke
// (und löschen sie damit)
newBookmarks.Add(name,
(Word.Bookmark) doc.Range(ref start, ref end));
// merken sie uns aber...
} catch(Exception ex)
{
// zur Sicherheit mit Fehlerbehandlung
Console.WriteLine(ex);
}
}

Würden wir die neuen Textmarken gleich erzeugen, würden wir auch die
Ergebnismenge der foreach-Schleife jedes mal ändern und so in eine
Endlosschleife gelangen. Deshalb haben wir uns die neu zu erstellenden
Textmarken in einer lokalen Liste gemerkt und erstellen sie jetzt:

foreach (KeyValuePair<string, Word.Bookmark> bm in newBookmarks)
{
try
{
if (!doc.Bookmarks.Exists(bm.Key))
{
// Zur Sicherheit prüfen wir noch mal,
// dass die Textmarke wirklich nicht existiert.
object range = bm.Value;
doc.Bookmarks.Add(bm.Key, ref range);
}
}
catch (Exception ex)
{
// und auch hier wieder mit Fehlerbehandlung,
// wir arbeiten schließlich mit COM!!!
Console.WriteLine(ex);
}
}
newBookmarks.Clear(); // nicht vergessen, die Referenzen auf die
COM-Objekte (Ranges) wieder freizugeben!


Anschließend noch das Dokument speichern und Word beenden:

doc.Save();
doc = null;
app.Quit(ref missing, ref missing, ref missing);
app = null;

Und ganz wichtig, alle auf COM-Objekte erstellten Referenzen löschen,
weil COM mit einem Referenzzähler arbeitet und die Objekte erst aus dem
Speicher entfernt, wenn deren Zähler auf 0 zurückgesetzt werden. Sonst
dürfte Word im Speicher verbleiben, was wir ja nicht wollen. Und wenn
das Programm auf einem Server sagen wir mal stündlich im Hintergrund
läuft, hätten wir nach einem Tag 24 Word-Leichen im Speicher und der
wird dann auch irgendwann knapp.

Ich hoffe, dir damit etwas geholfen zu haben.

Viele Grüße und ein schönes Wochenende noch.

Marco


PS: Falls du noch Fragen haben solltest, melde dich bitte bis Dienstag
nachmittag, danach bin ich ca. 2 Wochen nicht online.

Loading...