Home
VB- und VBA-Tipps
Herrsching


von Norbert Hahn

Ich habe versucht, hier ein paar Tipps oder Probleme bei der
Programmierung aufzuzeigen, die nicht in jedem Buch oder auf
jeder Tipp-Seite zu finden sind. Es sind sicher nicht die weltbesten
Tipps, aber die Erkenntnisse haben mich zum Teil leider sehr viel
Zeit gekostet.
Ich würde mich freuen, wenn ich Rückmeldungen über den
'Wahrheitsgehalt' meiner Aussagen bzw. über andere und bessere
Lösungsmöglichkeiten erhalten würde 


Inhalt:

  • Vermeidung von 'Mischen' von Word-Ausdrucken an Netzwerkdruckern
  • Einstellen der Druckoptionen von Word 97 ohne Ausdruck
  • Seriendruck und verknüpfte Datenbank
  • Dateieigenschaften lesen mit dsofile.dll oder Fpropset.dll
  • Word als E-mail-Editor bei Outlook und Fehler bei VB-Word-Automation
  • Bildschirm-Hardcopy (einmal anders)


'Mischen' von Word-Ausdrucken an Netzwerkdruckern verhindern

Problemstellung:

Etwa 20-30 User drucken 'ihre' Schreiben auf einem Netzwerkdrucker
aus. Dabei werden über ein VB-Programm für einen Vorgang zunächst
alle Original-Schreiben ausgedruckt (können durchaus 10 und mehr sein).
Danach werden die Entwürfe für die Akten ausgedruckt. Da jedes
Schreiben in einem eigenen Druckvorgang ausgedruckt wird, könnte
es vorkommen, daß die Schreiben eines Vorgangs mit den Schreiben
eines anderen Vorgangs (eines anderen Users) am Drucker durch-
einander 'herauskommen' (gemischt werden), da Windows einfach in
der Reihenfolge des Eingangs die Druckaufträge ausführt.

Lösung:

Alle Schreiben eines Vorgangs werden zunächst in eine Druckdatei
gedruckt, wobei das erste Schreiben die Druckdatei neu erstellt und
jedes weitere (auch die nachfolgenden Entwürfe) an die bestehende
Druckdatei angehängt werden. Anschließend wird die Druckdatei als
Ganzes an einen Anschluß (z.B. 'lpt1') kopiert. Eine Mischung mit
anderen Vorgängen am Drucker erfolgt nicht mehr.

z.B.:

_____Set oDruckdialog = oWord.Dialogs(wdDialogFilePrint)
_____With oDruckdialog
_______.Update
_______.AppendPrFile = 0 '(0=File-Inhalt überschreiben; 1=an File anhängen)
_______.Range = 0 'Seitenbereich:Alles
_______.PrToFileName = InDieseDateiSchreiben$
_______.NumCopies = WieOft%
_______.Order = 0 'alle im Bereich
_______.PrintToFile = 1
_______.Collate = 1 'Sortieren
_______.filename = "" 'Aktives Dokument
_______.Execute
_____End With
_____.....
_____.....
_____FileCopy InDieseDateiSchreiben$, "lpt1"

Aber Achtung:

Noch unter Win 3.11 war das Kopieren an z.B. 'lpt1'
kein Problem. Unter Win NT 4.0 (meine Plattform) müssen vorher
auf jedem PC über den Befehl 'net use' die entsprechenden Drucker
als Ziel des Kopierbefehl eingestellt werden.

z.B.:

_____ Net use lpt1: SERVERNAMEDRUCKERNAME /persistent:yes




Einstellen der Druckoptionen ohne Ausdruck

Problemstellung:

Einige Druckoptionen in Word 97 lassen sich nur durch einen
anschließenden Druckbefehl einstellen. Beispielsweise läßt sich
die im vorherigen Beispiel notwendige Option 'Drucken in Datei'
nicht ohne einen Ausdruck zurückstellen (bzw. ausschalten).

Lösung:

