Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Bericht drucken mit Spoolerkontrolle HILFE -ggf. neuer Ansatz ab Beitrag 6?

Begonnen von wetlook, Januar 30, 2012, 17:48:26

⏪ vorheriges - nächstes ⏩

wetlook

Hallo liebes Forum,
ich stehe hier vor einem (zumindest für mich) unlösbaren Problem. Ich habe eine Datenbank
die eine generierte Nummer über Berichte drucken soll. Soweit ganz einfach
(Tabelle mit mehreren Spalten: ID, Prefix, Nummer, Suffix werden berechnet und zu einem
Wert zusammengefasst. Heraus kommt z.B. 123456 dieses soll nun per Bericht gedruckt werden.

Jetzt das Problem:
Die Datenbank soll in einer Schleife immer weiter neue Werte berechnen, drucken und in der Tabelle speichern.
Ist auch kein Thema...
ABER: Die Schleife soll immer erst den nächsten Datensatz erstellen, wenn der letzte gedruckt wurde (also
aus dem Spooler verschwunden ist. Zudem muss es ein Button geben, um die Schleife dann irgendwann zu
unterbrechen.

Hintergrund: Es soll ein Stapel Papier in den Drucker gelegt werden, dieser wird mit den Werten bedruckt
und dann kann man entweder abbrechen oder neues Papier einlegen-je nachdem wieviel gerade gebraucht wird,
ohne vorher die Menge abzählen zu müssen oder das der Spooler vollläuft. Es dürfen keine offenen Aufträge im
Drucker verbleiben die nicht gedruckt werden...

Ich hoffe es ist einigermaßen Verständlich ausgedrück und jemand kann mir helfen?  ???
Vielen Dank schonmal für eure Hilfe...
LG


wetlook

Hallo,
das habe ich schon gefunden, jedoch werden hier alle Daten an den Spooler übergeben...
der Teil mit der Schleife und dem Abbruch-Button funzt leider doch nicht... oder ich
bekomme es nicht hin es in meinen Quellcode richtig einzubauen... Er sieht so aus:

DoCmd.OpenReport "Ausdruck", , , "ID =" & Me!ID
DoCmd.GoToRecord , , acNewRec
Me.Schluessel1 = Me.Kombinationsfeld2.Column(1)
Me.Schluessel2 = Me.Kombinationsfeld2.Column(2)
Me.Schluessel3 = Me.ID
Me.Bezeichnung = Me.Kombinationsfeld2.Column(5)
Me.Druckschluessel = Me.Schluessel1 & "" & Me.Schluessel2 & "" & Me.Schluessel3
DoCmd.OpenReport "Ausdruck", , , "ID =" & Me!ID
DoCmd.Save

DF6GL

HAllo,

ich halte das Vorgehen für ein hoffnungsloses Unterfangen, wenn man nicht dramatisch tiefer in das Zusammenspiel Drucker/Windows-Spooler/Druckertreiber/Access-Bericht  einsteigen will.


Wenn es nur darum geht eine gewisse akt. Menge an solchen berechneten Werten zu drucken, dann würde ich die einfachere Methode vorziehen:

In einem Textfeld in einem Form die gewünschte ( oder eine plausible max. ) Anzahl eintragen und damit den Kopieen-Parameter der Outputto-Methode bemühen. Soll heißen, den Spooler bis zu einem sicheren Wert "befüllen"

Bei allen "neueren" (physikalischen) Druckern kann man durch Öffnen des Papierschachtes den Druckvorgang unterbrechen und Papier nachlegen, wenn nötig.


Wenn der Vorgang anders sein sollte, habe ich den Hintergrund der Frage nicht verstanden..

wetlook

Hallo,
danke erstmal für die Antwort. Darüber habe ich auch schon nachgedacht, leider enthalten
die Werte unter anderem die ID und sollen immer fortlaufend sein. Somit kann ich nicht einfach
eine Menge x drucken und den Rest verwerfen... Oder hast du eine Idee wie man das mit den
fortlaufenden Nummern sonst regeln könnte?

Beaker s.a.

Hallo wetlook,
Zitatleider enthalten die Werte unter anderem die ID und sollen immer fortlaufend sein. Somit kann ich nicht einfach
eine Menge x drucken und den Rest verwerfen..
Heisst das, dass die Nummern beim nächsten Mal wieder mit der ersten nicht verwendeten Nummer des letzten Durchgangs begonnen werden muss?
Dann würde ich eine Hilfstabelle anlegen, in der die letzte verbrauchte Nummer gespeichert wird.
Dann machst Du es so, wie von Franz vorgeschlagen. Druckst dann die Berichte in einer Schleife, und setzt jeweils nach dem Druck die fortlaufende Nr. hoch. Die Schleife kannst Du auch per Button unterbrechen, wenn Du ein Do Events einbaust.
hth
gruss ekkehard
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

wetlook

Ja, und genau da ist mein Problem... Wie speicher ich den letzten Datensatz der WIRKLICH gedruckt wurde,
und nicht der letzte der in den Spooler geschoben wurde? Wenn ich z.B. 500 Druckaufträge aus dem Formular
mit einer Schleife starte, dann gehen die sofort alle in den Spooler. Jetzt habe ich nach 430 kein Papier mehr
zu bedrucken und müsste abbrechen. Wie bekomme ich den letzten Datensatz ermittelt ??

wetlook

Hallo,
ok, da mir hierbei wohl nicht geholfen werden kann vielleicht ein anderer Ansatz?
Kann ich in einem Formular ggf. den Druckerspooler-Inhalt in einem Listenfeld anzeigen
und dann den Druck über eine Schleife starten, mit der Bedingung, wenn das Listenfeld leer ist?
Leider habe ich hierfür keine Idee wie ich das hinbekomme......

DF6GL

Hallo,


"Jetzt habe ich nach 430 kein Papier mehr
zu bedrucken und müsste abbrechen. Wie bekomme ich den letzten Datensatz ermittelt ??"



sagte doch, dass das nicht ohneweiteres möglich ist.  Der Drucker empfängt im "ungünstigsten" Fall die  gesamten Daten des Druckjobs in sein eingebautes Memory und beginnt dann zu drucken.   Wenn beim Drucken dann ein Fehler auftaucht , z. B. fehlendes Papier, dann wird er das kundtun und pausieren , aber nicht abbrechen, d. h. nach Einlegen von neuem Papier druckt er einfach weiter, evtl. wiederholt er auch diejenige Seite, bei der ein Fehler aufgetreten ist, in, diesem Fall z. B., bei einem Papierstau.   


Eine genaue Prüfung der richtig ausgedruckten Blätter kannst Du m. E. nur durch "Sichtkontolle" erledigen..


der "Druckerspooler-Inhalt" nützt Dir gar nichts, den gibt es schon nicht mehr  , wenn der Drucker am Drucken ist. Ausserdem steht da ja nicht
"Seite 5 von 500 perfekt gedruckt und ausgeworfen" drin...


Im Grunde musst Du selber als "Feedback" fungieren, indem Du z. B. durch Drücken von Enter jeweils einen einzelnen , d. h. den nächsten Ausdruck anstößt...



(Hätte da eine schlaue  8)  Lösung:  druck die fortlaufende Nr. zusätzlich als Barcode auf das Papier und positioniere einen Barcodeleser am Papierausgabefach des Druckers, so dass er den Barcode ablesen kann. Der Barcodeleser hängt  (z. B.) zwischen Tastatur und Rechner und sorgt so für die (feedback)- Eingabe der lfd. Nr. in ein Formular.  Dann kannst Du sogar eine Historie über die ausgedruckten Blätter führen)

Welches genaue Problem hast Du denn in Grunde?   


wetlook

Hallo,
es soll der Wert + der Wert als Barcode angedruckt werden. Jeder darf nur 1x verwendet werden (klar)
nur müssen diese eben fortlaufend sein und ich weiß vorher nicht wieviele gedruckt werden. Die Idee mit
dem Scanner am Drucker ist ganz gut, aber eben nur "zurechtgebastelt"...
Ich müsste sicherstellen, dass keine Nummern verloren gehen...
Ich hatte dieses schöne Modul gefunden:

Option Compare Database

Public Declare Sub sleep _
     Lib "Kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)

Public Declare Function GetProcessVersion _
     Lib "Kernel32" (ByVal ProcessId As Long) As Long

Sub procShellWait()

     Dim lngHandle As Long

     lngHandle = Shell("NOTEPAD.EXE", 1)
     While GetProcessVersion(lngHandle) <> 0
         DoEvents
         'Sleep verhindert, dass die Prozessorauslastung auf 100% geht
         'Tipp von Michael Zimmermann
         sleep 1
     Wend

    MsgBox "Process Finished"

End Sub

und gehofft das könnte man auf die Druckaufträge beziehen. Den Druckerspeicher kann ich bei dem Modell abschalten, so dass immer nur direkt aus dem spooler gedruckt wird. Wenn wie im Bsp. oben nicht wordpad aufgeht, sondern der
Druckauftrag könnte der Code nach dem Löschen des Druckauftrags von selber weiterlaufen...
Habe jetzt schon Stunden über Stunden über alternativen nachgedacht und bin für jeden Vorschlag dankbar...

wetlook

OK, hier ist doch was. Einfach ein Formular erstellen mit 1 Button + 1 Listenfeld     List1
Code ins Formular und es sollte über wmi alle Druckaufträge listen. Leider bekomme ich die Fehlermeldung
die der Autor unten im Code vorgesehen hat...Es ist ein Fehler aufgetreten. Evtl. ist WMI nicht installiert.
Weiß jemand warum? Was ist falsch... wmi ist auf allen neuen Betriebssystemen installiert (bei mir auch).
Verweise auf wmi habe ich auch in der Db...


Public Function fPrint_Queue_Stat(LB As ListBox) As Boolean
  ' aktuelle Print-Queue Statistik-Informationen in
  ' einer Listbox anzeigen:
  ' ===============================================
  Dim ComputerName As String
  Dim strPrinterStatus As String
  Dim oWMI
  Dim oPrintJob
  Dim colPrintJobs
  Dim lTotalJobs As Long
  Dim lTotalPages As Long

  On Error GoTo errHandler

  ' Computername (. = lokaler Rechner)
  ComputerName = "."

  ' WMI-Objekt erstellen
  Set oWMI = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & ComputerName & "\root\cimv2")

  ' WMI-Abfrage: alle Druckaufträge ermitteln
  Set colPrintJobs = oWMI.ExecQuery("SELECT * FROM Win32_PrintJob")

  ' Druckaufträge durchlaufen und
  ' anstehende Seiten hochzählen
  For Each oPrintJob In colPrintJobs
    lTotalJobs = lTotalJobs + 1
    lTotalPages = lTotalPages + oPrintJob.TotalPages
  Next

  ' Ergebnis in ListBox anzeigen   
  With LB
    .AddItem "Summe aller Druck-Jobs in der Print-Queue: " & lTotalJobs
    .AddItem "Summe aller Druck-Seiten in der Print-Queue: " & lTotalPages
  End With

  ' Funktionsrückgabewert
  fPrint_Queue_Stat = True
  Exit Function

errHandler:
   fPrint_Queue_Stat = False
End Function
Private Sub Command1_Click()
  ' alle Druckaufträge ermitteln
  If Not fPrint_Queue_Stat(List1) Then
    ' Fehler!
    MsgBox "Es ist ein Fehler aufgetreten. Evtl. ist WMI nicht installiert."
  End If
End Sub

database

Hallo,

füge die Bestimmung der Datenherkunft für das Listenfeld ein, dann funktioniert der Code ohne Fehlermeldung.


' Ergebnis in ListBox anzeigen
With LB
    .RowSourceType = "Value List"   
    .AddItem "Summe aller Druck-Jobs in der Print-Queue: " & lTotalJobs
    .AddItem "Summe aller Druck-Seiten in der Print-Queue: " & lTotalPages
End With


HTH