Etiqueta

Mostrando entradas con la etiqueta #AULAOMNIS. Mostrar todas las entradas
Mostrando entradas con la etiqueta #AULAOMNIS. Mostrar todas las entradas

5 de agosto de 2015

Gestión de sub-formularios dentro de un mismo panel o “Paged Pane”.

En éste artículo queremos destacar una, de las muchas cosas que nos ha traído la versión 6 de Omnis, se trata de la posibilidad de gestionar un grupo de subformularios dentro de un mismo contenedor, creando un efecto de paneles plegables al estilo de lo que sucede con el menú de un “Paged Pane”. Los diferentes subformularios quedan dispuestos verticalmente pudiendo ser expandidos o contraídos, haciendo clic/tocando sobre su barra de título o bien sobre el icono dispuesto al efecto


Configuración de los paneles


Para crear el grupo de paneles tendremos que hacer uso del método “clientcommand”  denominado “subformset_add”, junto con algunos nuevos parámetros, cuyas constantes podremos encontrar bajo el grupo ”Subform sets” y con el epígrafe “kSFSflag...”. El comando “subformset_add” creará el conjunto de subformularios dentro de la instancia “remote form” actual, tal y como si se tratase de un “Paged Pane”.

Do $cinst.$clientcommand("subformset_add",row-variable)

La variable de tipo “row” es definida como: row(grupo,padre,flags,orden,lista). A continuación describimos las principales banderas o “flags” que pueden ser usadas con el comando “subformset_add”.

kSFSflagOpenMin

Éste “flag” o bandera causa que el grupo de paneles se abra en estado minimizado. Normalmente, todos los subformularios se abren en estado de no-minimizado, de modo que deberemos hacer uso de ésta bandera para evitar su comportamiento predeterminado.

kSFSflagMinAsTitle

Cuando se minimiza un panel (subformulario) del grupo, se mostrará sólo la barra de título. Esta bandera anula su comportamiento predeterminado y que es ocultar completamente (cerrar) el subformulario. Para añadir el botón de minimizar a cada subformulario, deberá usarse la bandera “kSFSflagMinButton”, lo cual permite al usuario expandir o contraer el panel mediante su pulsación y no sólo mediante hacer clic en su título.

kSFSflagAutoLayout

Dispone automáticamente los paneles (subformularios del grupo) verticalmente dentro de su matriz, ignorando su posiciones originales “left” y “top”. Se activa la bandera  “kSFSflagMinAsTitle” y se desactivan “kSFSflagResize” y “kSFSflagMaxButton”. Si además activamos “kSFSflagAutoLayout”, el usuario podrá arrastrar y soltar la barra de título de los diferentes paneles del grupo, para reordenarlos, colocándolos en el orden que prefiera.

kSFSflagParentWidth

Sólo es aplicable si antes se ha activado “kSFSflagAutoLayout”. Su posición original “width” (ancho) será ignorada, tomándose en su lugar el ancho del subformulario “padre” para todo el grupo. También fija el “edgefloat” de cada subformulario a “kEFright”. De modo que, el uso de “kSFSflagParentWidth” nos permite, la creación de un “Paged Pane” compuesto a modo de varios paneles creados a partir de un grupo de subformularios, que se redimensionan o ajustan automáticamente dentro del panel que los contiene.

kSFSflagSingleOpen

Sólo es aplicable si antes se ha activado “kSFSflagAutoLayout” y “kSFSflagMinButton”. Permite asegura que al menos una ventana o panel esté siempre abierto.

 

Un ejemplo vale más que mil palabras


La imagen que mostramos al inicio de éste artículo, muestra un conjunto de paneles o grupo de subformularios contenidos en un “Paged Pane”, con las opciones “Auto Layout” y “Parent Width” activadas.

El método que mostramos a continuación, construye el grupo de subformularios asignándolo a un “Paged Pane” colcado a su vez dentro de un “remote form”. En el ejemplo, el subformulario tan solo contiene un campo de edición, con un pequeño texto ("This is panel #"). La lista o grupo de subformularios es construida incluyendo dicho texto, además del color de fondo, todo dentro de la variable “row” indicada para en el método “clientcommand” y su opción “subformset_add”.

; defina las variables para “lFormList”, “lSetRow” y para todas sus columnas
; construya el grupo de subformularios sobre “lFormList”
Do lFormList.$define(lFormID,lClassName,lFormParams,lFormTitle,lFormLeft,lFormTop,lFormWidth,lFormHeight)
Do lFormList.$add(1,'jsSubformSetPanelsSubForm',con(1,chr(44),rgb(221,221,255),chr(44),chr(34),"This is panel 1",chr(34)),'Panel 1',,,,160)
Do lFormList.$add(2,'jsSubformSetPanelsSubForm',con(2,chr(44),rgb(204,204,255),chr(44),chr(34),"This is panel 2",chr(34)),'Panel 2',,,,160)
Do lFormList.$add(3,'jsSubformSetPanelsSubForm',con(3,chr(44),rgb(187,187,255),chr(44),chr(34),"This is panel 3",chr(34)),'Panel 3',,,,160)
Do lFormList.$add(4,'jsSubformSetPanelsSubForm',con(4,chr(44),rgb(170,170,255),chr(44),chr(34),"This is panel 4",chr(34)),'Panel 4',,,,160)
; defina la variable “row” para el comando “subformset_add” como “lSetRow”
Do lSetRow.$define(lSetName,lParent,lFlags,lOrderVar,lFormList)
Do lSetRow.$assigncols("SubformPanelsSet",'PagedPane:1',kSFSflagSingleOpen+kSFSflagMinButton+kSFSflagAutoLayout+kSFSflagParentWidth,'iOpenForms',lFormList)
Do $cinst.$clientcommand("subformset_add",lSetRow)

En este caso las banderas “kSFSflagSingleOpen”, “kSFSflagMinButton”, “kSFSflagAutoLayout” y “kSFSflagParentWidth” son sumadas para dotar al grupo en construcción de todas las propiedades simultáneamente.

29 de julio de 2015

Controlando la entrada de datos en formularios (Form Errors)

Ahora es posible mostrar etiquetas de error, que guíen al usuario durante la introducción de valores en los campos de un formulario web, podremos hacer que (dichas etiquetas) se muestren a la derecha o debajo de los campos de entrada de un "remote form". Esta nueva característica hará más fácil a los usuarios rellenar formularios en la web y en nuestras aplicaciones móviles, de éste modo podremos realizar una validación dinámica e interactiva del formulario. Los errores aparecen en el formulario como etiquetas de texto "text field", y situados bajo un control o a su derecha, por lo que será necesario diseñar los "remote form" de modo que dejen el espacio necesario para que sea posible mostrar el texto de error. El estilo del texto, puede indicarse mediante HTML o CSS.


Descripción y uso de sus propiedades


$errortext


