Ein After_Print-Event ertricksen

Hallo liebe Wissenden!

Schon seit letzter Woche, verfolgt mich folgendes Problem:

Die Excel-Datei (Excel 2003), um die es geht, ist ein Bestellformular. Die Tabelle, in der das alles drin steht, hat einen Blattschutz mit Passwort, damit die ‚Ausfüller‘ nur etwas in bestimmte Zellen schreiben (und auch nur diese auswählen) können. Das sind die Zellen für die Mengenangabe.

Da das ganze Bestellformular 3 Seiten hat, in der Regel aber nur einige wenige Artikel davon auch tatsächlich geordert werden, sollen nun nur die entsprechenden Zeilen ausgedruckt werden. Außerdem die ‚Kopfzeilen‘ und eine Schlusszeile (Gesamtbetrag…)

Um das ganze zu realisieren, kopiere ich im Before_Print-Event den Inhalt der Tabelle einfach in eine andere rüber. In der anderen Tabelle habe ich eine ‚Steuerspalte‘, die ebenfalls in dem Event aktualisiert wird. Also wenn eine Menge angegeben wurde, dann kommt in die entsprechende Zelle der Steuerspalte ein Kennzeichen.

Wenn ich das durchlaufen habe, setze ich einen Autofilter, der mir alle Zeilen mit dem Kennzeichen anzeigen.

So weit so gut.

Nun hätte ich aber ganz gerne die Zusatztabelle wieder geleert, NACH dem Druck. Und außerdem sollte der Fokus wieder auf der Ausgangszelle der Originaltabelle stehen, damit der Ausfüller wieder da ist, wo er quasi herkommt.
Allerdings gibt es ja kein After_Print-Event.

Dass man sich das zusammentricksen kann, habe ich zwar auch schon herausgefunden, aber genau hier habe ich so meine Probleme:

  1. Variante:
    Der eigentliche Druckauftrag wird gecancelt (in Before_Print -> Cancel = true) und manuell noch mal angestoßen. Danach kommen dann die ‚After_Print‘-Anweisungen.
    ABER: a) Es wird dann auch gedruckt, wenn ich nur auf ‚Seitenvorschau‘ gehe.
    b) Es wird kein Drucker-Dialog mehr angezeigt, falls der Druck über ‚Datei -> Drucken‘ angestoßen wird. Das Verhalten soll hier aber genau sein wie vorher. Also beim klicken auf das Druckersymbol einfach ausdrucken, beim Drucken über den Menüpunkt MIT Drucker-Dialog.
    Ich habe aber nichts gefunden, wie man feststellen kann, wo nun der Druck-Befehl her kommt. :frowning:

  2. Variante:
    Am Ende von Before_Print via Application.OnTime … in einem Modul eine Funktion mit After_Print-Befehlen aufrufen.
    Was aber etwas unsicher zu sein scheint - weil es eben alles auf Zeitsteuerung basiert. Zu hoch darf ich den Zeitindex also nicht einstellen, weil sonst evtl. schon jemand etwas in der plötzlich sichtbar gewordenen Tabelle gepfuscht haben könnte, die Datei vielleicht sogar geschlossen hat??
    Zu niedrig aber auch auf gar keinen Fall, denn wie ich die Sache sehe, nimmt der Drucker sonst diese kurzfristigen Änderungen nicht wahr, weil sie schon wieder rückgängig gemacht sind und druckt doch alles.

Tja,… und nun bin ich ratlos und wende mich an Euch.

Weiß hier jemand Rat, was ich noch tun könnte? Besonders in Hinsicht auf Variante 1 vielleicht mit dem Erkennen des Unterschieds zwischen dem DruckButton und Menü-Druck, wäre ich wirklich froh, wenn jemand noch eine Idee hätte.

Im Voraus vielen Dank schon mal - und wenn’s allein für das Lesen des langen Textes ist. :smile:

Lg Tally

Hi Tally,

alles oberhalb von „So weit so gut“ in deinem Beitrag ist doch gelöst oder habe ich schon da was nicht kapiert?

Nun hätte ich aber ganz gerne die Zusatztabelle wieder
geleert, NACH dem Druck.

