Seite 1 von 1

PaperBins() [erledigt]

Verfasst: Di, 19. Apr 2011 23:30
von Werner_Bayern
Servus,

was ist an dem Code falsch?

Code: Alles auswählen

oDrucker := XbpPrinter():new()
aDrucker := oDrucker:list()
nLaenge := len(aDrucker)
if nLaenge == 0
   fehler("Es sind keine Drucker installiert!")
endif
aSchaechte := array(nLaenge)
for i := 1 to nLaenge
   oDrucker:create(aDrucker[i])
   aSchaechte[i] := oDrucker:paperBins()
   oDrucker:destroy()
next i
Bei einem Kunden knallt es bei

Code: Alles auswählen

aSchaechte[i] := oDrucker:paperBins()
mit

Code: Alles auswählen

oError:args         :
          -> VALTYPE: O CLASS: XbpPrinter
oError:canDefault   : N
oError:canRetry     : N
oError:canSubstitute: J
oError:cargo        : NIL
oError:description  : Falscher Objekt Status
oError:filename     : 
oError:genCode      :        104
oError:operation    : :paperBins
oError:osCode       :          0
oError:severity     :          2
oError:subCode      :       4208
oError:subSystem    : BASE
oError:thread       :          1
oError:tries        :          0

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 0:07
von Herbert
Werner,
Paperbins gibt selber ein zweidimensionales Array zurück. Mit "aSchaechte:=" klappt das meiner Meinung nach nicht unbedingt.
Oder der Kunde hat einen Drucker, der nichts retourniert. Es gibt viele wirre als Drucker erscheinende Objekte (Fax, PDF-Creators oder PrintScreen Dinger wie Snagit oder One Note2010 von Office)

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 0:30
von Werner_Bayern
Mit "aSchaechte:=" klappt das meiner Meinung nach nicht unbedingt.

Was soll daran falsch sein? Ich werte das Array korrekt später aus, es knallt aber hier schon.
Hab die Routine gerade geändert und frag nach dem create() jetzt ab:

Code: Alles auswählen

oDrucker := XbpPrinter():new()
aDrucker := oDrucker:list()
nLaenge := len(aDrucker)
if nLaenge == 0
   fehler("Es sind keine Drucker installiert!")
endif
aSchaechte := array(nLaenge)
for i := 1 to nLaenge
   oDrucker:create(aDrucker[i])
   if .not. oDrucker:printerStatus() == XBPPRN_STATUS_READY
      fehler("Drucker " + aDrucker[i] + " nicht verfügbar: " + chr(13) + cPrinterStatus(oDrucker:printerStatus()))
   endif
   aSchaechte[i] := oDrucker:paperBins()
   oDrucker:destroy()
next i
mal morgen sehen, was das beim Kunden bringt.
Es gibt viele wirre als Drucker erscheinende Objekte (Fax, PDF-Creators oder PrintScreen Dinger wie Snagit oder One Note2010 von Office)
Bisher ohne Probleme, entweder liefern die nur einen Standardschacht, oder NIL, was völlig korrekt ist. Aber bisher nirgends ein "falscher Objektstatus".

Danke.

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 2:49
von AUGE_OHR
Werner_Bayern hat geschrieben:was ist an dem Code falsch?

Code: Alles auswählen

for i := 1 to nLaenge
   oDrucker:create(aDrucker[i])
was soll das o:create() in einer "Schleife" ?

Code: Alles auswählen

FUNCTION PRINTERPS( cPrinter, nCopies, nPaperBin )
LOCAL oDC    := XbpPrinter():New()
...
      IF oDC:Create( cPrinter ) == oDC
...
      nStatus := oDC:PrinterStatus()

      DO CASE
         CASE nStatus == 1
            lPFail := .F.                        // alles OK
         CASE nStatus == - 7
            MsgBox( "The Printer is Offline !" )
            lPFail := .T.
         CASE nStatus == - 6
            MsgBox( "The Printer has a failure !" )
            lPFail := .T.
         CASE nStatus == - 5
            MsgBox( "The Printer is not useable !" )
            lPFail := .T.
         CASE nStatus == - 4 .OR. nStatus == - 1
            MsgBox( "The Printer is not ready !" )
            lPFail := .T.
         CASE nStatus == - 3
            MsgBox( "The Printer has no paper !" )
            lPFail := .T.
         CASE nStatus == - 2
            MsgBox( "Der Netzwerk Drucker ist offline !" + CHR( 13 ) + CHR( 10 ) + CHR( 13 ) +, ;
                    "Abbruch Druck" )            // Text der Titelzeile
            lPFail := .T.
      ENDCASE
