Capítulo 15. Historial médico

Este capítulo ha sido realizado sobre el trabajo de Federico Martí, quien ha realizado el esbozo incial y casi todo el código.

Este caso de estudio fue planteado en la la sección de nombre Caso de estudio: una agenda para guardar el historial clínico de pacientes en Capítulo 4 del Capítulo 4. Su planteamiento gira en torno a una pila principal que tendrá una serie de controles (Figura 15-1a), que tomando como base el número de historial (Figura 15-1b), podrá abrir una serie de subpilas que mostrarán contenidios asociados a un paciente (Figura 15-1c), y no todos han de tener la misma estructua (Figura 15-1d). Se quiere así aprovechar ampliar la funcionalidad de la agenda construída en uno de los tutoriales básicos para que incluya elementos audiovisuales. El enfoque constituye una primera aproximación a construir una base de datos con características multimedia. En este caso, de pacientes de un centro hospitalario y puede ser necesario asociar imágenes, vídeos e incluso grabaciones sonoras realizadas durante el tratamiento a los pacientes o como notas que un doctor prefiera dejar así asociadas a un paciente.

Figura 15-1. Planteamiento incial de la agenda para guardar el historial.

a)

b)

c)

d)

Sin más dilación veamos ya como Fede decidió instanciar y resolver este problema: el planteamiento de partida es aprovechar la estructura de la agenda vista en el primer tutorial de MetaCard (véase la la sección de nombre Tutorial sobre aplicaciones en Capítulo 1) para realizar una pila ("Historial Clínico", como la representada en la Figura 15-2a) que tenga campos correspondientes a: Apellidos, Nombre, Hospital, Número de Historia, Navegadores, Buscador y Nuevo Registro. El formato final es el que se puede ver en la Figura 15-2b, donde queda básicamente por implementar la funcionalidad de los botones Numero de historia (que lanzará la subpila de historia del paciente) y el de Datos personales (que mostrará los correspondientes al paciente actual) como se indicaba en la propuesta original y que se puede ver en Figura 15-2c.

Nota: Si su visión del interfaz no coincide con esta, no la reescriba. Recuerde que esta es una posible solución: seguro que existen otras.

Figura 15-2. Captura de pantalla de la aplicación historial médico.

a)b)

 
c) 

De lo expuesto hasta ahora, señalar que el código de los botones de navegación y de búsqueda se ha heredado del tutorial, así que no se harán más comentarios al respecto. En su lugar sí que hay que comentar cómo se soluciona el obtener un identificador único. Le proponemos que considere utilizar el número de la tarjeta y así se ha implementado en el campo de texto n historia (el que está a la derecha del que lleva la leyenda de Número historia), donde se ha utilizado el siguiente código:

#
# Campo de texto "n historia" (junto a "Número de Historia")
#
on mouseUp
  put the number of this card into field "n historia"
end mouseUp

Nota: Una pequeña observación: sería interesante que, automáticamente, apareciese el número de "expediente" que no queremos que se tenga que ocupar el usuario; sobre todo para facilitarnos la eliminación de ellos y que no pueda haber un pequeño despiste y se asigne a más de un usuario un mismo índice de historial.

Se puede conseguir este comportamiento utilizando el código de la pila, en este se pude disponer el código que se habrá de ejecutar cada vez que se transita a una nueva tarjeta. Como hay subpilas, a esta pila le llegarán eventos de que se abre una tarjeta cuando se canvie en aquellas, así que habrá que seleccionar cuando actuar. Por ejemplo, se puede hacer de la forma siguiente:

#
# Pila pila "Historial Clínico"
#
on openCard
  if (there is a to fld "n historia") then send "mouseUp" to fld "n historia"
end openCard

De este manera el código que calcula el valor sigue estando en el objeto donde estaba, se puede cambiar si hace falta y el mecanismo de presentar el valor sigue siendo funcional e independiente.