Ja und, dann leer sie doch, worksheets(3).usedrange.clear

Und außerdem sollte der Fokus wieder
auf der Ausgangszelle der Originaltabelle stehen, damit der
Ausfüller wieder da ist, wo er quasi herkommt.

Wieso bewegt sich der Fokus überhaupt, bzw, warum wechselt die aktive Zelle?

Allerdings gibt es ja kein After_Print-Event.

richtig.

  1. Variante:
    Der eigentliche Druckauftrag wird gecancelt (in Before_Print
    -> Cancel = true) und manuell noch mal angestoßen. Danach
    kommen dann die ‚After_Print‘-Anweisungen.
    ABER: a) Es wird dann auch gedruckt, wenn ich nur auf
    ‚Seitenvorschau‘ gehe.

Warum das denn, Seitenvoschau heißt Seitenvorshau, warum sollte da Excel drucken, außer du klickst auf Drucken?

b) Es wird kein Drucker-Dialog mehr angezeigt, falls der Druck
über ‚Datei -> Drucken‘ angestoßen wird. Das Verhalten soll
hier aber genau sein wie vorher. Also beim klicken auf das
Druckersymbol einfach ausdrucken, beim Drucken über den
Menüpunkt MIT Drucker-Dialog.

Also, beim KLick auf das Druckersymbol (in Excel oder in der Seitenvorschau?) direkt ausdrucken,
beim Klick auf Datei–Drucken via Druckerdialog drucken.
Müßte zu machen sein *denk*

Ich habe aber nichts gefunden, wie man feststellen kann, wo
nun der Druck-Befehl her kommt. :frowning:

Irgendeinen Weg wird man da schon finden, aber erstmal ist mir noch einiges andere schleierhaft.

  1. Variante:
    Am Ende von Before_Print via Application.OnTime … in einem
    Modul eine Funktion mit After_Print-Befehlen aufrufen.
    Was aber etwas unsicher zu sein scheint - weil es eben alles
    auf Zeitsteuerung basiert. Zu hoch darf ich den Zeitindex also
    nicht einstellen, weil sonst evtl. schon jemand etwas in der
    plötzlich sichtbar gewordenen Tabelle gepfuscht haben könnte,
    die Datei vielleicht sogar geschlossen hat??

Ich sehe da keine notwendigkeit für einen Timer. Mal sahuen, vielleicht gibt es Wege das Blatt solange zu sperren bis der Drucker nicht mehr busy ist, API oder so.

Zu niedrig aber auch auf gar keinen Fall, denn wie ich die
Sache sehe, nimmt der Drucker sonst diese kurzfristigen
Änderungen nicht wahr, weil sie schon wieder rückgängig
gemacht sind und druckt doch alles.

Willst du sich schon Drucker befindliche Druckseiten nochmal abändern?

Tja,… und nun bin ich ratlos und wende mich an Euch.

Wenn das alles so ist wie ich es mir gerade zusammenreime, bzw. nicht hinkriege mir das zusammenzureien bin ich auch sehr ratlos :smile:

Weiß hier jemand Rat, was ich noch tun könnte? Besonders in
Hinsicht auf Variante 1 vielleicht mit dem Erkennen des
Unterschieds zwischen dem DruckButton und Menü-Druck, wäre ich
wirklich froh, wenn jemand noch eine Idee hätte.

Das ist mit das Einzigste was ich verstand, ja, das ist machbar.

Gruß
Reinhard

Hallo Tally,

Die Excel-Datei (Excel 2003), um die es geht, ist ein
Bestellformular. Die Tabelle, in der das alles drin steht, hat
einen Blattschutz mit Passwort, damit die ‚Ausfüller‘ nur
etwas in bestimmte Zellen schreiben (und auch nur diese
auswählen) können. Das sind die Zellen für die Mengenangabe.

Da das ganze Bestellformular 3 Seiten hat, in der Regel aber
nur einige wenige Artikel davon auch tatsächlich geordert
werden, sollen nun nur die entsprechenden Zeilen ausgedruckt
werden. Außerdem die ‚Kopfzeilen‘ und eine Schlusszeile
(Gesamtbetrag…)