Drucken Sie nach Einstellung der gewünschten Optionen die Seite '0'
aus. "Quatsch" werden Sie sagen, die Seite '0' gibt es nicht. Sie haben
natürlich recht, die Seite '0' gibt es wirklich nicht; deshalb wird sie auch
nicht gedruckt. Aber: Es kommt kein Fehler und die Druckoptionen
sind anschließend in der gewünschten Form gespeichert.

z.B.:

_____With oWord
________.Documents.Add
________Set oDruckdialog = .Dialogs(wdDialogFilePrint)
________With oDruckdialog
___________.Update
___________.AppendPrFile = 1
___________.Range = wdPrintRangeOfPages
___________.Pages = "0"    '= Seite 0
___________.NumCopies = 1
___________.PrintToFile = 0
___________.filename = ""
___________.Execute
________End With
_____End With

Zurück zum Seitenbeginn



Seriendruck und verknüpfte Datenbank

Problemstellung:

Eigentlich ist die Seriendruck-Funktion von Word 97 ja eine ganz
nützliche Sache. Leider kommt man aber bei vermeintlich normalen
bzw. häufig vorkommenden Problemen bereits an die Grenzen.
Beispiel: Sie haben zwei Tabellen. In der einen Tabelle stehen Adressen-
daten mit eindeutigen Nummern für jede Adresse. In der anderen Tabelle
stehen durcheinander Daten zu den verschiedenen Adressen. Die
Datensätze sind widerum mit den Adressennummern gekennzeichnet.
Sie möchten einen Serienbrief an alle Adressen der ersten Tabelle
erstellen, wobei alle die die jeweiligen Adressen betreffenden Daten-
sätze der zweiten Tabelle im Schreiben enthalten sein sollen.
Eigentlich nicht möglich !!!

z.B.:

Tabelle 'AdrTab':
  Nummer Name Ort Straße
  234 Firma Meier 12345 Ortsen Meierstr.1
  87 Firma Franz 98767 Berlein Franzenstr.5

Tabelle 'ListTab':
  Nummer Datum Ware Höhe
  87 15.01.2000 Bier 354,66
  87 18.01.2000 Wein 788,99
  234 25.03.2000 Wein 100,87
  87 21.06.2000 Bier 211,98
  234 22.09.2000 Wein 154,98

Lösung:

Über die Assistenten ist dies grundsätzlich nicht möglich.
Dies geht nur mit entsprechenden manuellen Ergänzungen,
die auch mit VBA-Code nachgebildet werden können.

  • Serienbrief erstellen mit Datenquelle 'AdrTab'
  • Seriendruckfelder einfügen; z.B. 'Nummer'
  • In Hauptdokument 'Datenbank einfügen' (Symbolleiste 'Datenbank')
  • Als Datenbank dabei 'ListTab' angeben
  • Als Abfrageoption 'Nummer gleich 234' eingeben
  • (Seriendruckfeld 'Nummer' kann als Option nicht eingegeben werden)
  • Die Datenbank als Feld einfügen
  • Datenbank im Dokument markieren und Feldfunktionen sichtbar machen
  • Den als Abfrageoption eingegebenen Wert '234' markieren
  • In die Markierung das Seriendruckfeld 'Nummer' einfügen

Ich gehe davon aus, dass die ersten sieben Punkte allgemein bekannt sind und nicht näher erklärt werden müssen.
Wenn man mit VBA dies nachvollziehen will, muß man wissen, daß
der vorläufig bei Abfrageoption eingegebene Wert (hier '234') ein
gültiger, in der Tabelle 'ListTab' vorhandene Wert sein muß. Sinnvoll
ist es hier, den ersten Wert des Seriendruckfeldes 'Nummer' der
Tabelle 'AdrTab' zu nehmen.



Dateieigenschaften lesen (dsofile.dll u. Fpropset.dll)

Problemstellung:

Über die Anwendung der beiden o.g. Dll's wurde bereits
ausführlich geschrieben.

Ein wohl eher unbekanntes Problem bei der Anwendung beider Dll's
tritt jedoch bei folgender Konstellation auf:

