Etiqueta
Home » Todas las entradas
30 de marzo de 2011
¿Cómo localizar filas con valores duplicados en tablas de Oracle?
Por fin he dado con una solución práctica y sencilla para resolver éste problema, he aquí la solución:
SELECT NOMBRE,APELLIDO1,APELLIDO2
FROM BALUMNOS
GROUP BY NOMBRE,APELLIDO1,APELLIDO2
HAVING COUNT (*) > 1;
Esta sencilla sentencia SELECT devolverá las filas contenidas en la tabla BALUMNOS cuyos nombres y apellidos estén duplicados.
29 de marzo de 2011
La “Component Library”
El navegador o “Studio Browser” contiene muchas
plantillas y asistentes (wizards) que nos facilitan la construcción de
aplicaciones y como ya sabemos es posible cambiar o añadir contenidos, tanto sobre
el “Studio Browser”, como sobre el “Component Store”. A continuación mostramos
dos ejemplos: El primero se trata de una plantilla simple, mientras que en el
segundo mostraremos como crear un sencillo asistente.
Primer ejemplo: Plantilla o “Template”, para la
creación de un menú “Edición” personalizado.
1)
Pulse
“botón-derecho” sobre la opción “Libraries” del navegador y escoja la opción
“Show Comps.lbs”.
2) Cree
una nueva clase “Menú” y llámela “Edición”.
3) Pulse “botón-derecho” sobre la clase recién creada y
tras escoger la opción “Component Store Type…”, seleccione “Template”.
Añada el código siguiente
según la opción correspondiente:
Deshacer: Standard menu
command *Edit/11001 {Undo}
Cortar: Standard menu command
*Edit/11002 {Cut}
Copiar: Standard menu command
*Edit/11003 {Copy}
Pegar: Standard menu command
*Edit/11004 {Paste}
Borrar: Standard menu command
*Edit/11005 {Clear}
Seleccionar todo: Standard
menu command *Edit/11006 {Select All}
Pegar desde archivo…: Standard
menu command *Edit/11065 {Paste From File...}
4) Finalmente oculte la librería de componentes (opción
“Hide Comps.lbs”)
Ahora
podrá encontrar bajo la opción “Class Wizard >> Menu… >>
Templates”, una nueva opción denominada “Edción”, selecciónela y pulse el botón
“Create” cada vez que desee añadirla a su biblioteca en construcción.
Segundo
ejemplo: Asistente o “Wizard” para la creación de un menú “Archivo”
personalizado.
1)
Pulse
“botón-derecho” sobre la opción “Libraries” del navegador y escoja la opción
“Show Comps.lbs”.
2) Cree
una nueva clase “Menú” y llámela “Archivo”.
3) Pulse “botón-derecho” sobre la clase recién creada y
tras escoger la opción “Component Store Type…”, seleccione “Wizard”.
4) Cree una nueva clase “Object” y llámela “CreaMenuArchivo”
5) Añada un método al objeto, llámelo “$start” y
asígnele el código siguiente, así como las variables locales y de parámetros
utilizadas al efecto.
De parámetro
pRef Item
reference
pWindowClass Character
pMenuLineText Character
Variables locales
lAplicacion Character
lMethodTextRef Item reference
lRefLine Item
reference
Método
Do pRef.$title.$assign('Archivo')
Do pRef.$methods.$findname('$setup()') Returns lMethodTextRef
Do pRef.$methods.$remove(lMethodTextRef) Returns #F
Prompt for input Introduzca el nombre de su aplicación:
/Nombre de la aplicación//15 Returns lAplicacion
If flag true
Do
pRef.$objs.$add(con('Registrar ',lAplicacion,'...')) Returns lRefLine
Do
lRefLine.$methods.$add('$event')
Do
lRefLine.$methods.$findname('$event') Returns lMethodTextRef
Do
lMethodTextRef.$methodtext.$assign(con("Do $prefs.$serialise(kTrue,'Datos
de registro",lAplicacion,"',24)")) Returns #F
Do
pRef.$objs.$add('')
Do
pRef.$objs.$add(con('Imprimirá en "',sys(24),'"...')) Returns
lRefLine
Do
lRefLine.$methods.$add('$event')
Do
lRefLine.$methods.$findname('$event') Returns lMethodTextRef
Do
lMethodTextRef.$methodtext.$assign("Standard menu command *File/11090
{Print Destination '$'...}") Returns #F
Do
pRef.$objs.$add('Ajustar página...') Returns lRefLine
Do lRefLine.$methods.$add('$event')
Do
lRefLine.$methods.$findname('$event') Returns lMethodTextRef
Do
lMethodTextRef.$methodtext.$assign("Standard menu command *File/11064
{Page Setup...}") Returns #F
Do
pRef.$objs.$add('Imprimir') Returns lRefLine
Do lRefLine.$methods.$add('$event')
Do
lRefLine.$methods.$findname('$event') Returns lMethodTextRef
Do
lMethodTextRef.$methodtext.$assign("Print top window") Returns #F
Do
pRef.$objs.$add('Imprimir informe guardado...') Returns lRefLine
Do
lRefLine.$methods.$add('$event')
Do
lRefLine.$methods.$findname('$event') Returns lMethodTextRef
Do
lMethodTextRef.$methodtext.$assign("Standard menu command *File/11079
{Print Report From Disk... }") Returns #F
End If
Tras
esto sólo nos quedará añadir un método al menú “Archivo” creado anteriormente,
al que denominaremos “$setup()”, con el código siguiente:
Variables locales
lObjeto Object ComponentLibrary.CreaMenuArchivo
Método
Do lObjeto.$start($cclass().$ref)
6) Finalmente oculte la librería de componentes (opción
“Hide Comps.lbs”)
Ahora
podrá encontrar bajo la opción “Class Wizard >> Menu…”, una nueva opción
denominada “Archivo”, tras seleccionarla y pulsar el botón “Create” se le
solicitará un nombre de aplicación, que será utilizado para componer la opción
“Acerca de..” del menú “Archivo”.
11 de febrero de 2011
Uso del método $search
Uno de los temas más debatidos en Omnis Studio, es como moverse a través de una lista de modo eficaz. El “blog” de Bastiaan, recogía un artículo dedicado a esto que me ha parecido muy esclarecedor, por lo que me he decido a traducirlo al castellano y publicarlo en el blog de “Experiencias con Omnis Studio”.
Por lo que debemos empezar por dar las gracias a Bastiaan Olij y a Kelly Burgess por sus aportaciones.
Desde muy temprano Omnis nos ha provisto de funciones 4GL que nos permitían buscar y seleccionar líneas en una lista, pero en Omnis Studio, disponemos de un potente método denominado $search. Por supuesto podrá seguir usando los comandos 4GL tradicionales. Sin embargo enseguida notará que puede conseguir mejores resultados si hace uso del método $search. A continuación se muestran algunos ejemplos, pero antes debemos explicar que el método $search, consta de los siguientes 5 parámetros:
- El primero, es la búsqueda en sí misma, un cálculo que será avaluado para cada línea de la tabla objeto de búsqueda. Podrá usarse “$ref” como puntero hacia la línea que está siendo evaluada.
- El segundo parámetro, determinará si la búsqueda deberá realizarse desde el principio. Si es “kTrue” la búsqueda comenzará desde la línea 1. No obstante es importante hacer notar, que si la línea actual es “0”, la búsqueda siempre comenzará desde el principio.
- El tercero nos permitirá indicar si la búsqueda deberá afectar sólo a las líneas actualmente seleccionadas o por el contrario a toda la lista. Si es “kTrue” sólo las líneas actualmente seleccionadas serán evaluadas.
- El cuarto parámetro nos permitirá marcar las líneas encontradas como seleccionadas.
- Finalmente, un quinto parámetro nos permitirá, realizar el proceso inverso al descrito en el parámetro anterior, es decir nos permite marcar las líneas halladas como no seleccionadas.
Éste primer ejemplo, nos permite localizar la línea que cumple con los criterios de búsqueda especificados:
; Siempre será necesario hacer uso de los 5 parámetros
If lvMiLista.$search($ref.MiColumna = 'Buscame',ktrue,kfalse,kfalse,kfalse)>0
; La encontré
Else
; No existe
End If
Selección de las líneas coincidentes con el criterio de búsqueda.
; Se usan los valores predeterminados para los parámetros
Do lvMiLista.$search($ref.MiColumna = 'Buscame')
Seleccionando todas las líneas.
Do lvMiLista.$search(kTrue)
Anulando la selección de todas las líneas.
; En este caso usamos un pequeño truco para anular la selección de sólo las líneas seleccionadas
Do lvMiLista.$search(kFalse,kTrue,kTrue)
Recorriendo las líneas seleccionadas.
; Aunque también es posible usar lvMiLista.$first(kTrue), poner $line a 0 nos ahorrará una línea de código
Calculate lvMiLista.$line as 0 ;; para comenzar desde el principio
While lvMiLista.$next(lvMiLista.$line,kTrue)
; Lo que quiera hacer
End While
Recorriendo las líneas coincidentes con el criterio de búsqueda, pero sin cambiar su estado actual.
Calculate lvMiLista.$line as 0 ;; para comenzar desde el principio
While
lvMiLista.$search($ref.MiColumna='Buscame',kfalse,kfalse,kfalse,kfalse)>0
; Lo que quiera hacer
End While
Y, finalmente, un interesante procedimiento que le permitirá localizar las líneas en una lista, de modo mucho más rápido que usando un $search, pero con las siguientes dos limitaciones:
- La columna objeto de búsqueda deberá contener un valor único.
- La lista deberá estar ordenada por la columna objeto de búsqueda.
Evidentemente la necesidad de tener que ordenar la lista previamente, rebajará la ganancia de rendimiento, pero si ya se han recuperado los datos ordenados o si se deben realizar muchas búsquedas, tal sobrecarga no tendrá importancia alguna, el método expuesto a continuación forma parte de una clase “table”, pero también podría estar en una clase “object” o “code”, a la que pasar la lista a tratar como un parámetro:
tTableClass.$quickSearch(char pvNombreColumna, fieldref pvValor,
int pvPrimeraLinea=1, int pvUltimaLinea=$cinst.$linecount)
--
;; Recuerde que la lista debe estar ordenada y la columna debe contener valores únicos
If pvPrimeraLinea>pvUltimaLinea ;; No hay lista
Calculate $cinst.$line as 0
Quit Method 0
End If
If $cinst.[pvPrimeraLinea].[pvNombreColumna]=pvValor
Calculate $cinst.$line as pvPrimeraLinea
Quit Method pvPrimeraLinea
Else If pvPrimeraLinea=pvUltimaLinea|$cinst.[pvPrimeraLinea].[pvNombreColumna]>pvValor ;; No está en la lista
Calculate $cinst.$line as 0
Quit Method 0
End If
If $cinst.[pvUltimaLinea].[pvNombreColumna]=pvValue
Calculate $cinst.$line as pvUltimaLinea
Quit Method pvUltimaLinea
Else If pvPrimeraLinea+1=pvUltimaLinea|$cinst.[pvUltimaLinea].[pvNombreColumna]
Calculate $cinst.$line as 0
Quit Method 0
End If
; Si se encuentra entre la primera y la última
Calculate lvLineaIntermedia as pvPrimeraLinea + ((pvUltimaLinea-pvPrimeraLinea)/2)
If lvLineaIntermedia=pvPrimeraLinea
Calculate lvLineaIntermedia as lvLineaIntermedia+1
Else if lvLineaIntermedia=pvUltimaLinea ;; ¿Podría suceder?
Calculate lvLineaIntermedia as lvLineaIntermedia-1
End If
If $cinst.[lvLineaIntermedia].[pvNombreColumna]=pvValor
Calculate $cinst.$line as lvLineaIntermedia
Quit Method lvLineaIntermedia
Else If $cinst.[lvLineaIntermedia].[pvNombreColumna]>pvValor
; Localizada en la zona alta de la lista
QuitMethod $cinst.$quickSearch(pvNombreColumna,pvValor,pvPrimeraLinea+1,lvLineaIntermedia-1)
Else
; Localizada en la zona baja de la lista
; Localizada en la zona baja de la lista
QuitMethod $cinst.$quickSearch(pvNombreColumna,pvValor,lvLineaIntermedia+1,pvUltimaLinea-1)
End If Ahora podrá hacer uso del “quicksearch”, mediante simplemente hacer un:
Calculate lvValor as 'MiValorUnico'
Do lvMiLista.$quickSearch('MiColumna',lvValor)
Do lvMiLista.$quickSearch('MiColumna',lvValor)
Suscribirse a:
Entradas (Atom)