Wäre das möglich, das ganz anders aufzubauen?
Wenn in dem Formular tatsächlich nur wenige Zeilen ausgefüllt werden, könnte man das doch auch mit einer Gültigkeitsliste lösen. Du bereitest in dem Formular entsprechend viele Zeilen vor und hast immer nur 1 Seite zu drucken, gleich ob 2 oder 20 Zeilen gefüllt sind.
Vba bräuchtest du dann nicht.

Gruß
Marion

Hallo Reinhard!

Erst einmal vielen Dank für Deine Antwort - da seh ich zumindest schon mal Licht am Ende des Tunnels. :wink:

alles oberhalb von „So weit so gut“ in deinem Beitrag ist doch
gelöst oder habe ich schon da was nicht kapiert?

Das stimmt schon Mal. :smile: Da habe ich mich alles in allem wohl zu umständlich ausgedrückt. Tschuldigung…

Und außerdem sollte der Fokus wieder
auf der Ausgangszelle der Originaltabelle stehen, damit der
Ausfüller wieder da ist, wo er quasi herkommt.

Wieso bewegt sich der Fokus überhaupt, bzw, warum wechselt die
aktive Zelle?

Ich hatte bisher einfach die gerade aktive Tabelle ausgedruckt. Daher war ich zum Zeitpunkt des Drucks immer in der Zusatztabelle.
Das ist ja auch der Hauptgrund, warum ich NACH dem Drucken, die Änderungen für’s Drucken alle wieder rückgängig machen möchte. (Das rückgängig machen selbst, klappt auch inzwischen.)

Warum das denn, Seitenvoschau heißt Seitenvorshau, warum
sollte da Excel drucken, außer du klickst auf Drucken?

Hm,… also wenn ich auf Seitenvorschau (das Icon mit dem Blatt und der Lupe) klicke, wird das Before_Print-Event ausgelöst. Warum, weiß ich leider auch nicht. :frowning:
Jedenfalls, wenn ich den eigentlichen Druck in Before_Print abbreche, um ihn dort manuell nochmal anzustoßen, wird dann auch bei der Seitenvorschau gedruckt.
Ich hoffe, das war jetzt verständlicher??

b) Es wird kein Drucker-Dialog mehr angezeigt, falls der Druck
über ‚Datei -> Drucken‘ angestoßen wird. Das Verhalten soll
hier aber genau sein wie vorher. Also beim klicken auf das
Druckersymbol einfach ausdrucken, beim Drucken über den
Menüpunkt MIT Drucker-Dialog.

Also, beim KLick auf das Druckersymbol (in Excel oder in der
Seitenvorschau?) direkt ausdrucken,
beim Klick auf Datei–Drucken via Druckerdialog drucken.
Müßte zu machen sein *denk*

Genau. Aber weißt Du auch WIE das gehen könnte?
Ich hatte versucht, einen Unterschied herauszufinden, indem ich Makros aufgezeichnet habe. Eins bei dem ich den Druck über das Symbol ausgelöst habe, eins mit Datei -> Drucken.
Aber die Makros waren beide gleich. :frowning: Daher konnte ich keinen Unterschied feststellen.

Ich sehe da keine notwendigkeit für einen Timer. Mal sahuen,
vielleicht gibt es Wege das Blatt solange zu sperren bis der
Drucker nicht mehr busy ist, API oder so.

Das war auch nur die zweite Variante, die ich als Möglichkeit gefunden hatte, sich ein After_Print-Event zu ertricksen. Aber die erste wäre mir eindeutig lieber.

Willst du sich schon Drucker befindliche Druckseiten nochmal
abändern?

Nein, aber das passiert ‚versehentlich‘, wenn der Timer zu niedrig eingestellt ist.

Weiß hier jemand Rat, was ich noch tun könnte? Besonders in
Hinsicht auf Variante 1 vielleicht mit dem Erkennen des
Unterschieds zwischen dem DruckButton und Menü-Druck, wäre ich
wirklich froh, wenn jemand noch eine Idee hätte.

