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
Hallo,
vielleicht hilft dir das weiter:
http://www.alice-dsl.net/ahmed.martens/index.htm?/ahmed.martens/Tools.html (http://www.alice-dsl.net/ahmed.martens/index.htm?/ahmed.martens/Tools.html)
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
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..
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?
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
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 ??
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......
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?
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...
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
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