Las otras dos subpilas necesarias se pueden crear en este momento, aprovechando que estamos decidiendo las cuestiones de interfaz, Siguiendo el método habitual de creación de una nueva pila se puede obtener algo similar a lo que se puede observar en la Figura 15-3.

Figura 15-3. Captura de ventana de la supila "datos personales" (fila superior) y de la subpila "hist" (fila inferior) de la aplicación historial médico.

Recordemos que estas pilas deben estar accesibles desde la inicial. Es decir que, mediante un botón se pueda acceder a la pila que contenga los datos personales y, lo mismo ha de ocurrir con la historia. Debería poner un botón que me dirija a ellas: ¿cómo conseguir esto? Tras indagar por la ayuda (Help) de MetaCard[1], se puede deducir que lo que se debe hacer es crear ambas pilas y, en sus propiedades, decirles que la MainStack o pila principal es la inicial ("Historial Clínico"). Así pues, cree dos pilas una con el nombre de "Datos personales" y otra con el nombre de "Historial".

Una vez creadas las pilas y puesto en sus propiedades que sean subpilas, compruebe que en las propiedades de "Historial Clínico", que aparece como componentes las pilas "Datos Personales" e "Historial". Ahora, habrá que añadir el código correspondiente a los botones para ir hacia estas subpilas en la pila inicial: Datos personales y Abrir Historia.

El botón Datos Personales es el más sencillo: abre la pila correspondiente y avanza hasta la tarjeta que corresponde al paciente que se está considerando en la pila inicial:

#
# botón "Datos personales"
#
on mouseUp
  put field "n historia" into y
  go to stack "datos personales" 
  open card y                                    
end mouseUp

                     

El otro caso es un poco más complejo, puesto que una persona, puede tener que ir varias veces al hospital, e incluso a diferentes servicios. Para que cada vez sea posible añadir algo en su historial. Así pues, para cada paciente, debería haber una pila, es decir, debían existir tantas pilas como pacientes o números de historia. Por lo que el código es:

#
# botón "Abrir Historia"
#
on mouseUp
  put field "n historia" into y
  if exists (stack ("hist"&y) of stack "Historial Clínico")  then
    ask "NO puede generar una historia que ya existe"
  else
    clone stack "Historial"
    set the name of the stack it to "hist"&y
    set the mainStack of the stack ("hist"&y) to "Historial Clínico"
   ##
    send mouseUp to button "crear" of card 1 of stack "datos personales"
  end if
end mouseUp
                     

Hay varias cosas que destacar en este código:

Ya casi hemos terminado tenemos abierto el camino a la asociación a un paciente de datos textuales (Figura 15-4a), sólo nos queda por resolver la inclusión de los ficheros de imágenes, audio o vídeo. Para ellos crearemos, por ejemplo, una pila para cada tipo en cada paciente y esta que sea el contenedor de todos los ficheros de una de esas tres clases. Vamos a verlo para el caso de las imágenes, con un planteamiento bastante poco elaborado para empezar (algo improvisado como lo de la figura Figura 15-4b).

Figura 15-4. Captura de la ventana de la subpila "image1" de la aplicación historial médico.

a)

b)

Después de lo visto, seguro que ya tiene una idea de cómo la pila historial (bueno, realmente la versión clonada que se habrá creado para un paciente dado) puede disponer de botones que lancen las pilas correspondientes a cada medio. Para las imágenes puede ser algo como:

#
# botón "Imagen"
#
on mouseUp
  put field "n_historia" into y
  go to stack "imagen"&y
end mouseUp
                     

Y para poder incorporar los ficheros, ¿qué mejor que preguntarle al usuario por el nombre del mismo y asignarselo a un objeto de MetaCard? Vale, vale, es una solución un poco simple, pero, ¿ha visto las líneas de código que utiliza? Añadir que para los sonidos y los vídeos deberá utilizar el objeto player, de una forma totalmente equivalente a lo que hemos hecho aquí con el control de tipo image, así que no insisto más. El código que puede implementar esto es algo como:

