Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tabellen-Bearbeitung von VB6-App

27 views
Skip to first unread message

Lothar Geyer

unread,
Jan 31, 2007, 3:37:40 AM1/31/07
to
Ich hatte das Thema schon mal in dieser NG angesprochen, bin aber trotz
Eurer Mithilfe nicht weitergekommen. Jetzt habe ich eine neue Idee.

Nochmal zum Problem.
Ich habe eine Word-Vorlage mit einer Tabelle. Die Anzahl der Zeilen wird
erst zur Laufzeit der VB6-Anwendung ermittelt. Diese Anwendung soll dann
die notwendige Anzahl Zeilen erstellen und ausfüllen. Soweit zunächst
mal kein Problem.
Beim Einfügen einer zusätzlichen Zeile soll aber die komplette
Formatierung einschließlich eventueller Textmarken in die neue Zeile
übernommen werden. Diese eine Zeile der Vorlage ist sowas wie ein
"Template", das das Aussehen aller anderen Zeilen vorgeben soll.

Ein einfaches Kopieren der Zeile habe ich nicht fertig bekommen, da ich
dadurch immer die Textmarken verliere. Aber vielleicht habe ich auch was
falsche gemacht?

Meine neue Idee (falls das möglich ist): Kopieren der Tabelle aus der
Vorlage in meine Anwendung (würde also ein "abgekoppeltes" Table-Object
ohne Dokument benötigen). Dann für jede Zeile Kopieren der
"Template"-Zeile aus diesem Objekt in die Tabelle des Dokuments und
Ausfüllen der Textmarken.

Eine (allerdings wesentlich aufwendigere) Variante wäre, die gesamte
Vorlage zweimal zu laden. Und jedesmal die Template-Zeile in die Tabelle
des anderen Dokuments kopieren und die Textmarken ausfüllen.

Sind diese Wege machbar?

Lothar Geyer

Carsten Sekulla

unread,
Jan 31, 2007, 4:41:51 AM1/31/07
to

"Lothar Geyer" <Lothar...@EDV-Berater-Online.de> schrieb im Newsbeitrag
news:52b2rsF...@mid.individual.net...

> Ich hatte das Thema schon mal in dieser NG angesprochen, bin aber trotz
> Eurer Mithilfe nicht weitergekommen. Jetzt habe ich eine neue Idee.
>
> Nochmal zum Problem.
> Ich habe eine Word-Vorlage mit einer Tabelle. Die Anzahl der Zeilen wird
> erst zur Laufzeit der VB6-Anwendung ermittelt. Diese Anwendung soll dann
> die notwendige Anzahl Zeilen erstellen und ausfüllen. Soweit zunächst mal
> kein Problem.
> Beim Einfügen einer zusätzlichen Zeile soll aber die komplette
> Formatierung einschließlich eventueller Textmarken in die neue Zeile
> übernommen werden. Diese eine Zeile der Vorlage ist sowas wie ein
> "Template", das das Aussehen aller anderen Zeilen vorgeben soll.
>
> Ein einfaches Kopieren der Zeile habe ich nicht fertig bekommen, da ich
> dadurch immer die Textmarken verliere. Aber vielleicht habe ich auch was
> falsche gemacht?
Nein
eine Textmarke kann nur EINMAL im Dokument gestzt werden.
Durch das kopieren hättes du 2 also wird eine gelöscht (bzw. erst garnicht
angelegt)

Wenn du die Textmarke erweitern willst, musst du innerhalb der Textmarke
arbeiten
oder diese lschen und neu anlegen.


> Eine (allerdings wesentlich aufwendigere) Variante wäre, die gesamte
> Vorlage zweimal zu laden. Und jedesmal die Template-Zeile in die Tabelle
> des anderen Dokuments kopieren und die Textmarken ausfüllen.
>
> Sind diese Wege machbar?

fraglich (s.o.)

Wenn du mit einer dynamische Tabelle arbeitest, kannst du doch die Zellen
über
den Index ansprechen und belegen.
Das geht viel schöner als mit Textmarken.

Private Sub xxx()
Dim oDoc As Word.Document
Dim oTab As Word.Table

Dim i As Long
Dim j As Long