Das ist mit das Einzigste was ich verstand, ja, das ist
machbar.

Ein Lichtblick! Wie??

Liebe Grüße,

Tally

Hallo Marion!

Und vielen Dank für Deine Antwort! :smile:

Wäre das möglich, das ganz anders aufzubauen?

Grundsätzlich bin ich auch einer gänzlich anderen Lösung nicht abgeneigt.

Wenn in dem Formular tatsächlich nur wenige Zeilen ausgefüllt
werden, könnte man das doch auch mit einer Gültigkeitsliste
lösen. Du bereitest in dem Formular entsprechend viele Zeilen
vor und hast immer nur 1 Seite zu drucken, gleich ob 2 oder 20
Zeilen gefüllt sind.

Allerdings kann ich nie voraussehen, wieviele (unterschiedliche) Artikel jemand tatsächlich bestellt. Theoretisch (wenn auch sehr unwahrscheinlich) könnten es eben doch mal alle sein, oder zumindest so viele, dass man mehr als eine Seite bräuchte.
Hier muss ich also auf jeden Fall variabel bleiben.

Aber trotzdem Danke. Vielleicht hast Du - oder sonst jemand - ja noch eine Idee?

Liebe Grüße,

Tally

Hallo Tally.

Wer druckt denn die Datei? Nur Du, oder die, die auch das Formular ausfüllen?

Eigentlich sollte es möglich sein, eine benutzerdefinierte Symbolleiste und ein benutzerdefiniertes Menü für speziell Deine Datei zu programmieren und die „excel-gelieferten“ Druck-Buttons im Menü und in der vorhandenen Symbolleiste auf „Enabled = False“ bzw. sogar auf „Visible = False“ einzustellen.

Viele Grüße Carsten

Hallo Carsten!

Vielen Dank für Deine Antwort schon mal.

Wer druckt denn die Datei? Nur Du, oder die, die auch das
Formular ausfüllen?

Jeder der die Datei verwendet, soll sie auch drucken können. Und zwar so, wie man es bereits als ‚Standard‘ aus Excel gewöhnt ist - also über den vorhandenen Menüpunkt bzw. Button.

Oder gibt es eine Möglichkeit, einen eigenen Button so aussehen zu lassen, wie das Standard-Druck-Symbol und es auch dort zu positionieren?

Liebe Grüße,

Tally

Lösung für Seitenansicht
Hallo Tally,

kommst du damit klar?
Im Before_Print Code kannst du die globale Variable Druckart abfragen, sie sagt dir ob der Ausdruck „Normal“, „SeiteDatei“ oder „SeiteSymbol“ ausgeführt werden soll.
SeiteDatei heißt, es wurde Datei–Seitenansicht angeklickt, SeiteSymbol heißt, es wurde auf das Symbol für Seitenansicht geklickt.

Die Codezeilen für das Drucken fehlen noch.

**in Modul1

Option Explicit
Public DruckArt As String
'
Sub Umbelegen()
Dim cmbb As CommandBarButton
Set cmbb = Application.CommandBars("worksheet menu bar").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = "tt1"
Set cmbb = Application.CommandBars("standard").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = "tt2"
End Sub
'
Sub NormalDruck()
Dim cmbb As CommandBarButton
Set cmbb = Application.CommandBars("worksheet menu bar").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = ""
Set cmbb = Application.CommandBars("standard").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = ""
DruckArt = "Normal"
End Sub
'
Sub tt1()
DruckArt = "SeiteDatei"
ActiveSheet.PrintPreview
End Sub
'
Sub tt2()
DruckArt = "SeiteSymbol"
ActiveSheet.PrintPreview
End Sub

In dieseArbeitsmappe

Option Explicit
'
Private Sub Workbook\_Open()
Call Umbelegen
End Sub
'
Private Sub Workbook\_BeforeClose(Cancel As Boolean)
Call NormalDruck
End Sub
'
Private Sub Workbook\_BeforePrint(Cancel As Boolean)
'MsgBox DruckArt
Select Case DruckArt
 Case "SeiteDatei", "SeiteSymbol"
 Exit Sub ' oder auch Cancel=true
 Case "DruckDatei"
 ' mach dies
 Case "DruckSymbol"
 ' mach dies
 Case "Normal"
 'mach nix