In einem Dokument (z.B. Word 97) wurde auf der ersten Seite eine
Bildschirm-Hardcopy bzw. ein großes Bitmap oder auch eine Tabelle eingefügt und das Dokument wurde mit der Option 'Vorschaugrafik speichern'
abgespeichert

Unter diesen Umständen wird beim Versuch, die Dateieigenschaften
zu lesen, eine Fehlermeldung angezeigt. Der Lesevorgang wird
abgebrochen

Lösung:

Eine echte Lösung dafür gibt es eigentlich nicht. Der Fehlerabbruch kann nur verhindert werden, wenn eine der beiden o.g. Bedingungen nicht erfüllt ist, d.h. wenn die Hardcopy, die Bitmaps oder die Tabelle benötigt wird, muß das Dokument ohne Vorschaugrafik abgespeichert werden




Fehler bei Word-Automation: Outlook u. E-Mail-Editor

Problemstellung:

Wird in Outlook 'Word 97 als E-Mail-Editor' verwendet, führt dies dazu,
daß die Word-Automation von VB 5 aus nicht funktioniert. Es hat den
Anschein, daß Word von Outlook 'blockiert' wird

Lösung:

Die im folgenden vorgestellte Lösung (Code-Ausschnitte) ist zwar nicht
gerade optimal, aber immerhin hat sie bei mir funktioniert.
Zunächst muß überprüft werden, ob WordMail läuft, da in diesen
Fällen die 'Blockierung' erfolgt.

Dies geschieht hier mit einer Funktion:
_____Function isWordMail(objWord) As Boolean
________' wenn Fokus in einem WordMail Header
________' (To, CC or Subject line)
________If objWord.Application.FocusInMailHeader Then
___________isWordMail = True
___________Exit Function
________End If
________' wenn nicht in einem WordMail Header,
________' aber Fokus ist in der WordMail-Message
________If objWord.Selection.Information(wdInWordMail) Then
___________isWordMail = True
________End If
_____End Function


Wenn isWordMail=true dann wird versucht, mit folgendem Code
Outlook 'umzustellen':
_____Private Sub OutlookUmstellen()
________'Outlook-Automation beginnen
________Dim oOutl As Outlook.Application
________Set oOutl = GetObject(, "Outlook.Application")
________Set oNameSpace = oOutl.GetNamespace("MAPI")
________Set meinOrdner = _
________oNameSpace.GetDefaultFolder(olFolderInbox)
________'Zwei neue Nachrichten erstellen und anzeigen
________Set meinelement = meinOrdner.Items.Add
________Set meinelement1 = meinOrdner.Items.Add
________meinelement.Display
________meinelement1.Display
________'zwei Nachrichten ohne Änderung wieder löschen
________meinelement1.Delete
________meinelement.Delete
________Set meinelement1 = Nothing
________Set meinelement = Nothing
________Set oOutl = Nothing
_____End Sub




Bildschirm-Hardcopy mit VB/VBA (einmal anders)

Problemstellung:

Eine Bildschirm-Hardcopy in die Zwischenablage zu kopieren ist ein
häufiger Punkt in Newsgroups. Normalerweise wird bei den Antworten
die API bemüht. Lösung:

Wenn Word 97 verwendet wird, gibt es aber immer noch die
Möglichkeit, den 'SendKeys'-Befehl einzusetzen. Halt, halt - nicht gleich
wegklicken. Quatsch, werden Sie sagen, der 'SendKeys'-Befehl
funktioniert nicht. Schließlich kann man das überall nachlesen - und zwar
in jedem Standardwerk und in allen NG's und FAQ's. Glauben Sie's mir:
Es stimmt alles nicht. Zwar ist richtig, daß 'SendKeys "{PRTSC}"' nicht
funktioniert, auch nicht unter Word 6 mit WordBasic.  

Unter Verwendung des WordBasic-Objektes geht es aber anders:

_____WordBasic.SendKeys "%{1068}"

Dies funktioniert auch mit Word-Automation von VB 5 aus




Zuletzt bearbeitet: 29.April 2006 (ohne inhaltliche Änderung)

Top