Set oDoc = Application.Documents.Add("C:\Dokumente und
Einstellungen\sekulla\Desktop\Dok1.dot")
Set oTab = oDoc.Tables(1)
For i = 1 To oTab.Rows.Count
For j = 1 To oTab.Columns.Count
oTab.Cell(i, j).Range.Text = "Zelle: " & CStr(i) & ", " & CStr(j)
Next
Next
End Sub


>
> Lothar Geyer
>


Thomas Gahler

unread,
Jan 31, 2007, 7:07:44 AM1/31/07
to
Hallo Lothar

> Ein einfaches Kopieren der Zeile habe ich nicht fertig bekommen, da ich
> dadurch immer die Textmarken verliere. Aber vielleicht habe ich auch was
> falsche gemacht?

Ein normales .rows.add sollte doch die Zeile schön kopieren, sofern die
Tabelle richtig formatiert ist.

Die Textmarke kommt nie mit (siehe auch Beitag von Carsten)

Vielleicht schaust du dir auch mal die Möglichkeiten von Formatvorlagen vom
Typ Tabelle an, da kannst du so ziemlich alle Formate einer Tabelle
festlegen.


Du kannst deine zeile sonst auch noch als AutoText abspreichern, vielleicht
ist das auch noch was

--
Thomas Gahler
MVP für WordVBA
Co-Autor von »Microsoft Word-Programmierung.
Das Handbuch« (MS Press)

- Windows XP (SP2), Office XP (SP3)


Lothar Geyer

unread,
Jan 31, 2007, 7:36:43 AM1/31/07
to
Hallo Carsten,

leider kenn ich mich zwar in VB, aber nicht in VBA (und schon gleich gar
nicht in den Word-Objekten) aus.. :-(

Carsten Sekulla schrieb:
> ...


>>Ein einfaches Kopieren der Zeile habe ich nicht fertig bekommen, da ich
>>dadurch immer die Textmarken verliere. Aber vielleicht habe ich auch was
>>falsche gemacht?
>
> Nein
> eine Textmarke kann nur EINMAL im Dokument gestzt werden.
> Durch das kopieren hättes du 2 also wird eine gelöscht (bzw. erst garnicht
> angelegt)
>
> Wenn du die Textmarke erweitern willst, musst du innerhalb der Textmarke
> arbeiten
> oder diese lschen und neu anlegen.

Textmarken von meiner VB-Anwendung aus "aufzufüllen" (also mit real-Text
zu ersetzen) mache ich bei vielen Dokument-Arten (Brief, Fax usw.)

>>Eine (allerdings wesentlich aufwendigere) Variante wäre, die gesamte
>>Vorlage zweimal zu laden. Und jedesmal die Template-Zeile in die Tabelle
>>des anderen Dokuments kopieren und die Textmarken ausfüllen.
>>
>>Sind diese Wege machbar?
>
> fraglich (s.o.)
>
> Wenn du mit einer dynamische Tabelle arbeitest, kannst du doch die Zellen
> über
> den Index ansprechen und belegen.
> Das geht viel schöner als mit Textmarken.
>
> Private Sub xxx()
> Dim oDoc As Word.Document
> Dim oTab As Word.Table
>
> Dim i As Long
> Dim j As Long
>
> Set oDoc = Application.Documents.Add("C:\Dokumente und
> Einstellungen\sekulla\Desktop\Dok1.dot")
> Set oTab = oDoc.Tables(1)
> For i = 1 To oTab.Rows.Count
> For j = 1 To oTab.Columns.Count
> oTab.Cell(i, j).Range.Text = "Zelle: " & CStr(i) & ", " & CStr(j)
> Next
> Next
> End Sub

Wenn ich das richtig verstanden habe, macht das aber nicht das, was ich
will.

Ausgangssituation:
In der Vorlage ist eine Tabelle mit einer Zeile mit (angenommen) drei
Spalten. In jeder Spalte dieser Zeile steht ein Text mit einer oder
mehreren eingebetteten Textmarken und teilweise Formatierungen
(Fettschrift).

Meine Anwendung soll aus dieser Tabelle eine Tabelle mit n (erst zur
Laufzeit bekannt) Zeilen erstellen. Jede dieser Zeilen soll gleich der
ersten (in der Vorlage enthaltenen) sein, nur mit anderen Ersetzungen
für die Textmarken.

Lothar Geyer

Carsten Sekulla

unread,
Jan 31, 2007, 8:02:39 AM1/31/07
to

"Lothar Geyer" <Lothar...@EDV-Berater-Online.de> schrieb im Newsbeitrag
news:52bgs4F...@mid.individual.net...

> Hallo Carsten,
>
> leider kenn ich mich zwar in VB, aber nicht in VBA (und schon gleich gar
> nicht in den Word-Objekten) aus.. :-(
Unter VB wirst du ja auch auf Word referenzieren müssen.
Entweder mir CreateObject() oder Dim As ... [New] Word.Application
und dann ist alles gleich ....


> Textmarken von meiner VB-Anwendung aus "aufzufüllen" (also mit real-Text
> zu ersetzen) mache ich bei vielen Dokument-Arten (Brief, Fax usw.)

aber immer nur an EINER Stellen ....
Tabellen sind da viel angenehmer, da die Felder explizit über Indizes
angesprochen werden können.

>> Wenn du mit einer dynamische Tabelle arbeitest, kannst du doch die Zellen
>> über
>> den Index ansprechen und belegen.
>> Das geht viel schöner als mit Textmarken.
>>
>> Private Sub xxx()
>> Dim oDoc As Word.Document
>> Dim oTab As Word.Table
>>
>> Dim i As Long
>> Dim j As Long
>>

in VB:
Dim oWW as Word.Application 'Verweis für Word Setzen

set oww = new word.application
oww.visible=true
oww.windowsstate=1 'ggf. minimiert oder was weiss ich

Set oDoc = oww.Documents.Add("C:\Dokumente und
usw.


>> Set oDoc = Application.Documents.Add("C:\Dokumente und
>> Einstellungen\sekulla\Desktop\Dok1.dot")
>> Set oTab = oDoc.Tables(1)
>> For i = 1 To oTab.Rows.Count
>> For j = 1 To oTab.Columns.Count
>> oTab.Cell(i, j).Range.Text = "Zelle: " & CStr(i) & ", " & CStr(j)
>> Next
>> Next
>> End Sub
>
> Wenn ich das richtig verstanden habe, macht das aber nicht das, was ich
> will.

das ist ein Beispiel

> Meine Anwendung soll aus dieser Tabelle eine Tabelle mit n (erst zur
> Laufzeit bekannt) Zeilen erstellen. Jede dieser Zeilen soll gleich der
> ersten (in der Vorlage enthaltenen) sein, nur mit anderen Ersetzungen für
> die Textmarken.

(siehe Thomas)
mit
.rows.add
Tabelle erweitern und mit
oTab.Cell(i, j).Range.Text
Zellen belegen und ggf. formatieren.

Die Indizes i und j kann man sich jetzt berechnen.
deswegen das Beispiel.


z.B.
Vorlage hat 2 Zeilen (1 Titel, 1 formatierte Daten-Zeile)
zu erstellende Tabelle soll 1+N Zeilen habe
also

For j = 1 To oTab.Columns.Count

oTab.Cell(2, j).Range.Text = "Zelle: " & CStr(2) & ", " & CStr(j)
Next

For i=3 to 1+N
oTab.rows.add


For j = 1 To oTab.Columns.Count
oTab.Cell(i, j).Range.Text = "Zelle: " & CStr(i) & ", " & CStr(j)
Next
Next

'fertsch

cu CS

>
> Lothar Geyer
>


Lothar Geyer

unread,
Jan 31, 2007, 9:08:45 AM1/31/07
to
Hallo Carsten,

ich glaube, hier liegt ein ganz großes Mißverständnis vor.

Was ich als "Vorlage" meine, ist eine .dot-Vorlage, die ein mir
unbekannter Anwender mit einer Tabelle erstellt hat. In der ersten Zeile
der Tabelle kann in jeder Zelle irgendein von diesem unbekannten
Anwender angegebener Text stehen, den er irgendwie formatiert hat. In
diesem Text soll dieser unbekannte Anwender Textmarken angeben können,
die ich dann mit meiner VB-App ausfüllen soll.
Und aus dieser einen Zeile können 10 oder 20 werden (oder es kann auch
bei der einen, ersten bleiben), und jede soll gleich aussehen, nur eben
immer mit anderen Ersetzungen für die (gleiche) Textmarke.

Ungefähr so:

fügeNeueZeileHinzu
ersetzeTextMarke "TextMarke1" in Zeile1 mit ErsetzText11
ersetzeTextMarke "TextMarke2" in Zeile1 mit ErsetzText12
ersetzeTextMarke "TextMarke3" in Zeile1 mit ErsetzText13
fügeNeueZeileHinzu
ersetzeTextMarke "TextMarke1" in Zeile2 mit ErsetzText21
ersetzeTextMarke "TextMarke2" in Zeile2 mit ErsetzText22
ersetzeTextMarke "TextMarke3" in Zeile2 mit ErsetzText23
fügeNeueZeileHinzu
ersetzeTextMarke "TextMarke1" in Zeile3 mit ErsetzText31
ersetzeTextMarke "TextMarke2" in Zeile3 mit ErsetzText32
ersetzeTextMarke "TextMarke3" in Zeile3 mit ErsetzText33

wobei es dem Ersteller der Vorlage möglich sein soll, z.B. die
Textmarke1 in irgendeiner Spalte unterzubringen.

Lothar Geyer

Lothar Geyer

unread,
Jan 31, 2007, 9:12:01 AM1/31/07
to
Hallo Thomas,

Thomas Gahler schrieb:
> ...


>>Ein einfaches Kopieren der Zeile habe ich nicht fertig bekommen, da ich
>>dadurch immer die Textmarken verliere. Aber vielleicht habe ich auch was
>>falsche gemacht?
>
> Ein normales .rows.add sollte doch die Zeile schön kopieren, sofern die
> Tabelle richtig formatiert ist.
>
> Die Textmarke kommt nie mit (siehe auch Beitag von Carsten)

das ist eben das Problem. Und da suche ich irgendeinen "Trick", denn ich
brauche das ... ;-))

> Vielleicht schaust du dir auch mal die Möglichkeiten von
Formatvorlagen vom
> Typ Tabelle an, da kannst du so ziemlich alle Formate einer Tabelle
> festlegen.

Die Formate sind nicht das Problem, sondern eben die Textmarken.

> Du kannst deine zeile sonst auch noch als AutoText abspreichern,
vielleicht
> ist das auch noch was

Huch, Autotext? Was ist das? Werde mir das erst mal anlesen müssen.

Lothar Geyer

Carsten Sekulla

unread,
Jan 31, 2007, 9:39:12 AM1/31/07
to

"Lothar Geyer" <Lothar...@EDV-Berater-Online.de> schrieb im Newsbeitrag
news:52bm8mF...@mid.individual.net...

> Hallo Carsten,
>
> ich glaube, hier liegt ein ganz großes Mißverständnis vor.
Ich glaube nicht (-:

Also das ist schon i.o. so wie ich dir das vorgeschlagen habe,
nur brauchts du eine Zuordnung TM zu Zelle
zum Testen in Word-VBA


Private Sub xxx()
Dim oDoc As Word.Document
Dim oTab As Word.Table

Dim oTM As Word.Bookmark
Dim sTM2CellCol() As String

Dim i As Long
Dim j As Long

Dim N As Long

N = 5


Set oDoc = Application.Documents.Add("C:\Dokumente und
Einstellungen\sekulla\Desktop\Dok1.dot")
Set oTab = oDoc.Tables(1)

If oTab.Range.Bookmarks.Count > 0 Then
ReDim sTM2CellCol(oTab.Columns.Count) As String
j = 0
For Each oTM In oTab.Range.Bookmarks
sTM2CellCol(oTM.Range.Cells(1).ColumnIndex) = oTM.Name 'nur eine
TM pro Zelle
Debug.Print oTM.Name, sTM2CellCol(j)
Next

For j = 1 To UBound(sTM2CellCol())
oTab.Cell(2, j).Range.Text = sTM2CellCol(j)
Next
For i = 3 To N + 1
oTab.Rows.Add
For j = 1 To UBound(sTM2CellCol())
oTab.Cell(i, j).Range.Text = sTM2CellCol(j)
Next
Next
End If
End Sub
'funkt

wie unten gewünscht
cu CS

Lothar Geyer

unread,
Jan 31, 2007, 9:50:48 AM1/31/07
to
Hallo Carsten,

ich bin momentan etwas unter Zeitdruck. Ich werde mir das am Abend
ansehen und melde mich dann wieder.

Lothar Geyer

Thomas Gahler

unread,
Jan 31, 2007, 10:47:22 AM1/31/07
to
Hallo Lothar


> Was ich als "Vorlage" meine, ist eine .dot-Vorlage, die ein mir
> unbekannter Anwender mit einer Tabelle erstellt hat. In der ersten Zeile
> der Tabelle kann in jeder Zelle irgendein von diesem unbekannten Anwender
> angegebener Text stehen, den er irgendwie formatiert hat. In diesem Text
> soll dieser unbekannte Anwender Textmarken angeben können, die ich dann
> mit meiner VB-App ausfüllen soll.
> Und aus dieser einen Zeile können 10 oder 20 werden (oder es kann auch bei
> der einen, ersten bleiben), und jede soll gleich aussehen, nur eben immer
> mit anderen Ersetzungen für die (gleiche) Textmarke.

Dann sehe ich höchstes die Möglichkeiten von Platzhalten im Text. So
ungefähr so

"Hallo, meine Name is @@@NAME@@@. Und wie heisst du?"


Weisst du was ich meine? Das kannst du sicher duplizieren, aber jetzt hast
du einfach zig mal @@@NAME@@@ in der Tabelle und was jetzt?

Mit Sucher/Ersetzen kannst du gleich alle mit dem gleichen Wert ausstatten.
Oder eben wie es Carsten macht, die Zellen ansprechen und darin den Text
ersetzen (.Range bestimmen) oder Suchen/Ersetzen in diesem .Range anwenden.

Carsten Sekulla

unread,
Jan 31, 2007, 11:36:03 AM1/31/07
to
p.s.
hatte noch Test auf leere Zelle (ohne Textmarke nicht im Modul) vergessen.

hier das ganze als VB-Modul
Private Sub main()
Dim oWW As Object 'Word.Application
Dim oDoc As Object ' Word.Document
Dim oTab As Object 'Word.Table
Dim oTM As Object 'Word.Bookmark
Dim sTM2CellCol() As String

Dim i As Long
Dim j As Long
Dim N As Long

N = 5

Set oWW = CreateObject("Word.Application") ' New Word.Application
oWW.Visible = True
oWW.WindowState = 0 'wdWindowStateNormal
' 1. Zeile Überschrift
' 2. Zeile erste Datenzeile mit Textmarken
Set oDoc = oWW.Documents.Add("C:\Dokumente und

Einstellungen\sekulla\Desktop\Dok1.dot")
Set oTab = oDoc.Tables(1)
If oTab.Range.Bookmarks.Count > 0 Then
ReDim sTM2CellCol(oTab.Columns.Count) As String

For Each oTM In oTab.Range.Bookmarks
sTM2CellCol(oTM.Range.Cells(1).ColumnIndex) = oTM.Name 'nur eine
TM pro Zelle
Debug.Print oTM.Name

Next
For i = 2 To N + 1
If i > 2 Then
oTab.Rows.Add
End If


For j = 1 To UBound(sTM2CellCol())

If Len(sTM2CellCol(j)) > 0 Then
'Hier kann auch was vernünftiges zugewiesen werden
oTab.Cell(i, j).Range.Text = "Wert für: " & sTM2CellCol(j) &
" in Zeile: " & CStr(i)
End If
Next
Next
End If
Set oWW = Nothing
End Sub


cu CS


Lothar Geyer

unread,
Jan 31, 2007, 11:21:55 PM1/31/07
to
Hallo Thomas,

Thomas Gahler schrieb:


>>Was ich als "Vorlage" meine, ist eine .dot-Vorlage, die ein mir
>>unbekannter Anwender mit einer Tabelle erstellt hat. In der ersten Zeile
>>der Tabelle kann in jeder Zelle irgendein von diesem unbekannten Anwender
>>angegebener Text stehen, den er irgendwie formatiert hat. In diesem Text
>>soll dieser unbekannte Anwender Textmarken angeben können, die ich dann
>>mit meiner VB-App ausfüllen soll.
>>Und aus dieser einen Zeile können 10 oder 20 werden (oder es kann auch bei
>>der einen, ersten bleiben), und jede soll gleich aussehen, nur eben immer
>>mit anderen Ersetzungen für die (gleiche) Textmarke.
>
> Dann sehe ich höchstes die Möglichkeiten von Platzhalten im Text. So
> ungefähr so
>
> "Hallo, meine Name is @@@NAME@@@. Und wie heisst du?"
>
> Weisst du was ich meine? Das kannst du sicher duplizieren, aber jetzt hast
> du einfach zig mal @@@NAME@@@ in der Tabelle und was jetzt?

Angenommen in Spalte 1 ist die Textmarke "TM01" (@@@TM01@@@) und in
Spalte 3 ist die Textmarke "TM03" (@@@TM03@@@), dann könnte ich doch
- in Zeile 1 die Textmarke TM01 mit ABC1 ersetzen
- in Zeile 2 die Textmarke TM01 mit ABC2 ersetzen
usw.
Nur könnte ich ín diesem Fall keine Textmarken verwenden und könnte
keine Formatierungen mit übernehmen. Oder sehe ich das falsch?

> Mit Sucher/Ersetzen kannst du gleich alle mit dem gleichen Wert ausstatten.
> Oder eben wie es Carsten macht, die Zellen ansprechen und darin den Text
> ersetzen (.Range bestimmen) oder Suchen/Ersetzen in diesem .Range anwenden.

Das ist es ja was ich nicht will. Die einzusetzenden Texte sollen ja in
jeder Zeile anders sein können.

In der Antwort auf Carsten's Posting habe ich einen Link zu einem
Dokument angegeben, in dem ich das verdeutlicht habe.

Lothar Geyer

Lothar Geyer

unread,
Jan 31, 2007, 11:29:12 PM1/31/07
to
Hallo Carsten,

ich habe Dein Modul angesehen. Danke. Aber das ist nicht das, was ich
will. Die zu ersetzenden Texte sollen in jeder Zeile anders aussehen können.

Ich habe ein Beispiel unter
http://www.edv-berater-online.de/test/TabellenTest.dot zur Verfügung
gestellt.

Lothar Geyer

Reiner Wolff

unread,
Feb 1, 2007, 1:18:34 AM2/1/07
to
Moin Lothar,

*Lothar Geyer* schrieb:

Wenn sichergestellt ist, dass die Textmarken tatsächlich für jede Zeile
aufsteigend durchnummeriert werden müssten, kannst Du auch in allen Zeilen
mit @@TM@@ arbeiten. Dann steht zwar in der ganzen Tabelle in den Zeilen
überall die gleiche "Textmarke" (ja eigentlich ein geschützter Begriff aus
Word), aber das macht ja nichts.

Woher ermittelst Du denn die Texte, die diese Textmarken ersetzen sollen?
Du kannst entweder, um die Textmarken doch durchnummeriert zu haben, die
Tabelle durchgehen und @@TM@@ durch @@TMZeilenNummer@@ per Code ersetzen
lassen. Die Zeilennummer sollte man ja herausbekommen können.
Oder Du sparst Dir die Arbeit und gehst Deine Ersatztexte Zeilenweise durch
und ersetzt jeweils @@TM@@ nur Zeile für Zeile.

Zur Übernahme der Formatierungen wirst Du vermutlich (ich habe von Word
auch keine Ahnung) die Formateinstellungen zwischenspeichern müssen, um sie
auf den ersetzten Text danach direkt wieder anwenden zu können.

Als Programmierung sähe das so aus:
dim i As Long
Wenn es sich um eine einheitliche Tabelle handelt,
For i = 1 To Zeilenanzahl
Speichere das Format von @@TM@@
Ersetze in der Zeile i den Text von @@TM@@ durch 'Ersatz & i'
Übertrage das gespeicherte Format auf den ersetzten Text
Next i

Jetzt müsste man das "nur" noch nach Word-VBA umwandeln ;-)

HTH
Gruß aus Kiel
Reiner
--
Ein Programm sollte nicht nur Hand und Fuss,
sondern auch Herz und Hirn haben.
(Michael Anton)

Lothar Geyer

unread,
Feb 1, 2007, 1:39:09 AM2/1/07
to
Hallo Reiner,

Reiner Wolff schrieb:
> ...


> Wenn sichergestellt ist, dass die Textmarken tatsächlich für jede Zeile
> aufsteigend durchnummeriert werden müssten, kannst Du auch in allen Zeilen
> mit @@TM@@ arbeiten. Dann steht zwar in der ganzen Tabelle in den Zeilen
> überall die gleiche "Textmarke" (ja eigentlich ein geschützter Begriff aus
> Word), aber das macht ja nichts.
>
> Woher ermittelst Du denn die Texte, die diese Textmarken ersetzen sollen?
> Du kannst entweder, um die Textmarken doch durchnummeriert zu haben, die
> Tabelle durchgehen und @@TM@@ durch @@TMZeilenNummer@@ per Code ersetzen
> lassen. Die Zeilennummer sollte man ja herausbekommen können.
> Oder Du sparst Dir die Arbeit und gehst Deine Ersatztexte Zeilenweise durch
> und ersetzt jeweils @@TM@@ nur Zeile für Zeile.

Zum Hintergrund:
Es geht um das Erstellen von Rechnungen. Ich will dem Kunden, der mein
Programm kauft, die Möglichkeit geben, seine Rechnung frei zu gestalten.
Er soll alles, was Aufbau und Formatierung anbelangt, in der
Word-Vorlage definieren, und das Programm macht daraus eine Rechnung. In
der Word-Vorlage steht also bei meinem Kunden A z.B.:

|PosNr| |Kurztext| |EPreis| |Menge| |GPreis|
|Langtext| |Eh|

und bei meinem Kunden B z.B.:

|PosNr| |Kurztext| |GPreis|
|Langtext|
|Menge| |Eh| á |EPreis|

(Die Spalteneinteilung mußt Du Dir hier denken)
Die in |Name| sind die Textmarken, die dann in jeder Zeile anders
ausgefüllt werden.
Dazu die Formatierung: |Kurztext| und |GPreis| könnten z.B. fett
geschrieben werden.

Daß dann noch die Summen- und MWSt.-Zeilen definiert werden müssen, ist
kein Problem.

> Zur Übernahme der Formatierungen wirst Du vermutlich (ich habe von Word
> auch keine Ahnung) die Formateinstellungen zwischenspeichern müssen, um sie
> auf den ersetzten Text danach direkt wieder anwenden zu können.
>
> Als Programmierung sähe das so aus:
> dim i As Long
> Wenn es sich um eine einheitliche Tabelle handelt,
> For i = 1 To Zeilenanzahl
> Speichere das Format von @@TM@@
> Ersetze in der Zeile i den Text von @@TM@@ durch 'Ersatz & i'
> Übertrage das gespeicherte Format auf den ersetzten Text
> Next i
>
> Jetzt müsste man das "nur" noch nach Word-VBA umwandeln ;-)

Beim Format gibt es wahrscheinlich X Möglichkeiten, und das Programm
sollte möglichst wenig davon wissen müssen.

Lothar Geyer

Thomas Gahler

unread,
Feb 1, 2007, 2:17:46 AM2/1/07
to
Hallo Lothar


>> Dann sehe ich höchstes die Möglichkeiten von Platzhalten im Text. So
>> ungefähr so
>> "Hallo, meine Name is @@@NAME@@@. Und wie heisst du?"
>> Weisst du was ich meine? Das kannst du sicher duplizieren, aber jetzt
>> hast du einfach zig mal @@@NAME@@@ in der Tabelle und was jetzt?
>
> Angenommen in Spalte 1 ist die Textmarke "TM01" (@@@TM01@@@) und in Spalte
> 3 ist die Textmarke "TM03" (@@@TM03@@@), dann könnte ich doch
> - in Zeile 1 die Textmarke TM01 mit ABC1 ersetzen
> - in Zeile 2 die Textmarke TM01 mit ABC2 ersetzen
> usw.
> Nur könnte ich ín diesem Fall keine Textmarken verwenden und könnte keine
> Formatierungen mit übernehmen. Oder sehe ich das falsch?
>
>> Mit Sucher/Ersetzen kannst du gleich alle mit dem gleichen Wert
>> ausstatten. Oder eben wie es Carsten macht, die Zellen ansprechen und
>> darin den Text ersetzen (.Range bestimmen) oder Suchen/Ersetzen in diesem
>> .Range anwenden.
>
> Das ist es ja was ich nicht will. Die einzusetzenden Texte sollen ja in
> jeder Zeile anders sein können.

Aber du hast das 'oder' hoffentlich gesehen.


Ich frage mich nur wie du denn deine Platzhalter neu nummerieren willst und
weshalb? Aber egal ob du zuerst alle Zeilen einfügst und dann befüllst
(jetzt musst du neu nummerieren) oder du nur eine Zeile einfügst und dies
befüllst und dann die nächste Zeile usw. (dann musst du nicht nummerieren).
Du suchst wohl nach der .FormattedText-Eigenschaft.
Lass mal den nachstehenden Code über deine .dot laufen, dann siehst du was
möglich ist.


Sub Demo()
Dim doc As Word.Document
Dim tbl As Word.Table
Dim rng As Word.Range
Dim rng2 As Word.Range

Set doc = ActiveDocument
Set tbl = doc.Tables(2)
Set rng = tbl.Rows(2).Range

Set rng2 = ActiveDocument.Range
rng2.SetRange rng2.End, rng2.End

rng2.FormattedText = rng.FormattedText
End Sub

> In der Antwort auf Carsten's Posting habe ich einen Link zu einem Dokument
> angegeben, in dem ich das verdeutlicht habe.

Habe deine Datei angeschaut

Carsten Sekulla

unread,
Feb 1, 2007, 3:33:50 AM2/1/07
to

>
> Ich habe ein Beispiel unter
> http://www.edv-berater-online.de/test/TabellenTest.dot zur Verfügung
> gestellt.
>
> Lothar Geyer
Ah,
du willst noch etwas Text, nah dann kopiere die Zeile und merke dir die
Position der Textmarke in der Zelle.

Wenn du den Index der Textmarken brauchst (ich würde nach dem Namen der TM
gehen), kannst du dir diesen
auch noch in ein Array basteln.


cu CS

Private Sub main()
Dim oWW As Word.Application


Dim oDoc As Word.Document
Dim oTab As Word.Table
Dim oTM As Word.Bookmark

Dim oCell As Word.Cell
Dim sTM2CellCol() As String
Dim lTM2CellChar() As Long

Dim i As Long
Dim j As Long

Dim lRowIndex As Long
Dim N As Long

N = 3

Set oWW = New Word.Application
oWW.Visible = True
oWW.WindowState = wdWindowStateNormal
' letzte Zeile der Trabelle: erste Datenzeile mit Textmarken


Set oDoc = oWW.Documents.Add("C:\Dokumente und

Einstellungen\sekulla\Desktop\TabellenTest.dot")
Set oTab = oDoc.Tables(1) 'ggf andere Tabelle auswählen
If oTab.Range.Bookmarks.Count > 0 Then
ReDim sTM2CellCol(1 To oTab.Columns.Count) As String
ReDim lTM2CellChar(1 To oTab.Columns.Count) As Long

lRowIndex = oTab.Rows.Count
For Each oTM In oTab.Rows(lRowIndex).Range.Bookmarks
Set oCell = oTM.Range.Cells(1)
i = oCell.ColumnIndex
sTM2CellCol(i) = oTM.Name 'nur eine TM pro Zelle
lTM2CellChar(i) = -oTM.Range.StartOf(wdCell)
lTM2CellChar(i) = lTM2CellChar(i) + CLng(lTM2CellChar(i) > 0) + 1 '
Minimum 1
oTM.Range.Text = "X"
Set oCell = Nothing
Next
For i = lRowIndex To N + lRowIndex - 1
If i = lRowIndex Then
oTab.Rows(lRowIndex).Range.Copy
Else
oDoc.Range(oTab.Range.End, oTab.Range.End).Paste
End If
For j = LBound(sTM2CellCol()) To UBound(sTM2CellCol())


If Len(sTM2CellCol(j)) > 0 Then
'Hier kann auch was vernünftiges zugewiesen werden

oTab.Cell(i, j).Range.Characters(lTM2CellChar(j)).Text = _
"Ersetzt" & CStr(i - 1) & CStr(j)


End If
Next
Next
End If

oDoc.Content.Characters(1).Copy
Set oTab = Nothing
Set oDoc = Nothing
Stop
oWW.Quit wdDoNotSaveChanges

Carsten Sekulla

unread,
Feb 1, 2007, 9:14:14 AM2/1/07
to

"Carsten Sekulla" <carsten....@Spam.medizin.uni-halle.de> schrieb im
Newsbeitrag news:uDIn4udR...@TK2MSFTNGP02.phx.gbl...

>
>>
>> Ich habe ein Beispiel unter
>> http://www.edv-berater-online.de/test/TabellenTest.dot zur Verfügung
>> gestellt.
>>
>> Lothar Geyer
> Ah,
> du willst noch etwas Text, nah dann kopiere die Zeile und merke dir die
> Position der Textmarke in der Zelle.

Da fällt mir noch eine Lösung ein, wenn deine Daten aus irgend einer
Datenquelle stammen (MDB, XLS)
Aus der Tabelle ein Serien(brief)-Verzeichnis zu machen:
Ist für große Tabellen viel performanter.
cu CS

Private Sub main_2()


Dim oWW As Word.Application
Dim oDoc As Word.Document

Dim oCat As Word.Document


Dim oTab As Word.Table
Dim oTM As Word.Bookmark

Dim sXLS As String
Dim sSQL As String

sXLS = "C:\Dokumente und Einstellungen\sekulla\Desktop\Mappe1.xls"

Set oWW = New Word.Application
oWW.Visible = True
oWW.WindowState = wdWindowStateNormal
' letzte Zeile der Trabelle: erste Datenzeile mit Textmarken
Set oDoc = oWW.Documents.Add("C:\Dokumente und
Einstellungen\sekulla\Desktop\TabellenTest.dot")
Set oTab = oDoc.Tables(1) 'ggf andere Tabelle auswählen

If oTab.Rows(oTab.Rows.Count).Range.Bookmarks.Count > 0 Then
Set oCat = oWW.Documents.Add
oTab.Rows(oTab.Rows.Count).Range.Cut
oCat.Content.Paste
oCat.MailMerge.MainDocumentType = wdCatalog
For Each oTM In oCat.Tables(1).Rows(1).Range.Bookmarks
oCat.MailMerge.Fields.Add Range:=oTM.Range, Name:=oTM.Name
Next
sSQL = "Select * from `Tabelle1$`"
oCat.MailMerge.OpenDataSource Name:=sXLS, ReadOnly:=True, _
Connection:="DSN=Excel-Files;" &
_
"DriverId=790;" & _
"MaxBufferSize=2048;" & _
"PageTimeout=5;", _
SQLStatement:=sSQL
oCat.MailMerge.Destination = wdSendToNewDocument
DoEvents
oCat.MailMerge.Execute False
DoEvents
oWW.Documents(1).Tables(1).Range.Copy
oDoc.Range(oTab.Range.End, oTab.Range.End).Paste
oWW.Documents(1).Close wdDoNotSaveChanges
oCat.Close wdDoNotSaveChanges


End If
oDoc.Content.Characters(1).Copy
Set oTab = Nothing
Set oDoc = Nothing
Stop
oWW.Quit wdDoNotSaveChanges
Set oWW = Nothing
End Sub

Mappe1 Tabelle1:
Textmarke1 Textmarke3 Textmarke4
a b c
d e f
g h i


Lothar Geyer

unread,
Feb 1, 2007, 9:29:40 AM2/1/07
to
Hallo Carsten,

Carsten Sekulla schrieb:
> ...


> Da fällt mir noch eine Lösung ein, wenn deine Daten aus irgend einer
> Datenquelle stammen (MDB, XLS)
> Aus der Tabelle ein Serien(brief)-Verzeichnis zu machen:
> Ist für große Tabellen viel performanter.
> cu CS

Ist für mich weniger interessant. Trotzdem Danke für den Tipp. Kann ja
vielleicht jemand anders in der NG noch gebrauchen ;-)

Lothar Geyer

Lothar Geyer

unread,
Feb 1, 2007, 10:22:25 AM2/1/07
to
Hallo Carsten,

ich habe Deine Proc zwar am Laufe, aber ich verstehe sie nicht. Kannst
Du mir bitte erläutern:

> For Each oTM In oTab.Rows(lRowIndex).Range.Bookmarks
> Set oCell = oTM.Range.Cells(1)
> i = oCell.ColumnIndex
> sTM2CellCol(i) = oTM.Name 'nur eine TM pro Zelle
> lTM2CellChar(i) = -oTM.Range.StartOf(wdCell)
> lTM2CellChar(i) = lTM2CellChar(i) + CLng(lTM2CellChar(i) > 0) + 1

> oTM.Range.Text = "X"
> Set oCell = Nothing
> Next

Was macht diese Schleife, speziell das StartOf?

Meine "Referenzzeile" ist immer die zweite. Danach können noch andere
(Summen-)Zeilen kommen. Wie muß ich das "Paste" ändern, damit die neue
Zeile immer an der richtigen Position eingefügt wird?

> For i = lRowIndex To N + lRowIndex - 1
> If i = lRowIndex Then
> oTab.Rows(lRowIndex).Range.Copy
> Else
> oDoc.Range(oTab.Range.End, oTab.Range.End).Paste
> End If
> For j = LBound(sTM2CellCol()) To UBound(sTM2CellCol())
> If Len(sTM2CellCol(j)) > 0 Then
> 'Hier kann auch was vernünftiges zugewiesen werden
> oTab.Cell(i, j).Range.Characters(lTM2CellChar(j)).Text = _
> "Ersetzt" & CStr(i - 1) & CStr(j)
> End If
> Next
> Next

Was macht das folgende Statement?

> oDoc.Content.Characters(1).Copy

Sorry für die kleinlichen Fragen, aber die Objekt-Struktur von Word ist
mir noch ein Geheimnis.

Lothar Geyer

Thomas Gahler

unread,
Feb 1, 2007, 11:08:32 AM2/1/07
to
Hallo Lothar
Hallo Carsten,


Sorry, aber wieso arbeitet ihr immer noch mit Copy/Paste und versaut dem
Anwender die Zwischenablage, wenn ich doch schon den .FormattedText ins
Spiel gebracht habe. Oder habe ich was verpasst?

Lothar Geyer

unread,
Feb 1, 2007, 11:54:40 AM2/1/07
to
Hallo Thomas,

Thomas Gahler schrieb:

> ...


> Sorry, aber wieso arbeitet ihr immer noch mit Copy/Paste und versaut dem
> Anwender die Zwischenablage, wenn ich doch schon den .FormattedText ins
> Spiel gebracht habe. Oder habe ich was verpasst?

von meiner Seite habe eher ich was verpaßt, weil mir solche Sachen wie
.FormattedText unbekannt sind und ich daher auch nicht weiß, wie und was
man damit macht. Prinzipiell ist Dein Einwand natürlich berechtigt. Je
weniger Nebeneffekte, desto besser.

Zu der Sub von Carsten hatte ich ja auch noch ein paar Verständnisfragen...

Lothar Geyer

Carsten Sekulla

unread,
Feb 1, 2007, 1:17:27 PM2/1/07
to

"Lothar Geyer" <Lothar...@EDV-Berater-Online.de> schrieb im Newsbeitrag
news:52eeuuF...@mid.individual.net...

> Hallo Carsten,
>
> ich habe Deine Proc zwar am Laufe, aber ich verstehe sie nicht. Kannst Du
> mir bitte erläutern:
>
>> For Each oTM In oTab.Rows(lRowIndex).Range.Bookmarks
durchlaufe alle TM in der Zeile lRowIndex

>> Set oCell = oTM.Range.Cells(1)
>> i = oCell.ColumnIndex
suche den SpaltenIndex

>> sTM2CellCol(i) = oTM.Name 'nur eine TM pro Zelle
merke mir den Textmarkennamen
>> lTM2CellChar(i) = -oTM.Range.StartOf(wdCell)
Zähle die Zeichen bis zum Anfang der aktuellen Zelle

>> lTM2CellChar(i) = lTM2CellChar(i) + CLng(lTM2CellChar(i) > 0) + 1
Wenn 0 Zeichen (TM am Anfang) dann eine 1
>> oTM.Range.Text = "X"
lösche TM und setze ein Zeichen als Ersatz und zum Halten der Formatierung

> Meine "Referenzzeile" ist immer die zweite. Danach können noch andere
> (Summen-)Zeilen kommen. Wie muß ich das "Paste" ändern, damit die neue
> Zeile immer an der richtigen Position eingefügt wird?

lRowIndex = oTab.Rows.Count sucht die letzte Zeile, also bei dir
lRowIndex = 2

>> oDoc.Content.Characters(1).Copy
belegt die Zwischenablage mit nur einem Zeichen

cu CS

Option Explicit

Private Sub main()
Dim oWW As Word.Application
Dim oDoc As Word.Document
Dim oTab As Word.Table
Dim oTM As Word.Bookmark
Dim oCell As Word.Cell
Dim sTM2CellCol() As String
Dim lTM2CellChar() As Long

Dim i As Long
Dim j As Long
Dim lRowIndex As Long
Dim N As Long

N = 3
lRowIndex = 2 'auf Wunsch

Set oWW = New Word.Application
oWW.Visible = True
oWW.WindowState = wdWindowStateNormal
' letzte Zeile der Trabelle: erste Datenzeile mit Textmarken
Set oDoc = oWW.Documents.Add("C:\Dokumente und

Einstellungen\carsten\Desktop\TabellenTest.dot")


Set oTab = oDoc.Tables(1) 'ggf andere Tabelle auswählen

If oTab.Rows(lRowIndex).Range.Bookmarks.Count > 0 Then


ReDim sTM2CellCol(1 To oTab.Columns.Count) As String
ReDim lTM2CellChar(1 To oTab.Columns.Count) As Long

For Each oTM In oTab.Rows(lRowIndex).Range.Bookmarks


Set oCell = oTM.Range.Cells(1)
i = oCell.ColumnIndex
sTM2CellCol(i) = oTM.Name 'nur eine TM pro Zelle
lTM2CellChar(i) = -oTM.Range.StartOf(wdCell)
lTM2CellChar(i) = lTM2CellChar(i) + CLng(lTM2CellChar(i) > 0) + 1

'Minimum 1


oTM.Range.Text = "X"
Set oCell = Nothing
Next

For i = lRowIndex + 1 To N + lRowIndex - 1 ' Tabelle erweitern
oDoc.Range(oTab.Rows(lRowIndex).Range.End,
oTab.Rows(lRowIndex).Range.End).FormattedText = oTab.Rows(lRowIndex).Range
Next


For i = lRowIndex To N + lRowIndex - 1

For j = LBound(sTM2CellCol()) To UBound(sTM2CellCol())
If Len(sTM2CellCol(j)) > 0 Then

'Hier kann auch was vernünftiges zugewiesen werden, das X
wird ersetzt


oTab.Cell(i, j).Range.Characters(lTM2CellChar(j)).Text = _
"Ersetzt" & CStr(i - 1) & CStr(j)
End If
Next
Next

Carsten Sekulla

unread,
Feb 1, 2007, 1:19:23 PM2/1/07
to

"Thomas Gahler" <wurze...@SPAM.bluewin.ch> schrieb im Newsbeitrag
news:ulL85sh...@TK2MSFTNGP05.phx.gbl...

> Hallo Lothar
> Hallo Carsten,
>
>
> Sorry, aber wieso arbeitet ihr immer noch mit Copy/Paste und versaut dem
> Anwender die Zwischenablage, wenn ich doch schon den .FormattedText ins
> Spiel gebracht habe. Oder habe ich was verpasst?

Hi Thomas
weil ich mir die Zeile ohne die hinzuzufügenden Daten merken wollte,
Jetzt habe ich aber eine Möglichkeit gesehen ohne Clipboard.
cu CS


Carsten Sekulla

unread,
Feb 2, 2007, 1:18:23 AM2/2/07
to
> oDoc.Content.Characters(1).Copy
Ups, brauchts du dank Thomas nicht mehr
cu CS


Thomas Gahler

unread,
Feb 2, 2007, 1:31:02 AM2/2/07
to
Hallo Lothar


> von meiner Seite habe eher ich was verpaßt, weil mir solche Sachen wie
> .FormattedText unbekannt sind und ich daher auch nicht weiß, wie und was
> man damit macht.

dann lass den Code im Posting vom 01.02.07 08:17 mal in deiner Demo.dot
laufen, dann siehst du was damit abgeht.

0 new messages