Programma di esempio CODQT.PRT |
; CODQT
;
; Programma per Proteus
;
; (C) 2002-2003 Simone Zanella Productions
;
; Accetta codice/quantità e li salva sul file operator.TXT.
#!proteus -z
!include "console.prt"
IF LT(ARGC, 5)
CONSOLELN "Parametri insufficienti."
CONSOLELN ""
CONSOLELN "Sintassi: proteus codqt <operatore>"
CONSOLELN "operatore = i dati sono salvati sul file operatore.txt"
ABORT 0
FI
Operator = UPPER(ARGV(5))
; Nome del file in cui saranno salvate le registrazioni
NomeFile = Operator ".TXT"
; Massima lunghezza del codice introdotto (sempre convertito in maiuscolo)
MaxCod = 50
; Massima lunghezza della quantità introdotta (può essere un numero decimale o intero)
MaxQt = 6
; Salva lo schermo sottostante
OldScreen = DISPSAVE(1, 1, 80, 25)
; Impostazioni del display: blink, dimensioni, colori, giustificazione, ombre
DISPSET(DISP_BLINK, DISP_BLINK_OFF)
RESIZE(24, 20)
DISPSET(DISP_FOREG, YELLOW)
DISPSET(DISP_BACKG, BLUE)
DISPSET(DISP_UNSFG, YELLOW)
DISPSET(DISP_SELBG, GREEN)
DISPSET(DISP_JUST, DISP_JUST_NONE)
DISPSET(DISP_JLEN, 0)
DISPSET(DISP_SHADOW, DISP_SHADOW_RIGHT)
; Maschera per l'introduzione dei dati
DISPCLS()
DISPBOX(1, 1, 23, 19)
; Centra il nome dell'operatore nell'interfaccia
L = ADD(STRLEN(Operator), 2)
L = SUB(23, L)
L = DIV(L, 2)
IF LT(L, 0)
L = 0
FI
DISPWRITE(INC(L), 1," " LEFT(Operator, 21) " ")
; Visualizza la maschera per l'introduzione dei dati
DISPWRITE(3, 3, "Codice:")
DISPWRITE(3, 6, "Quantita':")
DISPWRITE(3, 9, "Digita codice")
DISPWRITE(3, 12, "F1 pulisci")
DISPWRITE(3, 13, "F2 canc. ultimo")
DISPWRITE(3, 14, "F5 canc. tutti")
; Stato del cursore: sovrascrittura
Insert = 0
; Fase di acquisizione: chiede codice
Passo = 1
DISPSET(DISP_FOREG, BLACK)
DISPSET(DISP_BACKG, BROWN)
Codice = ""
Qt = "1"
WHILE 1
; Scrive il valore corrente del codice e della quantità
DISPWRITE(3, 4, PADR(Codice, 18, " "))
DISPWRITE(3, 7, PADR(Qt, MaxQt, " "))
SWITCH Passo EQ
ON 1
; Richiede il codice
DISPSET(DISP_FOREG, YELLOW)
DISPSET(DISP_BACKG, BLUE)
DISPWRITE(3, 9, "Digita codice ")
DISPSET(DISP_FOREG, BLACK)
DISPSET(DISP_BACKG, BROWN)
; Posizione iniziale del cursore e offset iniziale della finestra
Start = 0
WinOffset = 0
; Converto in maiuscolo i codici introdotti
STATUS = GETSTRINGUDF(3, 4, @Codice, MaxCod, 18, @Start, @WinOffset, @Insert, "!", CodUdf)
IF ISEMPTY(Codice)
; Richiesto "pulisci": torna a chiedere il codice
CONTINUE
FI
; Qui si potrebbe introdurre una verifica sulla lunghezza del codice,
; per accettarlo solo se di dimensioni corrette
; IF NEQ(STRLEN(Codice), 18)
; Attenzione("Lunghezza errata (" STRLEN(Codice) ")!")
; CONTINUE
; FI
; Passa alla richiesta della quantità
Passo = 2
ON 2
; Richiede la quantità
DISPSET(DISP_FOREG, YELLOW)
DISPSET(DISP_BACKG, BLUE)
DISPWRITE(3, 9, "Digita quantita'")
DISPSET(DISP_FOREG, BLACK)
DISPSET(DISP_BACKG, BROWN)
; Posizione iniziale del cursore e offset iniziale della finestra
Start = 0
WinOffset = 0
; La quantità può essere float (maschera "F") oppure intera (maschera "N", come in questo caso)
STATUS = GETSTRINGUDF(3, 7, @Qt, MaxQt, INC(MaxQt), @Start, @WinOffset, @Insert, "N", QtUdf)
IF ISEMPTY(Qt)
; Richiesto "pulisci": torna a chiedere la quantità
CONTINUE
FI
IF NOT(STATUS)
; Mancata conferma lettura: torna al codice
Passo = 1
ELSE
; Salvataggio record
Salva(Codice, Qt)
Codice = ""
Qt = "1"
Passo = 1
FI
OFF
LOOP
; Ripristina il contenuto precedente del display
DISPRESTORE(1, 1, 80, 25, OldScreen)
ABORT 0
FUNCTION ChiediSN(testo)
; Visualizza a centro schermo il testo passato e richiede la pressione di S o N
oldpar = DISPPARSAVE()
DISPSET(_DISP_FOREG, _WHITE)
DISPSET(_DISP_BACKG, _RED)
DISPSET(_DISP_JUST, _DISP_JUST_CENTER)
s = DISPOSD(testo " (S/N)?")
WHILE NOT(IN(ISET(c, UPPER(CHR(GETCH(0)))), "SN"))
LOOP
DISPRESTOREOSD(s)
DISPPARRESTORE(oldpar)
RETURN STREQ(c, "S")
FUNCTION QtUdf(car, stringa)
; UDF per la richiesta della quantità
retval = 0
SWITCH car EQ
ON 328
; Freccia su: torna a codice
retval = 3
ON 315
; F1: azzera la quantità
stringa = ""
retval = 2
ON 316
; F2: cancella l'ultimo record
Cancella()
ON 319
; F5: cancella tutti i dati
CancellaTutti()
OFF
RETURN retval
FUNCTION CodUdf(car, stringa)
; UDF per la richiesta del codice
retval = 0
SWITCH car EQ
ON 315
; F1: azzera il codice
stringa = ""
retval = 2
ON 316
; F2: cancella l'ultimo record
Cancella()
ON 319
; F5: cancella tutti i dati
CancellaTutti()
ON 27
; ESC: uscita (con conferma)
IF ChiediSN("Confermi uscita")
; Ripristina la scherma originale sottostante
RESIZE(80, 25)
DISPRESTORE(1, 1, 80, 25, _OldScreen)
ABORT 0
FI
retval = 5
ON 336
; Freccia giù: passo alla richiesta della quantità
car = 13
OFF
RETURN retval
FUNCTION Attenzione(messaggio)
; Mostra il messaggio passato e attende la pressione di un tasto
oldpar = DISPPARSAVE()
DISPSET(_DISP_FOREG, _WHITE)
DISPSET(_DISP_BACKG, _RED)
DISPSET(_DISP_JUST, _DISP_JUST_CENTER)
s = DISPOSD(messaggio)
BEEP(_BEEP_DEFFREQ, _BEEP_DEFDELAY)
GETCH(0)
DISPRESTOREOSD(s)
DISPPARRESTORE(oldpar)
RETURN
FUNCTION CancellaTutti()
; Cancella il file con i dati in memoria
h = FOPEN(_NomeFile, 1)
IF EQ(h, -1)
Attenzione("File dati vuoto!")
RETURN
FI
FCLOSE(h)
IF ChiediSN("Cancello tutto")
; Cancella tutti i dati
FREMOVE(_NomeFile)
FI
RETURN
FUNCTION Cancella()
; Cancella l'ultimo record (se l'utente conferma)
h = FOPEN(_NomeFile, 4)
IF EQ(h, -1)
Attenzione("File dati vuoto!")
ELSE
IF EQ(FSIZE(h), 0)
Attenzione("File dati vuoto!")
FCLOSE(h)
RETURN
FI
; 10 (data) + 8 (ora) + 3 (separatori) + 2 (CR+LF) = 23
FSEEK(h, NEG(ADD(_MaxCod, _MaxQt, 23)), 2)
articolo = FREADLN(h)
oldpar = DISPPARSAVE()
schermo = DISPSAVE(3, 9, 20, 18)
DISPCLEAR(3, 9, 20, 18, _BLUE)
DISPSET(_DISP_FOREG, _YELLOW)
DISPSET(_DISP_BACKG, _BLUE)
data = LEFT(articolo, 10)
ora = SUBSTR(articolo, 12, 8)
artcod = SUBSTR(articolo, 21, _MaxCod)
qt = RTRIM(RESTFROM(articolo, ADD(22, _MaxCod)), " ")
DISPWRITE(3, 9, "Cod:")
DISPWRITE(3, 10, LEFT(artcod, 18))
DISPWRITE(3, 12, "Qt: " qt)
DISPWRITE(3, 14, "Data: " data)
DISPWRITE(3, 16, "Ora: " ora)
DISPWRITE(3, 18, "Elimina (S/N)?")
WHILE NOT(IN(ISET(c, UPPER(CHR(GETCH(0)))), "SN"))
LOOP
IF STREQ(c, "S")
FRESIZE(h, SUB(FSIZE(h), _MaxCod, _MaxQt, 23))
FI
FCLOSE(h)
DISPRESTORE(3, 9, 20, 18, schermo)
DISPPARRESTORE(oldpar)
FI
RETURN
FUNCTION Salva(codice, qt)
; Salva data, ora, codice e quantità introdotte
d = DATE()
yy = YEAR(d)
mm = MONTH(d)
dd = DAY(d)
d = PFORMAT("02d", dd) "/" PFORMAT("02d", mm) "/" PFORMAT("04d", yy)
s = d "|" RTRIM(TIME(), " ") "|" PADR(codice, _MaxCod, " ") "|" PADR(qt, _MaxQt, " ") _EOL
result = -1
WHILE EQ(result, -1)
result = FAPPEND(_NomeFile, s)
IF EQ(result, -1)
; Errore: file dati bloccato
numtry = 0
; Attende un tempo casuale tra 1 centesimo di secondo e 1 secondo, quindi riprova per 3 volte
WHILE AND(LT(numtry, 3), EQ(result, -1))
SLEEP(FDIV(INC(RANDOM(100)), 100))
result = FAPPEND(_NomeFile, s)
IF NEQ(result, -1)
BREAK
ELSE
INC(@numtry)
FI
LOOP
; Arrivo qui se ho esaurito i tentativi oppure la scrittura ha avuto successo
IF EQ(result, -1)
Attenzione("File dati bloccato. Premi un tasto per riprovare.")
FI
FI
LOOP
DISPSET(_DISP_FOREG, _YELLOW)
DISPSET(_DISP_BACKG, _BLUE)
DISPWRITE(3, 9, "= MEMORIZZATO = ")
DISPSET(_DISP_FOREG, _BLACK)
DISPSET(_DISP_BACKG, _BROWN)
SLEEP(0.5)
RETURN