Todos los controles "jsClient" soportan la propiedad "$errortext", ésta propiedad es la que deberá contener el texto a mostrar cuando se produzca un error sobre el campo o control en uso. Inicialmente no contendrá valor alguno.

$errortextpos

La propiedad "$errortextpos" permite especificar la posición del texto de error. Sus posibles valores son:
  • kJSErrorTextPosUnder (El texto de error será mostrado bajo el control. Es también, su valor predeterminado.)
  • kJSErrorTextPosRight (El texto de error será mostrado a la derecha del control.)

Tenga en cuenta que Omnis deberá guardar valores para cada "$errortextpos", según los diferentes y posibles tamaños de pantalla. Durante el diseño del formulario, deberá mantener pulsada la tecla "control", para asignar un valor diferente según los tamaños de pantalla a soportar.

$errorline

La propiedad "$errorline" sólo puede ser usada en modo "tiempo de ejecución" o "runtime" y permite la asignación de "$errortext" a un objeto localizado dentro de una fila en un control "Complex Grid". Contendrá el número de la fila sobre la que aplicar el texto.

 

Eliminación de los textos mostrados


Un nuevo comando de tipo "client command", denominado "clearerrors" nos permite eliminar todos los mensajes de error mostrados sobre un formulario.

Do $cinst.$clientcommand(“clearerrors")


Ésta acción es equivalente a la asignación de un "$errortext" vacío para todos los controles del formulario con texto de error asignado.

 

Modificación del estilo del texto


A continuación indicamos las clases CSS que controlan la apariencia y bordes del texto. Podrá encontrarlos sobre el fichero "omnis.css".
  • div.om-error-text (Clase con lo estilos aplicables el texto de error.)
  • div.om-error-border (Configura los márgenes del "div" con el texto de error.)

22 de julio de 2015

Autenticación “Web Service”

A continuación describimos cómo configurar nuestro servidor web para que soporte autenticación “Web Service” basados en “REST”. (Disponible desde Omnis Studio 6.1.)

Por supuesto deberemos configurar nuestra librería Omnis, pero al margen de esto y cuando estamos utilizando un “simple” servidor Web (es decir no un servicio incorporado mediante Tomcat), podemos configurar la dirección URL del servicio web para que soporte autenticación básica (basic) o implícita (digest). También dispondremos de la opción de usar https y certificación para dar soporte a conexiones seguras.

A continuación incluimos algunas notas sobre cómo configurar Tomcat, Apache Web Server y IIS para que soporten autenticación básica (basic) o implícita (digest). Si así lo hacemos, el servidor Web será el encargado de autenticar a los clientes, a Omnis sólo pasará la solicitud una vez que cliente se ha autenticado correctamente; las cabeceras HTTP incluirán los datos con los detalles correspondientes, el llamado “Authorization header”.

Omnis Studio 6.1 posee una nueva función denominada parsehttpauth(auth) que permite examinar el contenido HTTP del “Authorization header”, ésta nos devolverá una variable de tipo “row” con la información extraída. La primera columna de la “row” con el nombre “scheme”, es el tipo de esquema (por ejemplo “basic”). El contenido del resto de las columnas, dependerá del tipo de esquema de que se trate. Por ejemplo, para las cabeceras siguientes:

Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

La “row” devuelta contendrá las siguientes 3 columnas:
  • scheme: basic
  • username: Aladdin
  • password: open sesame

Digest username="Mufasa",realm="testrealm@host.com",nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",uri="/dir/index.html",qop=auth,nc=00000001,cnonce="0a4f113b",response="6629fae49393a05397450978507c4ef1",opaque="5ccc069c403ebaf9f0171e9517f40e41"


La “row” devuelta contendrá las siguientes 10 columnas:
  • scheme: digest
  • username: Mufasa
  • realm: testrealm@host.com
  • nonce: dcd98b7102dd2f0e8b11d0f600bfb0c093
  • uri: /dir/index.html
  • qop: auth
  • nc: 00000001
  • cnonce: 0a4f113b
  • response: 6629fae49393a05397450978507c4ef1
  • opaque: 5ccc069c403ebaf9f0171e9517f40e41

OAuth realm="Example",oauth_consumer_key="0685bd9184jfhq22",oauth_token="ad180jjd733klru7", oauth_signature_method="HMAC-SHA1",oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D", oauth_timestamp="137131200",oauth_nonce="4572616e48616d6d65724c61686176",oauth_version="1.0"

La “row” devuelta contendrá las siguientes 9 columnas:
  • scheme: oauth 
  • realm: Example
  • oauth_consumer_key: 0685bd9184jfhq22
  • oauth_token: ad180jjd733klru7
  • oauth_signature_method: HMAC-SHA1
  • oauth_signature: wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D
  • oauth_timestamp: 137131200
  • oauth_nonce: 4572616e48616d6d65724c61686176
  • oauth_version: 1.0

Bearer 0b79bab50daca910b000d4f1a2b675d604257e42


La “row” devuelta contendrá las siguientes 2 columnas:
  • scheme: bearer
  • token: 0b79bab50daca910b000d4f1a2b675d604257e42

Para cualquier otro tipo de “scheme”, la “row” devuelta contendrá las siguientes 2 columnas:

  • scheme: nombre del esquema en minúsculas
  • data: resto de datos de la cabecera

Tomcat


Lo descrito a continuación ha sido testado con Tomcat 7.0.42 y Windows 8.1. Será necesario reiniciar Tomcat para que los cambios tengan efecto.

 

Autenticación “basic”


Configure el/los usuarios: Editando el fichero “conf/tomcat-users.xml”:

Añada el/los perfil(es) y usuario(s) bajo el item ≤tomcat-users≥, por ejemplo:

≤role rolename="omnisrest"/≥
≤user username="bobm" password="bobm" roles="omnisrest"/≥


Edite el fichero “web.xml” del “webapp” “omnisrestservlet” (carpeta WEB-INF);

Agregue lo siguiente después del item “servlet-mapping”:

≤security-constraint≥
≤web-resource-collection≥
≤web-resource-name≥All resources≤/web-resource-name≥
≤url-pattern≥/*≤/url-pattern≥
≤/web-resource-collection≥
≤auth-constraint≥
≤role-name≥omnisrest≤/role-name≥
≤/auth-constraint≥
≤user-data-constraint≥

≤!—el “transport-guarantee” podrá ser CONFIDENTIAL, INTEGRAL, o NONE --≥
≤transport-guarantee≥NONE≤/transport-guarantee≥
≤/user-data-constraint≥
≤/security-constraint≥
≤login-config≥
≤auth-method≥BASIC≤/auth-method≥
≤realm-name≥omnisrest≤/realm-name≥
≤/login-config≥

 

Autenticación “digest”


Igual que el anterior, excepto que el “auth-method” deberá ser “DIGEST”.

Probando el servicio SSL

Sobre el fichero “conf/server.xml”:

Elimine el comentario del conector SSL y modifíquelo, para dejarlo en algo como:

≤Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="C:\apache-tomcat-7.0.42\mykeystore" keystorePass="xxxxxx"/≥

Cree el certificado auto firmado para añadirlo al “keystore” de “tomcat”:

Nota: Será necesario indicar un nombre y apellido para el “localhost” (eso nos permitirá probar el servidor localmente, con “OWEN” como cliente)

"C:\Program Files (x86)\Java\jdk1.6.0_37\bin\keytool" -genkeypair -alias mycert -keyalg RSA - validity 10000 -keystore c:\apache-tomcat-7.0.42\mykeystore

Uso del cliente Omnis “OWEB” para pruebas:

Extracción del certificado:

"C:\Program Files (x86)\Java\jdk1.6.0_37\bin\keytool" -exportcert -alias mycert -keystore c:\apache-tomcat-7.0.42\mykeystore -file my_root_cert

Importación del certificado al “omnisTrustStore”:

cd \secure\cacerts

"C:\Program Files (x86)\Java\jdk1.6.0_37\bin\keytool" -importcert -alias my_tomcat - keystore omnisTrustStore -file c:\apache-tomcat-7.0.42\my_root_cert

Ahora podrá utilizar URLs como:

https://localhost:8443/omnisrestservlet/ws/5988/api/phase2/myapi/conTomcat

Nota: para eliminar la copia de un certificado use:

"C:\Program Files (x86)\Java\jdk1.6.0_37\bin\keytool" -delete -alias my_tomcat -keystore omnisTrustStore

 

Apache Web Server


Autenticación “basic”


Cree un usuario y su contraseña:

c:\apache24\bin\htpasswd -c c:\apache24\test_passwords test

Note: -c is optional - required the first time to create the passwords file

Edite el fichero “httpd.conf”, la entrada “omnisrest” deberá ser algo como esto:

≤Location /omnisrest≥
     SetHandler omnisrest
     AuthType Basic
     AuthName "omnisrest"
     AuthBasicProvider file
     AuthUserFile c:\apache24\test_passwords
     Require user test
≤/Location≥


El “Require” podrá ser “Require user...”, “Require valid-user” o “Require group...”. Consulte la documentación de Apache para más información.

 

Autenticación “digest”


Cree un usuario y su contraseña:

c:\apache24\bin\htdigest -c c:\apache24\test_digest_passwords omnisrest test
Nota: El uso de “-c” es opcional, pero necesario para la primera vez que se crear el archivo de contraseñas.

Edite el fichero “httpd.conf”, la entrada “omnisrest” deberá ser algo como esto:

≤Location /omnisrest≥
     SetHandler omnisrest
     AuthType Digest
     AuthName "omnisrest"
     AuthDigestDomain /omnisrest/
     AuthDigestProvider file
     AuthUserFile c:\apache24\test_digest_passwords
     Require valid-user
≤/Location≥


Des comente la entrada “LoadModule auth_digest_module modules/mod_auth_digest.so” del fichero “httpd.conf”.

El “Require” podrá ser “Require user...”, “Require valid-user” o “Require group...”. Consulte la documentación de Apache para más información.

IIS


Autenticación “basic”


IIS es bastante difícil de configurar (o al menos el “IIS Express” donde ha sido probado). Para habilitar el modo de autenticación “basic”, es necesario deshabilitar la autenticación “anonymous” del archivo “AppServer\applicationhost.config” ubicado bajo el directorio de instalación de IIS Express. Búsqueda la entrada “authentication” correspondiente.

Añada el código siguiente al final del archivo “applicationhost.config”:

≤location path="Default Web Site/cgi-bin/omnisrestisapi.dll"≥
≤system.webServer≥
≤security≥
≤authentication≥
≤basicAuthentication enabled="true" /≥
≤/authentication≥
≤/security≥
≤/system.webServer≥
≤/location≥


Después, podrá utilizar cualquier usuario existente y su contraseña con las URLs protegidas – se necesita disponer de una cuenta de usuario “standard” para que funcione.

16 de julio de 2015

Formato del método $showurl

Sintaxis: $showurl(cURL[,cFrame,cWindowProperties])

cURL: Es la dirección de la página a presentar en una nueva ventana o el marco específico de la venta cliente en la página HTML.

cFrame: Es el nombre de un marco HTML. Si cFrame está vacío, la página se mostrará  en una nueva ventana, de lo contrario se mostrará en el marco especificado y sobre la ventana actual.

cWindowProperties: Parámetro opcional, si no existe cFrame será ignorado. De lo contrario, tiene el mismo formato que en los argumento del comando javascript equivalente el "window.open", por ejemplo, especificar "toolbar = 0, menubar = 1" indicaría que la ventana del navegador tendrá una barra de menú, pero no una barra de herramientas.

Sus posibles opciones son:

toolbar - si la ventana del navegador tendrá una barra de herramientas
status - si la ventana del navegador tendrá una barra de estado
menubar - si la ventana del navegador tendrá una barra de menú
scrollbars - si la ventana del navegador tendrá barras de desplazamiento
resizable - si la ventana del navegador es de tamaño variable
location - si la ventana del navegador tendrá una barra para direcciones
directories - si la ventana del navegador mostrará el directorio Web
width - anchura de la ventana del navegador
height - altura de la ventana del navegador
top  - coordenada superioresde la ventana del navegador
left - coordenada izquierda de la ventana del navegador

Todas las opciones son booleanas (sólo valores 0 o 1) a excepción de la width, height, top y left, que deberán contener valores expresados en píxel's.

15 de julio de 2015

Uso de la utilidad del sistema "ditto" de Mac OS, desde Omnis

Crear un Zip, basePath y destName son las respectivas rutas de origen y destino del archivo.


Begin text block
    Text: set dir to "[basePath]" as string (Carriage return)
    Text: set dest to "[destName]" as string (Carriage return)
    Text: set scriptText to "ditto -rsrc -c -k --sequesterRsrc --keepParent " & quoted form of the POSIX path of dir & " " & quoted form of the POSIX path of dest (Carriage return)
    Text: do shell script scriptText
End text block
Get text block script
Do $runapplescript(script,result) Returns error


Descomprimir un Zip, basePath y destName son las respectivas rutas de origen y destino del archivo.


Begin text block
    Text: set dir to "[basePath]" as string (Carriage return)
    Text: set dest to "[destName]" as string (Carriage return)
    Text: set scriptText to "ditto -rsrc -x -k " & quoted form of the POSIX path of dir & " " & quoted form of the POSIX path of dest (Carriage return)
    Text: do shell script scriptText
End text block
Get text block script
Do $runapplescript(script,result) Returns error


Esto eliminaría el archivo temporal después de la copia/descompresión.


Begin text block
    Text: set source to "[pFrom]" as string (Carriage return)
    Text: set targetdir to "[pTo]" as string (Carriage return)
    Text: tell application "Finder" (Carriage return)
    Text: duplicate source to targetdir (Carriage return)
    Text: end tell
End text block
Get text block lScript
Do $runapplescript(lScript,lResult) Returns lnError

8 de julio de 2015

Cómo hacer aparecer una animación durante la carga del "remote form" inicial.

Tomando como base un documento HTML entandar para la llamada a un "remote form", necesitaremos realizar lo siguiente:

1) Eliminar las líneas siguientes:


2) Reemplazarlas por:


Obviamente, deberemos substituir el fichero GIF, por el que sea más apropiado.

3) Modificar el "remote form" indicado en el HTML

Añadir (si no existe), un método de tipo "client executed" denominado "$init" que deberá incluir la línea siguiente :

    JavaScript: clearSplash();

Ha de ser así, puesto que necesitamos eliminar el "splash" después de que termine el "jOmnis.onLoad()" y el $init es ejecutado exactamente cuando eso sucede, sin embargo, debemos tener en cuenta que el "$construct" aún no se habrá ejecutado, por lo que aún habrá una demora hasta que el cliente toma el control.

Para probarlo, podemos (por ejemplo) añadir al "$construct" el código siguiente, con intención de simular un retraso durante la carga del "remote form":

Do iMegaList.$define("","","")
For i from 1 to 50000 step 1
    Do iMegaList.$add("AAA","BBB","CCC")
End For


Eso es todo, espero sus comentarios, reciban un saludo.

1 de julio de 2015

Función para la generación de contraseñas

La función permite ser invocada con o sin parámetro del modo siguiente:

    Do method $PassGen() Returns Password

Por ejemplo devolvería: Password = x32Vn1

o mediante la especificación un parámetro con la longitud deseada:

    Do method $PassGen(4) Returns Password

Por ejemplo devolvería: Password = 4cB3

Definición de la función:

;  autor        ;; Florent Pousserot
;  método       ;; $PassGen
;  descripción  ;; Generación aleatoria de contraseñas
;  parametros   ;; Parametro 1: Longitud de la contraseña deseada.

                   Por defecto 6 caracteres
;  devuelve     ;; La contraseña generada

Do zlCharAuthorize.$define('char')

For x from 48 to 57 step 1     ;; códigos ascii [0-9]
    Do zlCharAuthorize.$add(chr(x))
End For

For x from 97 to 122 step 1     ;; códigos ascii [a-z]
    Do zlCharAuthorize.$add(chr(x))
End For

For x from 1 to pcPassLength step 1
    Calculate zlCursor as randrealrng(1,36)     ;; devuelve un valor aleatorio entre 1 y 36 ; representa [0-9,a-z] <=> [10+26]
    If mod(x,3)     ;; modulo 3
        Calculate zcPassword as con(zcPassword,zlCharAuthorize.[zlCursor].C1)     ;; minúscula
    Else
        Calculate zcPassword as con(zcPassword,upp(zlCharAuthorize.[zlCursor].C1))     ;; mayúscula
    End If
End For

Quit method zcPassword

24 de junio de 2015

Las variables de entorno en Omnis Studio

¿Qué son las variables de entorno?


Cuando arranca un proceso en un equipo, éste inicia algunas variables con información sobre su entorno de trabajo. Generalmente se trata de rutas de acceso (como por ejemplo la ruta del programa en ejecución) o de la iniciación de algunas constantes, como el nombre del usuario actual, el nombre del equipo, etc. Dichas variables están (normalmente) accesibles para todos los programas ejecutados en ese mismo entrono de trabajo.

Por supuesto los programas también pueden hacer uso de variables de entorno con información sólo relevante a si mismos. En éstos casos, dichas variables son algo así como los ajustes de preferencias, excepto que no son exclusivos del programa, ya que también son variables globales, (como las preferencias del sistema) aunque su uso está pensado para usuarios individuales y no para todo el equipo.

 

Variables de entorno: Del Sistema y de los Usuarios.


En Windows, disponemos de dos niveles de variables de entorno: Las variables del sistema y las del usuario. Las variables del sistema sólo pueden ser modificadas por un usuario con categoría de administrador. Normalmente no modificaremos éstas variables, ya que, si lo hacemos, será necesario reiniciar el equipo para que el sistema reconozca y use los cambios.

Las variables de usuario, engloban tanto variables definidas por el propio usuario, como las creadas mediante los diferentes programas. Podemos editarlas y utilizar sus nuevos valores sin tener que reiniciar el equipo. El programa desde el cual modificamos una variable de entorno, podrá hacer un uso inmediato del nuevo valor, pero si existen otros programas que quieren hacer uso de esos mismos cambios, deberán ser reiniciados.

 

Diferencias entre plataformas


Dado que, con Omnis Studio podemos escribir aplicaciones multiplataforma, deberemos ser conscientes de las diferencias que se producen entre éstas y sus variables de entorno. Sera absolutamente necesario, que el código escrito para manejar variables de entorno, lo esté del modo esperado para la plataforma en uso, es decir, sobre la que nuestra aplicación esté siendo ejecutada.

Atendiendo a la plataforma Windows, podemos ver (view) (pero no editar) las variables de entorno, mediante la aplicación “System Information”. Accedemos a esta aplicación siguiendo la siguiente ruta desde el menú “inicio” o “Start”: “menu≥Accessories≥System Tools≥System Information”. Podrá ver algo como lo siguiente:


En Windows, las variables de entorno pueden ser gestionadas manualmente, mediante el panel de control del sistema (“System Control Panel”) y su pestaña “Avanzadas” (“Advanced”). Podremos acceder a el, abriendo el directorio de paneles de control, para desde allí ir al panel de control del sistema y seleccionar su pestaña “Avanzadas”, finalmente, tendremos que hacer clic sobre los botones, para ver algo parecido a lo siguiente:


Los usuarios con privilegio de administradores, podrán ver y manipular tanto variables de usuario, como del sistema, mientras que el resto sólo podrán acceder a las de usuario.

Para Mac OS X, las variables de entorno de usuario están registradas en un fichero de tipo “property list” denominado “environment.plist”, localizado en un directorio no-visible denominado “.MacOSX”, ubicado dentro del directorio principal o raíz del usuario. Por defecto, este archivo y su directorio no existen, por lo que deberán ser creados para su uso, pero ha de tener en cuenta, que algunos programas los crean durante su instalación.

Una vez creado, el usuario podrá hacer uso de la aplicación “Property List Editor” (forma parte del conjunto de herramientas para desarrollo Xcode) para editarlo. Debería ver algo similar a los siguiente:


También podremos ver el contenido XML del archivo desde el terminal, escribiendo:

more ~/.MacOSX/environment.plist

En cuanto a las “rutas” o “paths” guardados en las variables de entorno, también (lógicamente) existen diferencias entre plataformas. La mayoría usan rutas de tipo POSIX, que hace uso del carácter barra diagonal (/) para separar los diferentes niveles de directorio. Sin embargo en DOS se hace uso de la barra invertida (\).

 

Valores alternativos


Una variable de entorno puede contener más de un valor. Por ejemplo, una variable que contiene una ruta hacia un archivo, podría contener rutas alternativas para indicar otras posibles ubicaciones. Al ser requerida por un programa, intentará localizar el archivo en la primera ruta indicada, pero si no lo encuentra, hará uso de la ruta alternativa.

Los valores alternativos deberán estar separados entre si, mediante el uso de un carácter delimitador. Aquí nos enfrentamos a otra diferencia entre plataformas. Para las que usan el formato POSIX, el carácter delimitador son los dos puntos (:). En DOS es el punto y coma (;). Por ejemplo y suponiendo una variable de entorno denominada PROGRAMPATH y que va a ser usada para localizar el mismo programa, pero con dos posibles nombres (“miPrograma” y “miOtroPrograma”), su valor podría ser el siguiente:

En Mac OS X: /Applications/miPrograma:/Applications/miOtroPrograma

En Windows: C:\Program Files\miPrograma;C:\Program Files\miOtroPrograma
 

 

¿Cómo usa las variables de entrono Omnis Studio?


El ejemplo más común, es el que tiene que ver con el uso de los componentes Java con Omnis Studio. Omnis Studio necesita saber dónde encontrar las clases Java en cada una de las plataformas, excepto en el caso de Mac OS X. Para ello, consulta las variables de entorno CLASSPATH y OMNIJVM. Podrá obtener más información sobre como configurar y asignar valores a estas variables consulte el Manual de “Programación Omnis” en castellano, a partir de su página 584.

Por defecto, el valor de CLASSPATH apunta al directorio que debería contener las clases de Java no usadas por Omnis Studio, pero, para indicar los directorios que contienen las clases Java que usaremos con nuestras aplicaciones Omnis, disponemos de la variable OMNISCLASSPATH.

Por supuesto, también podemos optar por configurar y utilizar nuestras propias variables de entorno con otros fines. Tal vez para indicar un directorio externo donde alojar archivos de imagen o informes “adhoc”. Por ejemplo, podríamos crear una variable de entorno (llamada CUSTOMPATH o algo similar) su uso se hará de modo similar al de la función sys(). Si no disponemos de herramientas para crear y manipular variables de entorno, podemos crear fácilmente nuestra propia utilidad con Omnis Studio...

 

Funciones para el uso de variables de entorno


Una alternativa a la configuración o ajuste manual de las variables de entorno mediante el Panel de Control (en Windows) o el editor “Property List” (en Mac OS X), podemos optar por hacerlo desde dentro de nuestros programas Omnis. Bajo la pestaña “General” de la ventana “Catalog” de Omnis Studio, encontramos las funciones: listenv(), setenv(), getenv() y putenv().

La función listenv() devuelve una lista con las variables de entorno de usuario, junto con sus correspondientes valores. Tenga en cuenta que no se requieren parámetros para esta función. La lista devuelta, contiene dos columnas denominadas “name” y “value”. Ambas columnas son de tipo carácter. La columna “name” está limitada a 255 caracteres, pero la columna “value” no está limitada. A continuación mostramos lo que típicamente se obtendría bajo la plataforma Mac OS X:



Tenga en cuenta que no todas las variables que se muestran son realmente de utilidad para Omnis Studio. Por ejemplo, con Omnis Studio 4.2, sólo las indicadas en el fichero “odbc.ini” son usadas.

En un entorno Windows, se obtendría algo similar a los siguiente:


Si bien se muestran muchas y diferentes variables, son muy pocas las que podemos utilizar con Omnis Studio, pero eso puede ir cambiando según la versión.

Todo lo que necesitamos saber es el nombre de la variable de entorno que deseamos consultar. Después, podemos usar la función getenv() de modo similar a como usamos la función sys() para recuperar su valor. El nombre de la variable debe ser indicado como parámetro de la función. Por ejemplo, para saber el nombre del usuario actual, usaríamos:

getenv('USERNAME')

Observe que el nombre de la variable de entorno debe ser indicada como una cadena entre comillas, aunque también podría estar contenida en una variable Omnis Studio. Si la variable que solicitamos no existe, la función devolverá un valor vacío.

Pero también puede ser que en algún momento desee modificar el valor de una variable de entorno. La función putenv() permite que lo hagamos. Esta función requiere dos parámetros: el nombre de la variable de entorno cuyo valor queremos modificar y el valor que queremos asignarle. Una ventaja adicional de esta función es que (si no existe) la variable es añadida al conjunto, así que ¡tenga cuidado con la ortografía y el uso de mayúsculas! Por ejemplo, si queremos crear o modificar una nueva variable de entorno denominada “OMNISREPORTPATH” y asignarle el valor “/Users/david/OmnisReports” usaríamos lo siguiente:

putenv('OMNISREPORTPATH','/Users/david/OmnisReports')

Si lo que quisiéramos fuera añadirle una ruta alternativa (cuando sabemos que ya contiene una), podríamos utilizar:

putenv('OMNISREPORTPATH',con(getenv('OMNISREPORTPATH'),':/Users/david/OmnisReports'))

Estos ejemplos son de Mac OS X, pero podrá encontrar con facilidad su equivalente Windows.

 

¿Ha encontrado útil éste artículo?


Recuerde que es necesario configurar manualmente las variables de entorno para utilizar clases Java dentro de nuestras aplicaciones, por lo que podemos utilizar estas nuevas funciones para simplificar el proceso de configuración para nuestros usuarios finales.

Espero con interés sus comentarios al respecto, reciban un saludo.

Como crear una row a partir de una clase "file"

Do miRow.$cols.$sendall(miRow.[$ref.$name].$assign(miClaseFile.[$sendallref.$name]))

17 de junio de 2015

Creación de códigos de barras en formato “Code 128”

El método que presentamos en éste artículo, requiere del uso de la fuente o tipo de letra “Code 128 Barcode” de IDAutomation. La generación de códigos de barras en formato ”Code 128” permite el uso de números, símbolos, y letras (mayúsculas o minúsculas) en el texto, pero tal flexibilidad hace que todas las fuentes para la generación de códigos de barras “Code 128” requieran un carácter de inicio, el carácter de suma de comprobación, y un carácter de parada, a fin de generar códigos de barras legibles, es decir que puedan ser leídos por cualquier lector con soporte “Code 128”.

Lo que deseamos mostrar en éste artículo, es un ejemplo sobre cómo realizar el cálculo para la composición de dicho código desde Omnis Studio. IDAutomation, dispone de otras fuentes o tipos de letra, más fáciles de usar, como el correspondiente al “Code  39”, que no requiere de sumas de comprobación u otros cálculos.

El código Omnis que mostramos a continuación ha sido escrito para el “Code 128” y la fuente de  IDAutomation de tipo C para Mac.


10 de junio de 2015

Como programar la impresión de rangos de páginas

Se debe tener en cuenta que (cuando no se especifican rangos de páginas) el administrador de impresión, construye previamente todas las páginas del informe, quedando temporalmente almacenadas en el disco. Sólo entonces son enviadas al dispositivo impresor. De hecho la ejecución del método “$ejectpage” no tiene efecto alguno hasta haber concluido los trabajos previos. Éste comportamiento es ligeramente diferente, cuando no se especifican rangos de páginas, en estos casos, el administrador de impresión expulsará las páginas tan pronto como se completan, excepto si la eyección automática está desactivada.

Algunos dispositivos (según el destino elegido para el informe) no soportan rangos de páginas. De hecho, (aparte de cualquier impresora) sólo los dispositivos de “pantalla” y ”vista previa” soportan actualmente rangos de páginas. Cómo siempre los rangos de páginas puede ser especificadas desde el diálogo de configuración del trabajo de impresión, pero en éste artículo lo que vamos a ver es, cómo hacerlo desde programación.

 

El componente “screen report field”


Éste componente contempla el método “$redirect”, el cual es usado para re-enviar el informe hacia otro dispositivo y la propiedad “$root.$prefs.$pages” puede ser utilizada para especificar el rango de páginas a enviar, a continuación mostramos un ejemplo:

Calculate $cdevice as kDevPrinter
Calculate $prefs.$pages as "20-1"
Do $cobj.$redirect(kFalse)
Calculate $prefs.$pages as ""

 

Rangos posibles


Los rangos de página que pueden ser especificados en “$root.$prefs.$pages” o en “$cinst.$pages”, si queremos que afecte sólo al informe en uso. Son los siguientes:
  • “1,3,5,2,4”
  • Imprimirá las páginas especificadas y en el orden en que se indican.
  • "1-10,30-35"
  • Imprimirá páginas de la 1 a la 10 y después las páginas de la 30 a la 35.
  • "O1-10, E1-10"
  • Imprimirá primero todas las páginas impares que se encuentren entre la 1 y la 10, después todas las páginas en el rango de 1 a 10.
  • "30-1"
  • Imprimirá las páginas de la 1 a la 30, pero en orden inverso.
  • "C"
  • Imprimirá la página en ese momento visible  (obviamente sólo utilizable junto con el método “$redirect” del componente “screen report field”).

Por supuesto podemos realizar cualesquiera combinaciones, basándonos en las reglas anteriores, si una página aparece más de una vez se imprimirá también más de una vez.

3 de junio de 2015

Uso de ODB en Windows

El manual Omnis sobre ODB (el odb.pdf) explica exhaustivamente el uso de ésta útil herramienta que nos permite construir un servidor de base de datos con nuestros df1, por lo que en éste artículo, sólo mostraré algunos de los últimos cambios introducidos y en concreto para la plataforma Windows. Recordemos que su última versión disponible es la 1.6.5

Uno de éstos cambios es que el ODB para ésta plataforma es ahora una aplicación sólo ejecutable desde la línea de comandos de Windows, habiendo sido eliminada la anterior aplicación denominada ODBService.exe.

Como iniciar ODB en Windows 2000/XP/Vista/7


Una vez actualizado el archivo de configuración con los detalles de los archivos de datos (ver el manual odb.pdf), podremos iniciar el ODB ejecutando el odbridge.exe ubicado en la carpeta ODB.
Abra el símbolo del sistema, (línea de comandos de Windows) sitúese sobre el directorio ODBC y escriba…

odbridge (o odbridge start)

...y pulse retorno.

Si todo ha funcionado como debe, verá lo siguiente:

Executing start...
...see messages.txt for success

Puede ver el contenido del fichero “messages.txt” de la carpeta ODBC para comprobar si el DB se ha iniciado correctamente. Si se ha producido un error este archivo contendrá los detalles del error, o (si todo fue bien) la línea siguiente:

ODB is now listening for requests from your clients

Nota: También es posible iniciar el ODB mediante hacer doble-clic en odbridge.exe mientras esté a la vista en una ventana. En este caso el servidor “data bridge” se iniciará de modo silencioso, pero aún se podrá consultar sobre su resultado en el archivo “messages.txt”.

Como parar el ODB


Para detener el servidor “data bridge”, escriba…

odbridge shutdown

…y pulse retorno.

Si todo ha funcionado como debe, verá lo siguiente:

Executing shutdown...
...see messages.txt for success

Si en el momento del cierre existen usuarios conectados, se producirá un error. En éste caso no es seguro que el ODB haya sido detenido realmente. Deberá asegurarse de que no existan usuarios conectados (es decir, que hayan cerrado sus archivos de datos) antes de volver a intentarlo.

Sin embargo, es posible forzar el apagado del OBD aún cuando existan usuarios conectados. Para ello escriba…

odbridge kill

…y pulse retorno.

Nota: Tenga en cuenta, que con esta acción se corre el riesgo potencial de corrupción del archivos de datos, si coincide que un usuario esté escribiendo en el archivo, durante el cierre.

Como instalar un servicio Windows para lanzar el ODB


Puede instalar el ODB como un servicio Windows, con el fin de que sea iniciado automáticamente junto con el sistema. Para ello, asegúrese primero de que el OBD no este ejecutándose, después, escriba…

odbridge install

…y pulse retorno.

Si todo ha funcionado como debe, verá lo siguiente:

Installing “C:\....\odbridge.exe” as a service
The operation completed successfully.

En caso de producirse un error, en lugar de lo anterior verá el mensaje de error correspondiente. Por defecto, el servicio (denominado “Omnis Data Bridge”) es configurado para iniciarse automáticamente, pero, usted puede modificar dicha configuración desde “Panel de control≥≥Herramientas administrativas≥≥Servicios” si así lo desea.

Como eliminar el servicio Windows


Para detener y eliminar el servicio “Omnis Data Bridge”, escriba…

odbridge remove

…y pulse retorno.

Si todo ha funcionado como debe, verá lo siguiente:

Uninstalling service: odbridge
The operation completed successfully.

En caso de producirse un error, en lugar de lo anterior verá el mensaje de error correspondiente.

Nota: La eliminación del servicio es equivalente a ejecutar el comando “odbridge kill”. Por lo que, (como en el caso anterior) deberá asegurarse de que no existan clientes conectados antes de eliminarlo.

27 de mayo de 2015

Uso del nuevo archivo de configuración del servidor de aplicaciones

Desde Omnis Studio 6.1 se incluye un nuevo archivo de configuración en formato JSON denominado "config.json" y situado en la carpeta "studio".

Es utlizado para configurar el servidor de aplicaciones Omnis, incluyendo propiedades de arranque, modo de uso y otras concernientes al uso de servicios web (Web Services). También incluye una sección específica para activar la caché de clases Java y otros elementos.

Habitualmente la configuración del servidor Omnis Server puede hacerse mediante seleccionar la opción "Server Configuration" del menú "File" desde el propio Omnis Server, pero, ahora también podrá hacerse mediante la edición del fichero "config.json" usando para elo cualquier editor de texto compatible, pero el archivo debe ajustarse al formato JSON.

La primera parte del archivo "config.json" contiene la siguiente distribución:

{
    "server": {
    "port": 5988,
    "stacks": 20,
    "timeslice": 1,
    "webServiceURL": "",
    "webServiceConnection": "",
    "webServiceLogging": "full",
    "webServiceLogMaxRecords": 100,
    "webServiceStrictWSDL": true,
    "RESTfulURL": "",
    "RESTfulConnection": "",
    "start": false,
    "retryBind": false,
    "showBindRetryMessage": true,
    "bindAttempts": 10
    }
}

donde...
 
  • port, stacks, timeslice 
  • Permiten definir el modo en que se ejecutará el servidor Omnis.

  • webService...
  • Definen los servicios web basados en SOAP/WSDL.

  • RESTful...
  • Definen los servicios web basados en REST.

  • start
  • Si es "true" significa que el servidor Omnis será activado automáticamente al arrancar.

  • retryBind
  • La propiedad "retryBind" deberá establecerse a "false" si no se desea que el servidor Omnis vuelva a intentar la conexión al puerto especificado, tras un primer intento. Por defecto o si el parámetro es omitido "retryBind" es "true".

  • showBindRetryMessage
  • Si "retryBind" es "true", "showBindRetryMessage" determinará si se mostrará o no, un mensaje de estado durante el tiempo que se esté re-intentando la conexión.

  • bindAttempts
  • Si "retryBind" es "true", "bindAttempts" anula el número predeterminado de intentos de conexión, obligando al servidor Omnis a realizar un intento cada segundo.
 

20 de mayo de 2015

Texto HTML en botones

Una nueva característica soportada por los controles JavaScript "Button" y "TransButton" nos permiten aportar textos con etiquetas HTML a los botones.

Para ello deberemos fijar su nueva propiedad "$textishtml" a "true"
, ésto afectará al modo en que será tratado el texto indicado para el botón (propiedad $text), el cual podrá ahora contener etiquetas HTML, ésto significa que podremos hacer uso de cualquier etiqueta HTML para aportar estilo al texto. Por ejemplo, podríamos insertar un salto de línea mediante la etiqueta "≤br≥".

La activación de la propiedad "$textishtml", no impide el uso del resto de atributos ya presentes para los controles de botón mencionados, por lo que no habrá problema alguno en seguir usando los elementos habituales para la asignación de estilo, tipo de letra y color.

Tenga en cuenta que modo-diseño no podremos observar el resultado de aplicar la etiqueta HTML (sólo veremos el código HTML) y si usamos atributos dentro del código HTML deberán ir situados entre comillas simples.

13 de mayo de 2015

Probando nuestros "remote forms"

Si estamos usando Firefox durante el desarrollo de aplicaciones con Omnis, podemos usarlo para probar los diferentes diseños y tamaños de pantalla pensados para su uso en dispositivos móviles y tabletas mediante su utilidad "Vista de diseño adaptable", indicar que se trata de una característica del navegador Firefox y que Omnis puede aprovechar, pero que no parece estar disponible (por el momento) en otros navegadores.

Pero quiero hablar de ello en éste "blog", ya que nos puede ahorrar mucho tiempo a los desarrolladores Omnis, durante la fase de diseño de nuestras aplicaciones, ya que nos evitará tener que probar o testar la aplicación en múltiples dispositivos. Sin embargo, le recomiendo que finalmente también pruebe su aplicación sobre el o los dispositivos que usted desee estén soportados por su aplicación.


Para que Omnis pueda hacer uso de dicha funcionalidad del navegador, deberá establecer su propiedad "gResponsiveDesign" a "true", podrá encontrarla dentro del archivo "ssz.js" ubicado bajo el directorio "html/scripts" dentro del raíz Omnis. Tenga en cuenta que deberá reiniciar Omnis para que el cambio tenga efecto.


Finalmente y para activa el modo en Firefox, diríjase al menú "Herramientas" opción "Desarrollador web" y seleccione "Vista de diseño adaptable".


Una vez hecho ésto, podremos probar nuestros "remote form" seleccionando los diferentes tamaños de pantalla y orientaciones bajo el menú desplegable de la ventana del navegador Firefox, nuestro "remote form" cambiará según lo especificado en su propiedad $screensize. Cuando hayamos concluido con las pruebas, deberemos volver a cambiar la configuración de "gResponsiveDesign" del fichero "ssz.js" para dejarlo en modo "false".

6 de mayo de 2015

Paso de parámetros a un "remote form" mediante URL

Ahora es posible el paso de parámetros hacia un "remote form" o "remote task", desde el propio cliente de JavaScript y desde la URL de llamada a la página web que contiene su "remote form". Dichos parámetros aparecerán añadidos a los que ya pueda llevar emparejados la invocación al "remote form", recuerde que habitualmente el paso de parámetros estaba limitado a los incluidos en la propia página HTML mediante el uso de las etiquetas "data-param1", "data-param2", etc.

Los parámetros adicionales pueden ser añadidos en la URL que apunta al "remote form" mediante el siguiente formato:
 
http://127.0.0.1:5988/jschtml/rfSetCurField.htm?x=y&a=b 

El cliente JavaScript añadirá éstos parámetros mediante una columna opcional denominada "URLparams" añadida a la variable "row" que transfiere al método $construct() del "remote form" o "remote task". Los datos contenidos en "URLparams" son guardados en formato JSON, por ejemplo, si los parámetros del URL son "x=y&a=b", el fichero JSON contendrá la entrada {"x":"y","a":"b"}. Si lo desea, podrá hacer uso de la nueva función estática OJSON para convertir su formato original, a formato "row" de Omnis, mediante...

Do OJSON.$jsontolistorrow(pRow.URLparams) Returns lRow

...donde "lRow" es una variable Omnis de tipo "row". Suponiendo el ejemplo anterior, el valor de la expresión "lRow.x" sería "y" y el de "lRow.a" sería "b".

29 de abril de 2015

Ventanas adaptables (Sync Screens Tool)

¿Cómo funciona la nueva herramienta "Sync Screens"?


La idea es que, tras crear un "remote form", podamos formatear todos sus campos y controles para que aparezcan con el tamaño y posición correctos, según cada una de las posibles orientaciones y tamaños de pantalla, ya sean de tipo escritorio, tabletas o móviles. (según las diferentes configuraciones soportadas para la propiedad $screensize).

Sin duda se trata de una tarea que nos consume mucho tiempo a los desarrolladores, debido al gran número de diferentes dispositivos y diseños soportados por los "remote form".


Afortunadamente ésta herramienta nos permitirá realizar ésta labor de forma automática, lo que sin duda nos ahorrará mucho tiempo, además de hacer que nuestras aplicaciones sean más consistentes y fáciles de usar para los usuarios finales, puesto que se adaptarán al dispositivo en uso.


Podrá localizar la nueva herramienta "Sync screens" situada bajo el menú "Tools≥≥Add Ons".


Para utilizarla deberá seleccionar una biblioteca desde el desplegable "Library" y seleccionar el "remote form" JavaScript que desee sincronizar. Mediante el desplegable 'Source Screensize' podrá indicar cual es el punto de partida sobre el cual se construirán el resto de los tamaños seleccionados. (por defecto aparecerá seleccionado "desktop") Después, deberá elegir qué tamaños deberán sincronizarse mediante las casillas de verificación. Los elementos situados bajo "Options" le permitirán escalar o no los objetos, según su posición horizontal y/o vertical y/o según su anchura y altura. Si no desea que un objeto en particular sea alterado por la herramienta, puede optar por bloquearlo. Para ello y desde el modo-diseño, pulse botón derecho sobre el objeto y escoja la opción "Lock", la opción "Ignore Locked Components" (por defecto activada) le permitirá decidir si tal comportamiento deberá ser tenido en cuenta o no. Una vez realizados los ajustes pertinentes, haga clic sobre el botón "Sync".

Ahora podrá cambiar la propiedad $screensize de su "remote form", para comprobar el funcionamiento de los diferentes diseños seleccionados. Recomendamos que también realice pruebas en un navegador y en diferentes dispositivos para comprobar que los diferentes objetos del "remote form" se dimensionen y posicionen correctamente.

22 de abril de 2015

Como eliminar líneas duplicadas de una lista

El ejemplo siguiente une dos listas (listaUno y listaDos) sobre una nueva denominada listaUnida, para después eliminar de ella las líneas duplicadas, según el valor de la columna aValor.

Calculate listaUnida as listaUno
Do listaUnida.$merge(listaDos)
Do listaUnida.$sort($ref.aValor,kFalse)
Do listaUnida.$sendall($ref.$selected.$assign(kTrue),($ref.aValor=listaUnida.[$ref.$line+1].aValor)|(($ref.$line>1)&($ref.aValor=listaUnida.[$ref.$line-1].aValor)))
Do listaUnida.$remove(kListDeleteSelected)

El ejemplo siguiente está considerado como el más rápido de todos, para una "myList"  con 1578 filas de las cuales 250 están duplicadas, el tiempo fue de dos segundos.

Set current list (myList)
Set sort field (myCol)
Sort list
Set search as calculation {myList(1,#L)=myList(1,#L-1)}
Search list (Select matches (OR),Deselect non-matches (AND))
Delete selected lines

Aunque seguramente la mejor opción sea la apuntada por Xavier Blanco, que consiste en el uso del método predefinido "listaUnida.$cols.aValor.$removeduplicates(ktrue)" (Ver la página 101 del manual de programación en castellano).


15 de abril de 2015

Códigos de error y constantes FileOps

En ésta entrada os dejo el listado de las constantes disponibles para FileOps, los códigos de error a que corresponden y una breve explicación.


kFileOpsOK 0
Ejecutado con éxito
kFileOpsParamError 1 Faltan parámetros
kFileOpsOutOfMemory 12
Memoria insuficiente
kFileOpsDirFull -33 Fichero o directorio lleno
kFileOpsDiskFull -34
Disco lleno
kFileOpsVolumeNotFound -35 El volumen especificado no existe
kFileOpsDiskIOError -36
Error de disco E/S
kFileOpsBadName -37 Nombre de archivo o volumen incorrecto (tal vez sin nombre)
kFileOpsFileNotOpen -38
Archivo no abierto
kFileOpsEndOfFile -39 Se llegó al final del archivo durante una operación de lectura
kFileOpsPositionBeforeStart -40
Intento de posicionarse en un lugar anterior al inicial del archivo
kFileOpsTooManyFilesOpen -42 Se han abierto demasiados archivos
kFileOpsFileNotFound -43
Archivo no encontrado
kFileOpsHardwareVolumeLock -44 El volumen está bloqueado por hardware
kFileOpsFileLocked -45
Archivo bloqueado
kFileOpsSoftwareVolumeLock -46 El volumen está bloqueado por software
kFileOpsMoreFilesOpen -47
Uno o más archivos ya estan abiertos
kFileOpsAlreadyExists -48 Ya existe un archivo con el nombre especificado 
kFileOpsAlreadyWriteOpen -49
Sólo se permite un único camino de acceso al archivo durante su escritura              
kFileOpsNoDefaultVolume -50 El volumen predefinido no existe 
kFileOpsBadFileRef -51 - 
kFileOpsVolumeNotOnline -53
El volumen no esta disponible o montado
kFileOpsPermissionDenied -54 Permiso denegado o archivo de sólo lectura 
kFileOpsVolumeAlreadyMounted -55
El volumen especificado ya está disponible o montado
kFileOpsBadDrive -56 El número de unidad expecificado no existe
kFileOpsInvalidFormat -57
El volumen no contiene uno de los formatos sportados
kFileOpsExternalSystemError -58 Error externo detectado por el sistema de archivos
kFileOpsProblemDuringRename -59
Se ha producido un problema durante el cambio de nombre
kFileOpsBadMasterBlock -60 Se ha detectado un bloque índice defectuoso; deberá reiniciar el volumen
kFileOpsCantOpenLockedFile -61
No ha sido posible abrir el archivo por estar bloqueado
kFileOpsDirectoryNotFound -120 Directorio no localizado
kFileOpsTooManyDirOpen -121
Se han abierto demasiados directorios
kFileOpsCantMoveToOffspring -122 Intento de posicionarse fuera del ambito del archivo
kFileOpsNonHFSOperation -123
Intento de relizar una operación HFS sobre un volumen con otro formato
kFileOpsDifferentVolume -124
Intento de relizar la operación sobre volúmenes o nombres de archivo diferentes
kFileOpsInternalSystemError -127 Error interno detectado por el sistema de archivos
kFileOpsCrossDeviceLink 100 -
kFileOpsDeadlock 101 -
kFileOpsTooManyArguments 102 -
kFileOpsMathArgument 103 -
kFileOpsExecFormatError 104 -
kFileOpsResultTooBig 105 -
kFileOpsUnknownError 998
Error desconocido
kFileOpsNoOperation 999 Operación no compatible para la plataforma en uso
kFileOpsInvalidEncoding 1000 -