End Select
End Sub

Gruß
Reinhard**

Lösung wie eben plus Drucken

Hallo Tally,

mit den ID-Nummern kenne ich mich nicht gut aus, möglicherweise hast du andere ID-Nummern, macht aber nix, lasse mal das Makro tt laufen, dann siehst du die IDs der Menüs/Symbole, ggfs dann die Nummern 109,4,2521 anpassen.

Modul1:

Option Explicit
Public DruckArt As String
'
Sub Umbelegen()
Dim cmbb As CommandBarButton
Set cmbb = Application.CommandBars("worksheet menu bar").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = "tt1"
Set cmbb = Application.CommandBars("standard").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = "tt2"
Set cmbb = Application.CommandBars("worksheet menu bar").FindControl(ID:=4, recursive:=True)
cmbb.OnAction = "tt3"
Set cmbb = Application.CommandBars("standard").FindControl(ID:=2521, recursive:=True)
cmbb.OnAction = "tt4"
End Sub
'
Sub NormalDruck()
Dim cmbb As CommandBarButton
Set cmbb = Application.CommandBars("worksheet menu bar").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = ""
Set cmbb = Application.CommandBars("standard").FindControl(ID:=109, recursive:=True)
cmbb.OnAction = ""
Set cmbb = Application.CommandBars("worksheet menu bar").FindControl(ID:=4, recursive:=True)
cmbb.OnAction = ""
Set cmbb = Application.CommandBars("standard").FindControl(ID:=2521, recursive:=True)
cmbb.OnAction = ""
DruckArt = "Normal"
End Sub
'
Sub tt1()
DruckArt = "SeiteDatei"
ActiveSheet.PrintPreview
End Sub
'
Sub tt2()
DruckArt = "SeiteSymbol"
ActiveSheet.PrintPreview
End Sub
'
Sub tt3()
DruckArt = "DruckDatei"
ActiveSheet.PrintOut
End Sub
'
Sub tt4()
DruckArt = "DruckSymbol"
ActiveSheet.PrintOut
End Sub
'
Sub tt()
Dim c
For Each c In Application.CommandBars("worksheet menu bar").Controls '("&Datei").Controls
 MsgBox c.ID & " - " & c.Caption
Next c
MsgBox "Datei fettig"
For Each c In Application.CommandBars("standard").Controls
 MsgBox c.ID & " - " & c.Caption
Next c
End Sub

In Diese Arbeitsmappe:

Option Explicit
'
Private Sub Workbook\_Open()
Call Umbelegen
End Sub
'
Private Sub Workbook\_BeforeClose(Cancel As Boolean)
Call NormalDruck
End Sub
'
Private Sub Workbook\_BeforePrint(Cancel As Boolean)
MsgBox DruckArt
Select Case DruckArt
 Case "SeiteDatei", "SeiteSymbol"
 Exit Sub ' oder auch Cancel=true
 Case "DruckDatei"
 ' mach dies
 Case "DruckSymbol"
 ' mach dies
 Case "Normal"
 'mach nix
End Select
End Sub

Gruß
Reinhard

1 „Gefällt mir“

Hallo Reinhard!!

Vielen, vielen Dank für diese Lösung und Deine tolle Hilfe! =) *strahl*

Ich habe es vorhin ausprobiert und funktioniert bestens!
Die ID-Nummern haben auch gestimmt - werde das aber hier noch weiter prüfen und ggf. die jeweiligen Nummern automatisch ermitteln lassen - das wird aber kein Problem sein. :smile:

Einzige Änderung die ich noch eingefügt habe, ist, den NormalDruck auch im Falle des Deaktivierens des Workbooks wiederherzustellen, bzw. das Umbelegen beim Aktivieren aufzurufen - falls jemand mehrere Excel-Dateien gleichzeitig aufhat und da was drucken möchte!

Echt spitze! Vielen Dank nochmal! =)

Liebe Grüße,
Tally