Guia de las mejores prácticas de Clarion
(Por Cristian Olsen)
Tipos de Campos
Acordarse siempre que lo que define el almacenamiento es la opción Characters, la opción Picture es solo como se va a mostrar
Clarion Que se puede almacenar
- Byte (de 1 a 99)
- Short (de 1 a 9,999)
- Long (de 1 a 999,999,999)
- Decimal (de 1 a 9,999,999,999,999,999,999,999,999,999,999)
- String (de 1 a 4 Mega-Bytes)
Para guardar hasta 99,999.99 se define un campo del tipo Decimal con un character de 7 decimal 2 picture @N9.2
Para campos alfanuméricos grandes se puede usar CSTRING pero en characters hay que poner uno más del que se quiere almacenar
Pictures para Fecha y Hora
- @D6 DD/MM/YYYY
- @D17 Fecha corta según formato Windows
- @D18 Fecha larga según formato Windows
- @T1 HH:MM
- @T4 HH:MM:SS
- @T7 Hora corta según formato de Windows
- @T8 Hora larga según formato de Windows
Para todos los pictures si se especifica B esto hará que cuando el campo es cero se muestre blanco (@D6B), otros ejemplos comunes son
- @N10 <<,<<<,<<<# Ejemplo de CUIT
- @N_10 <<<<<<<<<# Decimal 11 Picture @P##-########-#P
- @N010 ########## los guiones nunca son almacenados
Para el ingreso de datos la forma mas sencilla es la siguiente
Campos | Entry Mode |
---|---|
Numéricos | Insert |
Fecha | Overwrite |
String | Overwrite |
Relación tipos de campos entre Clarion y MS-SQL Server
CLARION | MS-SQL SERVER |
---|---|
Byte | Bit (de 0 a 1) |
Byte | Tinyint (de 1 a 99) |
Short | SmallInt (de 1 a 9,999) |
Long | Int (de 1 a 999,999,999) |
Decimal | Decimal (999.99 se define como: (pres 5 esc 2) |
String | Char |
CString | VarChar |
Date | DateTime (Fecha y Hora) |
Time | DateTime (Fecha y Hora) |
Para un buen funcionamiento de las aplicaciones todos los índices deben ser Únicos y los campos se deben definir sin el atributo NULL
Manejo de Tablas
Acceso a un registro
CLEAR(TBL:RECORD) TBL:CAMPO = XXXXX IF Access:TABLA.Fetch(TBL:CLAVE) = LEVEL:BENIGN !El registro existe ELSE !El registro no existe END
Insertar un registro
CLEAR(TBL:RECORD) TBL:CAMPO = XXXXX IF Access:TABLA.Insert() <> LEVEL:BENIGN ! Error al crear el registro
Cambiar un registro
CLEAR(TBL:RECORD) TBL:CAMPO = XXXXX IF Access:TABLA.Fetch(TBL:CLAVE) = LEVEL:BENIGN TBL:CAMPO = XXXXX IF Access:TABLA.Update() <> LEVEL:BENIGN !Error al actualizar el registro END END
Borrar un registro
CLEAR(TBL:RECORD) TBL:CAMPO = XXXXX IF Access:TABLA.Fetch(TBL:CLAVE) = LEVEL:BENIGN Access:TABLA.DeleteRecord() !Alternativa 1 Relate:TABLA.Delete(0) !Alternativa 2 Delete(TABLA) !Alternativa 3 END
Lectura secuencial
CLEAR(TBL:RECORD) TBL:CAMPO = XXXXX SET(TBL:CLAVE,TBL:CLAVE) LOOP Until Access:TABLA.Next() OR TBL:CAMPO <> XXXXX !!!! END
Igualar los registros de dos tablas
TB1:RECORD :=: TB2:RECORD :=: es una igualación en profundidad Esta instrucción iguala solo los campos que se llamen igual en ambas tablas independientemente de la posición de cada uno de ellos
Antes de abrir la ventana como saber si en el Form estoy en modo ADD-CHANGE-DELETE-VIEW
Window Manager - Init - Open the window (PR-8000)
IF SELF.Request = InsertRecord IF SELF.Request = ChangeRecord IF SELF.Request = ViewRecord IF SELF.Request = DeleteRecord La última instrucción solo es valida siempre que el Form muestre el registro a borrar
Agregar código antes que el Form realice el ADD-CHANGE-DELETE
Window Manager - TakeCompleted (PR-5000)
IF SELF.Request = InsertRecord IF SELF.Request = ChangeRecord IF SELF.Request = DeleteRecord
Agregar código después que el Form realizo el ADD-CHANGE-DELETE exitosamente
Window Manager - TakeCompleted (PR-5001)
IF ReturnValue = Level:Benign IF SELF.Request = InsertRecord IF SELF.Request = ChangeRecord IF SELF.Request = DeleteRecord La última instrucción solo es valida siempre que el Form muestre el registro a borrar
Como salir un procedimiento antes de abrir la window
RETURN Level:Fatal
Donde colocar código para hacer una validación en un campo en un procedimiento del tipo Form
Control Events – Accepted – Generated Code (PR-7000)
IF Condicion BEEP MESSAGE('Texto del Error','Texto de la Ventana’,&| ICON:Exclamation,BUTTON:Cancel,BUTTON:Cancel,1) SELECT(?) CYCLE END
Si quiero tomar control de los botones del cuadro de mensajes
CASE MESSAGE('Texto del mensaje’,’Texto de la Ventana’,&| ICON:Question,BUTTON:Yes+BUTTON:No,BUTTON:No,1) OF BUTTON:No SELECT(?) CYCLE OF BUTTON:Yes END
Como forzar la validación de un campo
Control Events – Selected – Generated Code (PR-4000)
?CAMPO{PROP:Touched} = TRUE
Como saber en la validación de un campo si se esta pasando cuando se presiono el botón OK
IF NOT ThisWindow{PROP:AcceptAll} o IF NOT (Nombre de Ventana){PROP:AcceptAll}
Como saber si luego de que un control del tipo Field LookUp que accedió a un browse para validar se le dio Select
IF GlobalResponse = RequestCompleted
Como colocar código en un Browse para cada registro leído
Local Objects – Browse on Tabla – SetQueueRecord (PR-2500)
Como filtrar un Browse antes de mostrarlo
Se puede hacer por record filter Si es mas complejo se puede hacer en
Local Object – Browse on Table – InitSort (PR-10000)
IF Condicion = 1 BRW1.SetFilter('(TCON:CVP_B <> 0)') BRW1.ApplyFilter() END
Como filtrar un registro en un Browse o Reporte antes que se muestre
Local Objects – Browse on Tabla – ValidateRecord (PR-4500)
IF Condition THEN RETURN Record:Filtered;END
Como controlar desde un Browse justo antes de llamar a un Form
Local Object – Browse on Table – Ask(Byte Request) (PR-4999)
IF Request = InsertRecord
Como abrir una tabla en modo exclusivo
Colocar la tabla en OTHER TABLE
Window Manager - Init – Open Files (PR-7501)
Relate:TABLA.Close Access:TABLA.SetOpenMode(12h);Relate:TABLA.Open Relate:TABLA.Close
O También abrir la tabla en modo exclusivo
Como ordenar una tabla para luego imprimirla en ese orden en un reporte
OpenReport – Code (PR-5000)
ThisReport.SetOrder('TBL:CAMPO1',TBL:CAMPO2’,’-TBL:CAMPO3’) ThisReport.ApplyOrder()
CAMPO1 Y 2 en orden ascendente CAMPO3 en orden descendente
Como filtrar una tabla para luego imprimirla sin esos registros en un reporte
OpenReport – Code (PR-5000)
ThisReport.SetFilter('TBL:CAMPO1 = XXXX’) ThisReport.ApplyFilter()
Tanto para el Order como para el Filter los campos a utilizar si no están pintados en el reporte tienen que estar definidos como HOT FIELDS
Como manejar un Browse con una clave compuesta por más de un campo e ir refrescándolo por cada cambio en esos campos
Clave de la Tabla
- Empresa
- Cliente
- Fecha
Colocar en Range Limit siempre el último campo de la clave que se quiere limitar, en este caso Cliente
Si se cambia la Empresa colocar
TBL:Empresa = GLO:Empresa BRW1.AddRange(TBL:Empresa) BRW1.ApplyRange() ThisWindow.Reset(True)
Si se cambia el Cliente colocar
TBL:Cliente = GLO:Cliente BRW1.AddRange(TBL:Cliente) BRW1.ApplyRange() ThisWindow.Reset(True)
Como refrescar un Browse
SETCURSOR(CURSOR:WAIT) BRW1.ResetFromFile() BRW1.ResetFromBuffer() ThisWindow.Reset(True) SETCURSOR
Como ordenar un Browse antes de abrir la ventana
Local Objects – Browse on Tabla – InitSort (PR-10000)
BRW1.SetOrder('TBL:CAMPO')
Como agregar otro ítem al PopUp menú de ABM del browse
Agregar un botón debajo de los estándar ADD-CHANGE-DELETE con atributo Hide
Window Manager - Init – Prepare Alert Key (PR-9001)
BRW1.PopUp.AddItemMimic('Texto',?Boton)
Como borro un boton de update en ABM del browse
Window Manager - Init – Open the Window (PR-8000)
BRW4.DeleteControl = 0
Como pararse en un browse de entrada en distintas partes
Window Manager - Init - (PR-9000)
POST(Event:ScrollUp,?Browse) ! subir un registro POST(Event:ScrollDown,?Browse) ! descer un registro POST(EVENT:ScrollTop,?Browse) ! primer registro POST(EVENT:ScrollBottom,?Browse) ! ultimo registro
Para apretar un botón desde la lógica
POST(EVENT:ACCEPTED,?Boton)
Colas en memoria (Queue)
Para recorrer toda una cola
LOOP Q# = 1 TO RECORDS(COLA) BY 1;GET(COLA,Q#) !Codigo END
GET(COLA,CAMPO) Busca un registro (El campo a buscar tiene que ser de la cola previamente igualado) ADD(COLA) Inserta un registro PUT(COLA) Modifica un registro DELETE(COLA) Borra un registro
Bloquear una Tabla
AUX:TABLA_UseLogOut = Relate:A_STOPRO.UseLogOut Relate:TABLA.UseLogout = FALSE LOOP;LOGOUT(1,TABLA);UNTIL ERRORCODE() = 0 !Mi código COMMIT Relate:TABLA.UseLogOut = AUX:TABLA_UseLogOut
Validación de campos en Browse EIP
Local Object – EIP Manager for browse using ?Browse:1 – Take Completed (BYTE Force) (PR-4999)
IF BRW1.Q.TBL:CAMPO <> 1 Return END
Poner disable un campo del EIP por una condición
Local Object – EIP Manager for browse using ?Browse:1 – GetEdit (PR-5001)
IF SELF.Req = ChangeRecord AND Self.Column = 1 AND TBL:MARCA <> 'E' ReturnValue = FALSE END
Agregar código antes que el EIP realice el ADD-CHANGE-DELETE
Local Object – EIP Manager for browse using ?Browse:1 – TakeCompleted Force (PR-4999)
IF SELF.Request = InsertRecord IF SELF.Request = ChangeRecord IF SELF.Request = DeleteRecord BRW1.Q.COU:DESCRIPTION = CLIP(UPPER(BRW1.Q.COU:DESCRIPTION))
Agregar código después que el EIP realice el ADD-CHANGE-DELETE Local Object – EIP Manager for browse using ?Browse:1 – TakeCompleted (PR-5001)
IF ReturnValue = Level:Benign
IF SELF.Request = InsertRecord IF SELF.Request = ChangeRecord IF SELF.Request = DeleteRecord