...
      IF oDC:paperBins() != NIL
         aPB := oDC:paperBins()
         iMax := LEN( aPB )

         IF NIL = cPrinter
            FOR i = 1 TO iMax
               nDummy := aPB[ i ] [ 1 ]
               IF nDummy == nPaperBin
                  lRaus := .F.
                  EXIT
               ENDIF
            NEXT
         ELSE
            //
            // HP P2055dn Paperbin Konstanten stimmen NICHT überein
            //
            IF "P2050" $ cPrinter                // HP LaserJet P2050 Series PCL6
               FOR i = 1 TO iMax
                  nDummy := aPB[ i ] [ 1 ]
                  DO CASE
                     CASE nPaperBin == XBPPRN_PAPERBIN_CASETTE
                        IF nDummy == 260
                           nPaperBin := 260
                           lRaus := .F.
                           EXIT
                        ENDIF
                     CASE nPaperBin == XBPPRN_PAPERBIN_MIDDLE
                        IF nDummy == 261
                           nPaperBin := 261
                           lRaus := .F.
                           EXIT
                        ENDIF
                  ENDCASE
               NEXT

            ELSE
            //
            // Paperbin "Nummer" stimmen überein mit Xbase++ Konstanten
            //
               FOR i = 1 TO iMax
                  nDummy := aPB[ i ] [ 1 ]
                  IF nDummy == nPaperBin
                     lRaus := .F.
                     EXIT
                  ENDIF
               NEXT
            ENDIF
         ENDIF

         IF lRaus
            cText := "!!! angegebene Papier Cassette nicht gefunden !!! "+CHR(13)+CHR(10)+;
                     " nehme : " + aPB[1][2]     // Text PapierQuelle
            MSGBOX( cText )
            nPaperBin := aPB[1][1]               // default nehmen ?
         ENDIF
      ELSE
         cText := "Keine Papier Cassetten gefunden"
         MSGBOX( cText )
         BREAK                                   // raus
      ENDIF

      oDC:setPaperBin( nPaperBin )               //  welche Kasette
      oDC:setNumCopies( nCopies )                //  Anzahl Kopien
      oDC:setCollationMode(XBPPRN_COLLATIONMODE_OFF)
      oDC:configure()

      oPS := XbpPresSpace() :New()
      oPS:Create( )
      oPS:configure( oDC, oDC:paperSize(), GRA_PU_LOMETRIC )

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 9:08
von brandelh
Hi,

auf den ersten Blick fällt mir auf, dass

1. immer erst prüfen ob ein Druckerobjekt wirklich ein Drucker ist (es könnte auch NIL sein)

2. prüfen ob der Drucker ansprechbar ist, wobei der Druckerstatus nicht nur READY sein muss
printerStatus() --> nStatus

* sollte gehen
XBPPRN_STATUS_PAUSED
XBPPRN_STATUS_READY
* problematisch
XBPPRN_STATUS_BUSY
XBPPRN_STATUS_SERVICE
XBPPRN_STATUS_NOPAPER
XBPPRN_STATUS_NOT_READY
* hier knallt es bestimmt
XBPPRN_STATUS_NA
XBPPRN_STATUS_ERROR
XBPPRN_STATUS_OFFLINE

3. Nie direkt von einem Array mit Inhalt ausgehen. Es könnte NIL oder emtpy() sein !
Also zunächst das Ergebnis in einer Variablen speichern und auf ! empty() prüfen, danach auf len(aVar) ...

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 9:25
von AUGE_OHR

Code: Alles auswählen

oDrucker := XbpPrinter():new()
for i := 1 to nLaenge
   oDrucker:create(aDrucker[i])
kann man, in einer Schleife, auf ein o:new() ein wiederholtes o:create() anwenden ?

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 9:32
von brandelh
Hi Jimmy,

im obersten Beispiel wird in der Schleife für jeden Drucker die Schachtinfo abgefragt und in ein Array gespeichert.

