Etiqueta

29 marzo 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”.

Pulse “doble-click” sobre la clase construida.

-->
 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 febrero 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:

  1. 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.
  2. 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.
  3. 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.
  4. El cuarto parámetro nos permitirá marcar las líneas encontradas como seleccionadas.
  5. 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:

  1. La columna objeto de búsqueda deberá contener un valor único.
  2. 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)
--
;; Algoritmo de búsqueda basado en los conocidos “QuickSort” y “QuickSearch”
;; 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];; No está en la lista
  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
 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)

03 febrero 2011

Conexión JDBC de Omnis Studio 5.1 a FileMaker 11


Acabo de conectar con éxito, en mi iMac a una fuente de datos FileMaker 11 desde Omnis Studio 5.1, a continuación explico los pasos que he dado:

  1. Copio el controlador JDBC de FileMaker 11 (fmjdbc.jar) sobre la carpeta "/Librería/Java/Extensions".

  2.  Activo la opción "Compartir JDBC/ODBC" de FileMaker.

  3. Creo la sesión mediante el SQL Browser de Omnis Studio, para la base de datos compartida mediante FileMaker, (en mi caso denominada "Prueba") tal y como se muestra en la siguiente imagen.


Y eso es todo, el atributo "$codepage" está fijado a "kUniTypeNativeCharacters" (valor por defecto, bajo la pestaña "Advanced") y todos los caracteres se visualizan perfectamente.