#
# botón "Nueva Imagen"
#
on mouseUp
  create Image "new image"
  answer file "Seleccione un archivo de imagen"
   if it is not empty
   then
     set the cursor to watch
     set the filename of last image to it
  end if 
end mouseUp

                     

¿Funciona, no? Sí pero poco, ya lo se. Lo siento pero es que así puedo ir contando un par de cosas que ya he mencionado y que creo que son interesantes.

Conclusiones

En el presente caso de estudio se ha desarrollado una aplicación capaz de mostrar información de naturaleza diferente de la puramente textual, a partir de la extensión de una aplicación anterior.

Si ha implementado la aplicación conforme hemos ido exponiendola habrá observado que es dudosamente buena la elección del número de identificación a partir del de la tarjeta. Sobre todo si ha intentado borrar un paciente (una tarjeta), esto se ha de extender a todas las tarjetas de las subpilas que corresponda (lo que no es mayor problema). Pero entonces hay que arreglar la inconsistencia que se dará al renumerar las tarjetas con en el consiguiente cruce de datos de pacientes. La solución pasa por elaborar un poco más esta elección de número, sin hacerlo coincidir con el de la tarjeta y olvidarse de que sea el número de historial una correspondencia con el de la tarjeta.

Respecto a las nuevas funcionalidades que se pueden incorporar para que el sistema sea de interés hemos comentado la necesidad de definir una estructura de almacenamiento de la información que permita su fácil recuperación. Pero además también se ha mencionado que el usuario puede querer asignar otras informaciones que no se hayan podido incluir en los campos originales y que son propios de cada fichero. Ejemplos de esto serían el tiempo en que ha tomado la muestra, las condiciones en que se ha tomado, la medicación que se había utilizado, etc.

Además esto permite abordar una cosa importante: nuestro sistema tal como está ahora, es totalmente dependiente del punto donde se encuentra y de aquel donde se encuentran los ficheros. Para que esto no sea así, las rutas deberían ser relativas, por ejemplo, al punto de arranque de la aplicación. De este modo se puede reubicar la misma en otro sistema donde las rutas no coincidan y no sólo me refiero a su configuración de GNU/Linux o de Mac. ¡No lo he podido evitar! :-). Algunas trabas importantes al desarrollo de aplicaciones multiplataforma van de la mano del uso de rutas absolutas, uso de identificadores de unidades de disco, uno de separadores ruta de archivos que sólo son válidos en un sistema operativo, ... Cosas como esta última son sencillas de resolver en MetaCard/Revolution: utilice siempre la barra ("/") y ya se ocupará la herramienta de reescribirla, si es necesario.

Como posible solución a este planteamiento cabe considerar que en el punto de arranque de la aplicación se creen tantos directorios como historiales de pacientes se vayan creando, de manera que para cada uno de ellos se creen tres directorios que contengan los diferentes ficheros organizados por el tipo de media a que pertenecen. Esos directorios por paciente se puede nombrar con el número de expediente que se les ha asignado, así será inmediato localizarlos, modificarlos e incluso borrarlos.

Figura 15-5. Forma final de la subpila "imagen" rediseñada para la aplicación historial médico.

Esto nos llevará a modificar la subpila "imagen" que puede quedar de la forma que muestra la Figura 15-5 y para lo que:

Un par de botones de navegación y uno que busque en el campo de texto "Anotaciones" redondearían el diseño. Por aquello de hacerlo fácil, se puede agrupar todo en un grupo de clase background y así cada vez que se crea una imagen se creará una nueva tarjeta con toda la funcionalidad esperada.

Por último las pilas de imágenes, sonido y vídeo carecen de opciones que permitan el borrado selectivo o la edición del fichero asignado. Estas extensiones básicas quedan a la consideración del lector para que ponga a prueba su aprendizaje.

Notas

[1]

En las MetaClasses encontrará más desglosado este mismo tema de creación y manejo de pilas y subpilas.