Da nach dem Create() ein destroy() steht, ist der nächste Aufruf von create() kein Problem.

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 9:36
von brandelh
O CLASS: XbpPrinter
oError:canDefault : N
oError:canRetry : N
oError:canSubstitute: J
oError:cargo : NIL
oError:description : Falscher Objekt Status

eindeutig ist das CREATE() in der Zeile davor nicht erfolgreich gewesen !
Die Abfrage des Druckerstatus sollte hier den Fehler verhindern.

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 9:59
von AUGE_OHR
brandelh hat geschrieben:O CLASS: XbpPrinter
oError:canDefault : N
oError:canRetry : N
oError:canSubstitute: J
oError:cargo : NIL
oError:description : Falscher Objekt Status

eindeutig ist das CREATE() in der Zeile davor nicht erfolgreich gewesen !
Die Abfrage des Druckerstatus sollte hier den Fehler verhindern.
das meine ich doch. Ein o:create() kann doch nicht ohne ein o:new() gehen wenn ich ein o:destroy() habe

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 10:32
von Herbert
Jimmy, das new() ist ausserhalb der Schleife, also OK.
Meine unglückliche Ausdrucksweise, dass ein wirrer Drucker da sein muss, klar, wie Hubert schreibt, den Status prüfen und erst nachher die Paperbins abfragen.
Uebrigens müsste dann dieser "falsche" Drucker vollkommen aus dem Array entfernt werden.

Wobei ich mich frage, Werner, warum du hier schon die Paperbins holst. Die brauchst du doch erst, wenn du auf den zu verwendenden Drucker was ausgibst...

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 10:37
von Werner_Bayern
brandelh hat geschrieben:1. immer erst prüfen ob ein Druckerobjekt wirklich ein Drucker ist (es könnte auch NIL sein)

2. prüfen ob der Drucker ansprechbar ist, wobei der Druckerstatus nicht nur READY sein muss
printerStatus() --> nStatus

3. Nie direkt von einem Array mit Inhalt ausgehen. Es könnte NIL oder emtpy() sein !
Also zunächst das Ergebnis in einer Variablen speichern und auf ! empty() prüfen, danach auf len(aVar) ...
Servus Hubert,

danke.

zu 1: Ich hole ja vorab mit :list() die gültige Druckerliste. Es sollte also immer ein gültiger Drucker sein?
zu 2: siehe 3
zu 3: es darf bei mir auch NIL sein, da das Array für eine Auswahl in einer Combobox für den jew. Druckerschacht benutzt wird. Das ist also absichtlich so gemacht.

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 10:46
von Werner_Bayern
Herbert hat geschrieben:Wobei ich mich frage, Werner, warum du hier schon die Paperbins holst. Die brauchst du doch erst, wenn du auf den zu verwendenden Drucker was ausgibst...
Systemeinstellungen. Funktioniert einwandfrei, auch wenn der Druckerstatus offline ist. Werde heute hoffentlich Gelegenheit bekommen, beim Kunden das nochmal zu testen, hab jetzt ja die Statusabfrage mit eingebaut.

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 11:06
von brandelh
Werner_Bayern hat geschrieben:zu 1: Ich hole ja vorab mit :list() die gültige Druckerliste. Es sollte also immer ein gültiger Drucker sein?
Auch wenn der Drucker als solcher "gültig" in Windows eingetragen ist, kann dennoch ein :Create() fehlschlagen.
Ähnlich wie eine bestehende Datei nicht immer exclusive geöffnet werden kann.
Werner_Bayern hat geschrieben:zu 2: siehe 3
zu 3: es darf bei mir auch NIL sein, da das Array für eine Auswhal in einer Combobox für den jew. Druckerschacht benutzt wird. Das ist also absichtlich so gemacht.
Es ist schon eine Weile her, dass ich meine Druckerklasse geschrieben habe, aber ich meine es gibt / gab auch Situationen in denen
das Druckerobjekt nach einem fehlgeschlagenen Aufruf von create() tatsächlich NIL war.
Möglicherweise ist das heute nicht mehr der Fall oder ich erinnere mich falsch ... sicher ist sicher, status prüfen.
Werner_Bayern hat geschrieben:zu 3: es darf bei mir auch NIL sein, da das Array für eine Auswhal in einer Combobox für den jew. Druckerschacht benutzt wird. Das ist also absichtlich so gemacht.
Wenn du das sauber durchprobiert hast ... könnte es aber auch an einem fehlerhaften Druckertreiber eines Herstellers liegen, der dann zu dem Fehler führt.

Auf jeden Fall deutet die Fehlermeldung darauf hin, dass Create() fehlgeschlagen ist ...

Re: PaperBins()

Verfasst: Mi, 20. Apr 2011 16:10
von Werner_Bayern
So, war gerade auf dem PC des Kunden. Die Abfrage mittels :printerStatus() brachte bei 3 Geräten den Status XBPPRN_STATUS_NA.
Man konnte nicht mal in der Systemsteuerung mittels Rechtsklick auf die Druckereigenschaften gehen, selbst da kam schon eine Fehlermeldung.
Verwaiste Drucker (die armen :? ).

Alle Drucker gelöscht, Problem beseitigt.

Danke an alle, vor allem Hubert, unser Drucker(bibliotheks)spezialist!

Re: PaperBins()

Verfasst: Do, 21. Apr 2011 1:44
von AUGE_OHR
Herbert hat geschrieben:Jimmy, das new() ist ausserhalb der Schleife, also OK.
ich scheine in der letzten Zeit auch kein Glück damit zu haben ... keiner versteht mich ;)

Code: Alles auswählen

oDrucker := XbpPrinter():new()
for i := 1 to nLaenge
   oDrucker:create(aDrucker[i])
...
   oDrucker:destroy()
next i
das o:new() ist ausserhalb der Schleife, das o:create() in der Schleife.
Das klappt beim 1st mal sowie das o:destroy() ... und dann ?

was hat oDrucker nach dem o:destroy() für einen "Value" ?
ist es NIL oder ein Object ?

da ich beim optimieren des Code gerade das "re-use" Problem angesprochen habe
bin ich mir ziemlich sicher das nach einem o:destroy() der "Value" NIL ist ... das Object ist "zerstört", oder ?

Re: PaperBins() [erledigt]

Verfasst: Do, 21. Apr 2011 10:01
von Werner_Bayern
AUGE_OHR hat geschrieben:was hat oDrucker nach dem o:destroy() für einen "Value" ?
ist es NIL oder ein Object ?
Servus Jimmy,

lt. Doku:
Die Methode :destroy() gehört zum Lebenszyklus eines Xbase-Parts und gibt Systemresourcen frei, die durch die Methode :create() angefordert wurden. Das XbpDialog-Objekt wird dadurch funktionsunfähig. Allerdings bleibt das Objekt erhalten und kann die Systemresourcen erneut mit :create() anfordern.

Re: PaperBins()

Verfasst: Do, 21. Apr 2011 10:17
von brandelh
AUGE_OHR hat geschrieben: was hat oDrucker nach dem o:destroy() für einen "Value" ?
ist es NIL oder ein Object ?
wie schon mehrfach erwähnt, zerstört ein :destroy() die Systemresourcen, die :create() angefordert hat.
Die Variable selbst ist aber weiterhin ein XbpPrinter()-Objekt und kann mit dem nächsten :create() wieder verwendet werden.

Re: PaperBins() [erledigt]

Verfasst: Fr, 22. Apr 2011 6:34
von AUGE_OHR
Allerdings bleibt das Objekt erhalten und kann die Systemresourcen erneut mit :create() anfordern.
da kann man das Help File noch so oft lesen um dann fest zu stellen das man das gar nicht verstanden hat 8-[

ich bin immer davon ausgegangen, weil "Value" = NIL, das Object im CG landet und dann "weg" ist.
ok wieder was gelernt, danke !

Re: PaperBins() [erledigt]

Verfasst: Fr, 22. Apr 2011 11:00
von brandelh
Hi,

das mit NIL funktioniert, wenn man die Variable sofort "beerdigen" will ...

RICHTIG - aber eigentlich unnötig:

oO := x:new()
oO:create()
oO:destroy() // beendet externe Resourcen Verbindungen
oO := NIL // nun ist oO kein Objekt mehr, sondern NIL.
Alle internen Variablen des Objekts werden sofort zerstört.

oO := x:new()
oO:create()
oO := NIL // nun ist oO kein Objekt mehr, sondern NIL.
Hierbei gibt es jetzt aber immer noch offene Verbindungen, der Speicher kann nicht freigegeben werden.