Vous êtes sur la page 1sur 72

Centro de Ingeniera y Desarrollo Industrial

Curso de LabWindows/CVI 9.0

Csar Armando Cruz Mendoza


CVI-01-2010
1

Introduccin .............................................................................................................................................................4
Qu es LabWindows/CVI? ..................................................................................................................................4
Entorno de desarrollo ...........................................................................................................................................4
Mi primer programa .................................................................................................................................................5
Atributos importantes de un panel ......................................................................................................................6
Generando cdigo de archivo UIR ........................................................................................................................8
Analizando el cdigo generado ......................................................................................................................... 11
Agregando un botn para desplegar un mensaje ............................................................................................. 13
Eventos posibles para paneles y controles ........................................................................................................ 16
Prctica manejando eventos ............................................................................................................................. 17
Manejo de datos en pantalla ................................................................................................................................. 17
Leer y asignar informacin en un panel ............................................................................................................ 17
Prctica modificando el estado de un led ......................................................................................................... 17
Prctica de operacin con dos nmeros ........................................................................................................... 18
Prctica para actualizar controles usando eventos ........................................................................................... 20
Manejo de Timers .................................................................................................................................................. 21
Timer Sncrono y Asncrono............................................................................................................................... 21
Consideraciones para un timer sncrono ........................................................................................................... 22
Ejercicio utilizando timer sncrono .................................................................................................................... 23
Funciones para controles de tipo Timer ............................................................................................................ 23
Ejercicio utilizando timer sncrono y control graph........................................................................................... 24
Funcionamiento:................................................................................................................................................ 24
Timer Asncrono ................................................................................................................................................ 28
Funciones para el manejo de un Timer Asncrono ............................................................................................ 28
Ejercicio utilizando un timer asncrono ............................................................................................................. 30
Manejo de ActiveX................................................................................................................................................. 31
Cmo se registra un ActiveX en Windows? ................................................................................................. 31
2

Puedo eliminar un ActiveX registrado? ....................................................................................................... 31


Insertando y habilitando un ActiveX en nuestro panel UIR .......................................................................... 31
Qu cambios hay en nuestro proyecto? ...................................................................................................... 35
Ejercicio utilizando el ActiveX de Calendario de Windows ............................................................................... 36
Ejercicio utilizando el ActiveX de Adobe Reader ............................................................................................... 44
Manejo de bases de datos ..................................................................................................................................... 46
Conceptos de base de datos .......................................................................................................................... 46
Structured Query Language (SQL) ................................................................................................................. 47
Ejercicios con cdigo SQL .............................................................................................................................. 48
LabWindows/CVI Toolkit SQL ........................................................................................................................ 57
Adminstrador ODBC ...................................................................................................................................... 57
LabWindows y bases de datos....................................................................................................................... 59
Ejercicio para leer el contenido de la tabla Frecuentan .................................................................................... 68
Ejercicio para insertar informacin a la tabla Frecuentan ................................................................................ 71
Ejercicio para eliminar informacin a la tabla Frecuentan................................................................................ 72
Apuntes finales sobre SQL ................................................................................................................................. 72

Introduccin
Qu es LabWindows/CVI?
LabWindows/CVI es un completo ambiente de desarrollo ANSI C para la creacin de
aplicaciones de instrumentacin virtual. LabWindows/CVI viene con libreras para
adquisicin, anlisis y visualizacin, una interface simplificada de edicin para usuario con
arrastre y colocacin de elementos y herramientas automatizadas de generacin de cdigo
con las cuales se puede probar dicho cdigo interactivamente entes de adicionarlo a un
proyecto. Con LabWindows/CVI, se pueden crear interfaces localizadas de usuario, crear y
trabajar con componentes ActiveX y desarrollar aplicaciones multihilos.

Entorno de desarrollo
La interfaz del entorno de desarrollo, es muy similar a otros IDE como Visual Studio, Eclipse,
etc.

1.- Panel de proyectos. En esta parte se organizan los archivos (*.c, *.h, *.uir, *.prj) que
integran el o los proyectos. En este mismo espacio se pueden insertar archivos que no
formen parte del proyecto, como pueden ser archivos *.txt, archivos de base de datos, etc.
Este tipo de archivos no afectan el proceso de compilacin o ejecucin de un proyecto.
2.- Panel de libreras. En este espacio CVI coloca la descripcin del contenido de las
diferentes libreras que se encuentran integradas al proyecto activo.

3.- Espacio para usos mltiples. Se utiliza como editor de cdigo C, editor de la interfaz
grfica, editor de paneles de funciones, visualizacin de contenido de variables, memoria,
etc.

Mi primer programa
Una vez iniciada la sesin con LabWindows/CVI, se proceder a guardar el proyecto que
vamos a crear, el nombre propuesto es Ejercicio01.

Ahora crearemos un nuevo documento de tipo UIR para crear nuestro panel de interfaz de
usuario.

Por default, LabWindows inserta


un panel en blanco en el nuevo
archivo UIR que acabamos de
crear.
Para editar las propiedades del
panel, pulsaremos doble clic
izquierdo sobre el panel.
En el panel de propiedades,
modificaremos el ttulo de la
ventana con la siguiente leyenda
Mi primer programa.

Atributos importantes de un panel


Todo panel que se crea en un archivo UIR, se
identifica por un atributo denominado Constant
Name.
Labwindows siempre propondr un nombre de
constante para cada panel que insertemos en un archivo UIR.
Se recomienda que el nombre a utilizar en este atributo, se escriba en maysculas y no
puede contener espacios en blanco. Esto sigue las mismas reglas utilizadas en un
compilador de C para la sentencia #define.
En un proyecto de CVI que utilice uno o varios archivos UIR, no se puede repetir el nombre
de una constante que identifique a un panel.
6

Otro parmetro importante dentro de los atributos de un panel, es el Callback Function.


Como veremos ms adelante al analizar el cdigo en CVI, LabWindows trabaja en base a
eventos.
Lo anterior significa que desde el archivo
UIR, se estar indicando qu bloques de
cdigo se debern ejecutar en los archivos
de cdigo fuente C.
El cundo y qu bloque de cdigo se debe
ejecutar, se configurar ms adelante al
especificar lo que se conoce como tipo de
evento.
Por el momento es importante saber que a
travs del archivo UIR, nosotros como
desarrolladores podemos conocer las
acciones que est realizando el usuario
como por ejemplo dnde puls clic
izquierdo, dnde se encuentra el cursor de su mouse posicionado, dnde ha modificado
informacin, etc.
Retomando el parmetro Callback Function, para
el caso de nuestro panel que estamos
configurando, deseamos poder capturar el evento
que corresponda a la accin de cerrar la ventana
de nuestra aplicacin que estamos creando.
Para lograr lo anterior, es necesario especificar un nombre de funcin. Esta funcin no existe
an, pero se crear ms adelante. Sobre las reglas para especificar el nombre de una
funcin, sern las que se tengan definidas en el estndar de programacin que se est
utilizando. Por mencionar alguna, se utilizarn letras minsculas con excepcin de la primera
letra del nombre de la funcin.
La configuracin final que debemos tener para nuestro ejercicio es la siguiente:

Una vez que hemos configurado nuestro primer panel, procederemos a guardar nuestro
archivo UIR. El nombre propuesto es Interfaz01.

Generando cdigo de archivo UIR


Ahora que hemos configurado nuestro primer panel, procederemos a generar el cdigo para
su ejecucin.
Para ello ejecutaremos la siguiente opcin del men principal:

Como en este momento no disponemos de ningn archivo de cdigo fuente C, el generador


de cdigo nos preguntar en dnde deseamos depositar el cdigo que estamos por crear.
Por ahora le indicaremos que deseamos hacerlo en una nueva ventana.
Posteriormente nos mostrar la siguiente ventana de configuracin.

A esta ventana le haremos algunos ajustes para obtener lo siguiente:

El primer cambio es para que el archivo destino con el cdigo fuente, sea insertado en
nuestro proyecto activo.
El segundo, es indicar el nombre de una variable (veremos ms adelante que ser de tipo
entero) que nos servir a nivel de cdigo, para identificar a este panel en particular. Esta
variable ser utilizada para acciones como el desplegar el panel u ocultarlo.

El ltimo se refiere a indicar cul funcin callback de las existentes en nuestro archivo UIR,
servir para poder cerrar nuestra aplicacin. Como en este momento solo hemos
especificado una funcin (Terminar), seleccionaremos la misma para finalizar la aplicacin.
Al aceptar estos ajustes, deberemos observar una imagen como la siguiente:

Podemos observar que en el panel de proyectos tenemos un proyecto de nombre


Ejercicio01, que contiene dos carpetas, una con el archivo UIR Interfaz01.uir y una con el
cdigo fuente recin generado Interfaz01.c.
En este momento nuestro proyecto ya puede ser ejecutado y ejecutar la nica accin que
tiene definida, cerrar la aplicacin. Bastar con pulsar en el siguiente botn:

LabWindows compilar el cdigo C existente y mostrar la siguiente pantalla:

10

Nuestra aplicacin solo se limita por ahora a mostrar un panel y responder a la accin de
cerrar. Las funciones de minimizar y maximizar se encuentran implcitas en todo panel
creado y no requieren de una funcin callback para ejecutarse.

Analizando el cdigo generado


El cdigo que hasta ahora hemos generado es el siguiente:

2
1
3

1. En esta parte se concentran todas las libreras de tipo .h que son necesarias para
poder compilar exitosamente cada una de las funciones incluidas en el cdigo fuente.
Por lo general LabWindows nos recomendar las libreras que son necesarias incluir
cuando alguna funcin sea desconocida. Entre estos archivos podemos ver que existe
uno con el mismo nombre de nuestro archivo UIR. Esto se debe a que todo archivo
UIR que generemos, siempre se encontrar acompaado por su respectivo archivo .h
11

2. Despus de la seccin de los archivos de cabecera, se colocar la definicin de las


variables globales a utilizar en el programa.
Recuerdas el nombre de variable que modificamos aqu?

Esta variable fue declarada en esta


seccin.

3. Como todo programa en C, siempre debe existir una funcin main. Normalmente en
esta funcin, se destina para ejecutar una funcin llamada LoadPanel.
La finalidad de esta funcin es el cargar en memoria el panel o los paneles que hemos
creado en nuestro archivo UIR. Esta funcin recibe tres parmetros:
- El primero por el momento lo usaremos con el valor de cero
- El segundo es el nombre del archivo UIR en donde se encuentra el panel que
deseamos cargar en memoria
- El tercero corresponde a la constante que identifica a nuestro panel.
Esta funcin retorna un valor de tipo entero, que no es otra cosa ms que la referencia
del panel que se ha cargado en memoria. Esta referencia sera el valor que
utilizaremos en todo nuestro cdigo para ejecutar acciones sobre un panel.
Importante: El valor que retorna la funcin LoadPanel, no es el mismo que se
encuentra asociado a la constante del panel. Son valores distintos.
4. En esta seccin encontramos nuestra funcin callback que definimos desde nuestro
archivo UIR. LabWindows por default genera una funcin callback en donde inserta
una estructura de control tipo switch.
La finalidad de una estructura switch es el poder manejar diferentes eventos que se
puedan generar desde el panel o control al que se encuentra asociada la funcin
callback.

12

Se puede observar que en cada case de la estructura switch se encuentran unas


constantes (asumimos esto porque se encuentran escritas en maysculas), que sirven
para identificar los eventos que podemos capturar con esta funcin callback desde el
panel que la contiene.

El caso que nos interesa analizar por este momento, es que corresponde al
EVENT_CLOSE. Este evento se asocia a la accin de pulsar clic izquierdo sobre la X
de la ventana, indicando que se desea cerrar la ventana.
Una vez que estamos listos para capturar el evento que nos interesa, solo resta
escribir al interior del case, las acciones que deseamos sean ejecutadas cuando se
cumpla esa condicin.
Para el ejercicio actual, LabWindows ha escrito la funcin QuitUserInterface que
significa se debe detener toda captura de eventos para salir de nuestro programa.
La funcin QuitUserInterface cancela a la funcin RunUserInterface que se ejecut en
la funcin main.

Agregando un botn para desplegar un mensaje


Vamos a modificar nuestro proyecto para adicionar un botn que nos permita desplegar un
mensaje en pantalla mediante la funcin MessagePopup.

13

Ajustaremos las propiedades del botn para que tenga el siguiente aspecto:

A este botn se asociaremos una funcin callback que se llamar: DespliegaMensaje.


Para crear la funcin asociada a este botn, pulsaremos clic derecho sobre el botn como se
muestra a continuacin:

El cdigo de esta funcin ha sido generado en el archivo de cdigo fuente que tenemos en
nuestro proyecto. Cuanto tengamos varios archivos .c, LabWindows nos preguntar en cul
de ellos deseamos depositar el cdigo a generar.
Ahora nuestro editor de cdigo se muestra como sigue:

14

En nuestra nueva funcin, complementaremos con cdigo en el caso para el evento


EVENT_COMMIT.
Insertaremos la siguiente lnea de cdigo:
MessagePopup(Mensaje de prueba,Hola mundo);
Volvemos a ejecutar nuestra aplicacin y al pulsar clic izquierdo sobre el botn Mostrar
mensaje, deberemos observar algo como lo siguiente:

15

Eventos posibles para paneles y controles


Los eventos que podemos configurar para los paneles son los siguientes:

Para los controles los eventos disponibles son:

16

Prctica manejando eventos


Modifique la funcin callback DespliegaMensaje para que despliegue el mensaje ante un clic
derecho y para un doble clic izquiero.

Manejo de datos en pantalla


Leer y asignar informacin en un panel
LabWindows proporciona dos funciones para el proceso de lectura y asignacin de datos a
controles:
- GetCtrlVal
- SetCtrlVal
Ambas funciones requieren tres parmetros:
- Referencia del panel donde se encuentra el control a leer o asignar el dato
- Constante que identifica al control. As como un panel se encuentra identificado por
un nombre de constante, un control se identifica de igual manera con el nombre de
una constante. Para efecto de utilizarse en esta funcin, el identificador del control
se compone por el nombre de la constante del panel ms el nombre de la
constante del control separados por un guion bajo (_). Por ejemplo, para el
ejercicio actual, nuestra constante de panel es VENTANA01 y si la constante del
control fuera BOTON01, el identificador que espera la funcin GetCtrlVal o
SetCtrlVal es VENTANA01_BOTON01.
- El tercer parmetro es segn la funcin:
o GetCtrlVal. La direccin de memoria donde se va a depositar el dato a leer.
o SetCtrlVal. El valor o la variable que contiene el dato a ser asignado al
control en pantalla.

Prctica modificando el estado de un led


Vamos a agregar a nuestro proyecto un control de tipo led que responda al evento de doble
clic izquierdo para encender y apagar el mismo.
Inserte en el panel un led (redondo o cuadrado), defina el nombre de la constante como LED
y asigne una funcin callback de nombre CambiaEstado.
Genere el cdigo de la funcin en el archivo de cdigo fuente del proyecto activo.
En la estructura switch de la funcin creada, modifique el evento EVENT_COMMIT para que
la funcin responda a la accin de doble clic izquierdo.
Agregue las lneas de cdigo faltantes hasta quedar como se indica a continuacin:

17

Ejecuta la aplicacin y valida su funcionamiento pulsando doble clic sobre el control led.

Prctica de operacin con dos nmeros


Modifique el proyecto actual para lograr una interfaz de usuario como la siguiente:

Dados dos nmeros (primera y segunda cantidad), al pulsar clic sobre el botn Multiplicar, se
colocar el resultado del producto en el control etiquetado como Resultado.

18

El cdigo fuente de la solucin es:

19

Prctica para actualizar controles usando eventos


Inserte en el panel de proyecto actual dos nuevos controles numricos como se muestra en
la siguiente imagen:

El funcionamiento de este ejercicio consiste en capturar a travs del control etiquetado como
Perilla de nivel, las variaciones que se hacen con el mouse en su valor y reflejarlo
simultneamente (sin soltar el mouse) en el control etiquetado como Depsito.

20

Manejo de Timers
Timer Sncrono y Asncrono
LabWindows ofrece dos tipos de controles que ayudan en el proceso de ejecucin
automtica de funciones mediante la programacin de eventos en base a tiempo.
El primero de ellos es el Timer
Sncrono, mismo que se pude insertar
desde el editor de UIR como un control.
Este tipo de control tiene las mismas
propiedades generales que hemos visto
hasta ahora, es decir, se identifica con un
Constant Name y se le asocia un nombre
de funcin callback, misma que se
ejecutar automticamente a intervalos
de tiempo predefinidos.
Un parmetro especfico para este tipo
de control, es el que permite la
configuracin del intervalo de tiempo de
ejecucin.
Otro parmetro que resulta de gran
utilidad al momento de trabajar con este
tipo de control, es el de habilitacin.
Este parmetro si se encuentra activo
indicar que desde el
momento en que nuestro proyecto es
ejecutado, el timer comenzar a ejecutar
la funcin asociada una vez transcurrido
el intervalo de tiempo especificado.
En caso contrario, si se encuentra deshabilitado
ser tarea del programador
mediante instruccin de cdigo, habilitar el timer cuando lo considere apropiado.
Una de las principales ventajas de este tipo de timer es su sencillez en el proceso de
implementacin, ya que se sigue el mismo proceso que hasta ahora hemos visto para
insertar un control y generar su funcin callback asociada desde el editor UIR.

21

La estructura de la funcin callback que nos genera un timer de este tipo es la siguiente:

Podemos observar que la nica diferencia es el tipo de evento que nos maneja la estructura
de control switch, ahora se trata de un EVENT_TIMER_TICK.

Consideraciones para un timer sncrono


Mencionbamos al inicio del curso que LabWindows trabaja en base a eventos y que su
manejador es la funcin que se ejecuta al inicio en el main de nuestros programas llamada
RunUserInterface.
Este manejador organiza los eventos que se reciben en una fila, mismos que se van
atendiendo en el orden de llegada.
Este modo de administracin puede generar que un timer que se haya configurado a un
intervalo de tiempo por ejemplo de 5ms, no sea determinstico. Por qu?. Porque al que al
tratarse de un evento que se atiende junto con el resto de los posibles eventos que se
generan en la interface de usuario (movimiento mouse, clics, modificaciones de datos, etc)
ms los que administra Windows por su propia cuenta, existan fluctuaciones entre el tiempo
que realmente ha transcurrido entre cada evento del timer.
As mismo, al querer manejar procesos
con este tipo de timer a tiempos muy
cortos de ejecucin (milisegundos),
genera que nuestro procesador se
sature y se destine un alto porcentaje de
tiempo de procesador a ello.
Se recomienda utilizar este tipo de
control para procesos que no son
crticos.
Un aspecto a cuidar tambin es la
relacin del intervalo de tiempo de
ejecucin del timer contra el tiempo que
se tardar en ejecutar las lneas de
cdigo que se incluyen en la funcin
callback.
22

Cuando se inserta un timer en un panel dentro del editor UIR, observaremos un icono como
este
No debemos preocuparnos mucho por su ubicacin en nuestro panel que se est
diseando, ya que en tiempo de ejecucin el icono no es visible para el usuario.
Un ltimo dato importante sobre este tipo de timer sncrono es la resolucin de tiempo,

Ejercicio utilizando timer sncrono


Comenzaremos diseando una aplicacin que en pantalla incremente el valor de un control
en uno de forma automtica cada segundo a partir de que se ejecuta la aplicacin.

Funciones para controles de tipo Timer


En la mayora de las aplicaciones a desarrollar, necesitaremos tomar el control del timer para
indicarle en qu momento iniciar o parar.
Para ello LabWindows nos ofrece las siguientes funciones:
- SuspendTimerCallbacks ();
- ResumeTimerCallbacks ();
Estas funciones afectan a TODOS los timers que tengamos corriendo en nuestra aplicacin.
Existe una tercera funcin que se llama SetCtrlAttribute. Esta funcin no es exclusiva para
el control de tipo Timer, al contrario, aplica para todos los controles que depositamos en un
panel.
Qu nos permite hacer?. Prcticamente modificar todo lo que deseemos de un control.
Todos los atributos que modificamos de un control desde el panel en el editor de UIR, con
esta funcin lo podemos hacer desde cdigo.
En el siguiente ejercicio la pondremos en prctica.

23

Ejercicio utilizando timer sncrono y control graph


Disearemos una interfaz de usuario como la siguiente:

Funcionamiento:
Cuando se pulse clic sobre el botn Iniciar grfica, utilizando el valor de intervalo de
tiempo configurado y el nmero de datos a generar, se estar construyendo con nmeros
aleatorios, un vector con la cantidad de nmeros especificada en la pantalla. Este vector de
datos se estar dibujando en la grfica cada t segundos, segn se haya igualmente
configurado en la pantalla.
La grfica estar de forma continua hasta que se pulse en el botn Pausar grfica o se
cierre la aplicacin. En caso de pausar el proceso, se reanudar con Iniciar Grfica.
Finalmente, mientras la aplicacin se encuentra graficando datos automticamente,
podremos variar el tiempo de graficado y la cantidad de datos, simplemente modificando los
valores de los controles respectivos.
24

Nuestro panel lo configuraremos como sigue:

Constant Name
Callback Function
Label

INTERVALO
CambiarIntervalo
Intervalo de tiempo (segundos)

Constant Name
Callback Function
Label

DATOS
CambiaCantidadDatos
Cantidad de datos a generar:

Constant Name
Callback Function
Label

COMMANDBUTTON
Graficar
Iniciar grfica

Constant Name
Callback Function
Label

COMMANDBUTTON_2
Pausar
Pausar grfica

Constant Name
Callback Function
Label
Enable

TIMER
GraficarVector
0.500
No

Constant Name
Callback Function
Points per Screen
Scroll Mode

MIGRAFICA
10000
Continuos
25

Panel
Constant Name
Callback Function
Panel Title

PANEL
Salir
Utilizando
grficas

timer

sncrono

Una vez que se tenga configurado nuestro UIR, generamos todo el cdigo para comenzar a
complementarlo.
Para poner en marcha nuestra aplicacin, se requiere pulsar sobre el botn Iniciar grfica,
por lo que este botn deber establecer las condiciones iniciales de nuestra aplicacin.
- Leer y configurar el intervalo de tiempo que se ha configurado en la pantalla
- Leer el nmero de datos que se deben de generar
- Poner en marcha el timer
Se recomienda que las variables donde se almacene el intervalo de tiempo y la cantidad de
datos, sean globales, ya que sern utilizadas por varias funciones de nuestra aplicacin.
Cmo configurar el timer?.
Utilizamos la funcin SetCtrlAttribute en donde sus parmetros son:
- Variable con la referencia del panel
- Identificador del control que queremos modificar, en este caso el del timer
- El tipo de atributo que queremos modificar:
o ATTR_INTERVAL: Para modificar el intervalo de tiempo (tipo doble)
o ATTR_ENABLE: Para habilitar el timer (tipo entero)
- El valor del parmetro con el tipo de dato que segn aplique
Ahora, programaremos la funcin del botn Pausar grfica, en el paso anterior vimos como
se pone en marcha el timer, cmo podramos indicar que no est habilitado?.
Listo!! Ya tenemos nuestra funcin para pausar nuestro proceso de graficado.
Ahora hagamos que nuestra aplicacin responda a las modificaciones del tiempo y cantidad
de datos mientras se grafica.
Se generaron dos funciones callback asociadas a los controles que tiene esta informacin,
por lo que en cada funcin solamente habr que incluir el cdigo para que actualicen sus
variables respectivas.
Finalmente programemos las acciones del timer. Ah debemos construir un arreglo de datos
dobles y llenarlo con datos aleatorios. Podemos utilizar la funcin Random(). Posteriormente
hay que dibujarlo en pantalla con la instruccin PlotStripChart().
Hemos terminado.

26

27

Timer Asncrono
El segundo tipo de timer que nos permite implementar LabWindows, es el denominado
asncrono.
Una de las principales caractersticas de este control, es que la llamada de su funcin
callback se ejecuta en su propio hilo. Esto es, la administracin de los eventos generados por
un timer asncrono no corre a cargo de la funcin RunUserInterface.
Esta caracterstica hace que este tipo de timers sean ideales para tareas de adquisicin de
datos, en donde se requiere un mayor nivel de determinismo en su tiempo de ejecucin.
La cantidad de timers asncronos que se pueden crear en un sistema basado en Windows es
de 16, en sistemas de tiempo real la cantidad es de 128 y en sistemas Linux hasta 256.
En cuanto a la resolucin mnima de tiempo que se puede implementar en un timer
asncrono, a diferencia de la limitante de 1ms para el timer sncrono, en este caso se puede
alcanzar una resolucin de hasta 1us. Para conocer la resolucin mnima soportada por el
sistema operativo donde se va a ejecutar, la funcin GetAsyncTimerResolution proporciona
este dato.
Al utilizar este tipo de timers, se debe tener especial cuidado con las variables que sean
comunes entre timers. Esto es, ya que al tratarse de ejecuciones en hilos separados, el
contenido de las variables no se encuentra protegido y un mal manejo podra generar
inconsistencias en el contenido de las variables.
Finalmente, este timer se encuentra definido dentro de la librera asynctmr.h.

Funciones para el manejo de un Timer Asncrono


Debido a que este tipo de control no es definido desde el editor UIR, es necesario conocer
algunas funciones que nos sern de ayuda para administrar el comportamiento de este timer.
-

NewAsyncTimer. Con esta funcin creamos un nuevo timer asncrono. Cada timer
creado, tiene asociado un identificador (ID) que es de tipo entero, mismo que es
retornado por la funcin:
iIdentificador = NewAsyncTimer();
Esta funcin requiere de 4 parmetros:
o Intervalo: se define el tiempo de ejecucin del timer (valor doble)
o Contador: un valor de -1 significa que el timer se estar ejecutando hasta
que sea descartado por software. Para un valor mayor que cero, indicar el
nmero de veces que se ejecutar antes de que el timer se descarte
automticamente.
o Estado inicial: acepta los valores de 0/1. Un cero indica que el timer ser
creado pero estar detenido hasta que indiquemos por software lo contrario.

28

Para un valor de 1, indica que el timer automticamente comienza a generar


las llamadas callback de su funcin asociada.
o Funcin de evento: requiere el nombre de la funcin callback que se
ejecutar, por ejemplo MiFuncion. Manualmente deberemos crear la
funcin callback de esta funcin que tendr la siguiente estructura:
int CVICALLBACK MiFuncion (int reserved, int timerId, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_TIMER_TICK:
break;
}
return 0;
}

Como podemos observar la estructura es muy similar a las que hemos


manajeado hasta el momento para una funcin callback.
o Dato callback: por el momento dejaremos en cero este parmetro. Ms
adelante trabajaremos el paso de datos/estructuras por referencia a una
funcin callback.
El aspecto de la lnea de cdigo donde creamos un timer sera como sigue:
iIdentificador = NewAsyncTimer (.01, -1, 1, MiFuncion, 0);

SetAsyncTimerAttribute. Al igual que hemos manejado la funcin SetCtrlAttribute


para controles, para el caso de un timer asncrono tenemos su funcin equivalente
que nos permite modificar el comportamiento del mismo.
Esta funcin requiere de 3 parmetros para su uso:
o Identificador de timer. La variable entera que tiene la referencia del timer.
o Atributo. Se puede seleccionar de una lista 5 posibles atributos a modificar.
o Valor del atributo. De acuerdo al tipo de atributo a modificar,
corresponder el tipo de dato a colocar.
Ejemplo de la instruccin SetAsyncTimerAttribute:
SetAsyncTimerAttribute (iIdentificador, ASYNC_ATTR_ENABLED, 0);

DiscardAsyncTimer. Permite liberar los recursos asignados a un timer asncrono,


para lo cual bastar pasar por referencia el identificador del timer a eliminar.
DiscardAsyncTimer (iIdentificador);

29

Ejercicio utilizando un timer asncrono


Disearemos una interfaz como la siguiente:

Funcionamiento.
-

El botn Crear timer, deber construir el timer asncrono para que se ejecute a
un intervalo de tiempo de 0.001 milisegundo.
El timer deber comenzar a ejecutarse automticamente para incrementar el
contenido del control numrico en 0.001
El botn Pausa, una vez que ha sido creado el timer y se encuentra en ejecucin,
deber pausar su ejecucin.
El botn Reanudar deber eliminar la pausa al timer asncrono, reanudando la
actualizacin de incremento en el control numrico.

Una vez concluida la aplicacin y estando en ejecucin, revisar el rendimiento del procesador
de la computadora y compararlo contra el ejercicio del timer sncrono con un intervalo de
0.001.

30

Manejo de ActiveX
LabWindows tiene la capacidad de utilizar los ActiveX registrados en Windows, dentro de las
aplicaciones que construyamos.
Como antecedente podemos comentar que los ActiveX son una tecnologa diseada por
Microsoft para el intercambio de informacin entre dos aplicaciones diferentes. Surgi de la
combinacin de dos tecnologas previas, OLE (Object Linking and Embedding - Insercin y
vinculacin de objetos) y COM (Common Object Model - Simulacin de objetos comunes).
Generalmente podremos identificar a un ActiveX por la extensin del archivo que lo contiene,
siendo sta .OCX

Cmo se registra un ActiveX en Windows?


En el caso de que dispongamos de un archivo OCX y deseemos registrarlo para utilizarlo con
LabWindows o cualquier otra plataforma de desarrollo, el proceso a seguir ser el siguiente:
-

Necesitamos disponer del siguiente archivo ejecutable: regsvr32.exe


Normalmente este archivo se encuentra en C:\Windows
Estando en la carpeta donde se encuentra nuestro archivo OCX, ejecutaremos la
siguiente lnea de comando. Para este ejemplo, se supone la existencia de un
archivo OCX de nombre calendario.ocx que se encuentra en raz.
C:\>regsvr32 calendario.ocx
Acto seguido nos presentar una ventana de confirmacin del proceso de registro.

Puedo eliminar un ActiveX registrado?


Si se desea retirar un ActiveX previamente registrado, bastar con ejecutar la siguiente lnea
de comando:
C:\>regsvr32 /u calendario.ocx

Insertando y habilitando un ActiveX en nuestro panel UIR


Cuando insertamos un ActiveX en alguno de los paneles de nuestro proyecto, es necesario
seguir un sencillo procedimiento para generar un archivo de extensin .fp Este archivo
contiene las diferentes funciones o mtodos que podremos utilizar del ActiveX.
Es importante saber que no siempre se tiene disponible la ayuda de las funciones de un
ActiveX al insertarse en LabWindows. Esto queda sujeto a la documentacin que se haya
generado en el mismo ActiveX.

31

Para insertar un ActiveX, de nuestra paleta de controles


en el editor de UIR, seleccionaremos la opcin etiquetada
como ActiveX
Esto nos mostrar la siguiente ventana:

En esta ventana podremos observar una lista con todos los diferentes controles ActiveX que
se encuentran registrados en nuestro sistema operativo Windows.
Tomaremos como ejemplo el control Calendario de Windows.

Hecho lo anterior, observaremos que se inserta en nuestro


panel el control ActiveX solicitado:

Si

pulsamos

doble

clic

izquierdo sobre el control,


32

podremos ver que tenemos la posibilidad de configurar nuestra ya conocida Constant Name
y Callback Function, las cuales nos ayudan a identificar en cdigo el control y capturar los
eventos respectivamente.

Procedamos a generar el archivo .fp con las funciones


disponibles. Sobre el control pulsaremos clic derecho y en
el men flotante seleccionaremos la opcin

LabWindows nos mostrar la siguiente ventana en donde


podremos especificar el prefijo a utilizar para el nombre de
cada funcion, por ejemplo, si definimos un prefijo DEMO,
cada una de nuestras funciones quedarn con el nombre
como sigue: DEMO_NombreFuncion.

33

As mismo, en esta ventana podremos seleccionar el directorio donde deseamos sea


depositado nuestro archivo .fp generado.
No olvidemos que este archivo .fp debe estar disponible para el proyecto, ya que de ah
estar tomando la informacin para poder ejecutar cada una de las funciones que
invoquemos relacionadas con el ActiveX.
Por el momento no modificaremos nada en la opcin de Compatibility Options.
Pulsamos Next y mostrar la siguiente ventana:

En la parte superior nos mostrar el nombre del control al que se generar el archivo .fp
Podemos pulsar en el botn Advanced Options para mostrar la siguiente informacin:

34

En este pantalla podemos revisar cada una de las diferentes funciones que se van a generar.
Finalmente, al continuar con el proceso de generacin, tendremos la ltima pantalla que nos
confirma que se ha generado la librera para CVI.

Qu cambios hay en nuestro proyecto?


Recordemos la seccin de nuestro entorno de
desarrollo denominada panel de libreras. Ah
podremos observar que se ha agregado un nuevo
elemento denominado Microsoft Calendar Control
2007. Este nombre puede variar un poco de acuerdo
a la versin del ActiveX disponible en la
computadora.

Si extendemos el contenido de este elemento,


podremos observar en detalle cada una de las
funciones que tenemos disponibles para el
control ActiveX que hemos insertado en
nuestro proyecto.
Tambin podemos observar el prefijo que
tuvimos oportunidad de personal al inicio en el
asistente para generar la librera .fp

35

Otro lugar donde podemos confirmar que nuestra librera ha sido cargada, es en el men
principal de nuestro entorno de desarrollo, en la seccin de Instrument.

Podemos ver que en la parte superior de la lista, aparece el nombre que identifica a nuestra
librera .fp
El resto de las opciones de este submen, nos permiten administrar nuestras libreras. Es
decir, si disponemos de alguna otra librera de tipo .fp, aqu es donde podemos indicarle a
nuestro proyecto que las incluya, las elimine o incluso, editarlas.
Nosotros podemos crear desde cero nuestra propia librera .fp, sin embargo, ese es un tema
que requiere dedicar varias horas de trabajo y por el momento, esta fuera del alcance de este
curso.

Ejercicio utilizando el ActiveX de Calendario de Windows


Disearemos una interfaz como la siguiente:

36

Funcionamiento:
Esta aplicacin deber capturar los eventos del control Calendario que correspondan al
momento en que modificamos la fecha seleccionada en l.
Una vez capturado el evento de modificacin, en los controles inferiores (Da, Mes y Ao) se
deber actualizar con la informacin correspondiente. Esta informacin la obtendremos del
control Calendario.
Finalmente, el botn de comando Actualizar calendario al da de hoy, nos servir para
restaurar la fecha en el control Calendario a la actual de nuestro sistema.
Bien, pues comencemos a desarrollar nuestra aplicacin.
Una vez que hemos configurado nuestro UIR y generamos cdigo, tendremos dos funciones
Callback que nos servirn para:
-

Cerrar nuestra aplicacin


Capturar evento del botn de comando

No debemos definir una funcin callback para el control Calendario?


Si. Nuestro control Calendario necesita de una funcin callback para que nos informe cuando
se detecte un evento sobre el mismo, sin embargo, para los controles ActiveX LabWindows
no puede asociar una funcin callback de manera directa como hasta ahora lo hemos hecho
con controles y paneles. Ms adelante veremos cmo podemos obtener una funcin callback
de nuestro control Calendario.
Cmo utilizamos nuestro control Calendario en nuestro cdigo?
Al igual que nuestros paneles requieren de una referencia (manejador) para ser utilizados a
lo largo de nuestro cdigo, para cada control ActiveX que insertamos en nuestro cdigo
debemos generar una referencia para el mismo fin.
La instruccin que nos permite obtener una referencia de un control ActiveX es la siguiente:
GetObjHandleFromActiveXCtrl (panel, control, handle);
Donde:
-

Panel. Es la referencia del panel en el que se encuentra insertado el control


ActiveX
Control. El identificador del control, que como hemos visto, se compone por el
nombre de la constante del panel + el nombre de la constante del control
Handle. Es la variable donde se almacenar la referencia de nuestro control. Esta
variable es de un tipo de dato que no hemos manejado hasta el momento que es:
CAObjHandle

37

Si exploramos dentro de los archivos .h para encontrar qu tipo de dato es este,


encontraremos que es un tipo entero, sin embargo, las funciones estn diseadas
para esperar un dato de tipo CAObjHandle.
Esta referencia del control Calendario, bien la podemos obtener al inicio de nuestra
aplicacin, incluyendo cdigo en la funcin main. As mismo, la variable de referencia nos
conviene sea de alcance global.

Antes de comenzar a insertar funciones relacionadas con el control Calendario para obtener
informacin de l, necesitamos crear la funcin callback que nos falta.
Veamos en nuestro panel de libreras lo siguiente.
La librera tiene dos grupos de funciones:
- Event Callback Registration Functions
- ICalendar
El primer grupo nos ofrece lo siguiente:

Aqu tenemos cada una de las funciones que nos permitirn registrar nuestras funciones
callback y que podemos asociar a nuestro control Calendario. Podemos ver que tenemos
funciones para registrar eventos tales como:
- Despus de que se ha generado alguna actualizacin
- Antes de generar una actualizacin
- Un clic
- Double clic
- Etc.

38

Cmo registrar una funcin callback?.


Para ello, invocaremos la funcin que nos permita registrar el evento que nos interesa, por
ejemplo, seleccionaremos la de nombre

Para insertar la funcin, podemos


arrastrar y soltarla dentro de nuestro
cdigo. Esta funcin requiere de
algunos parmetros. Para poder
obtener asistencia en el llenado de
la funcin podemos pulsar clic
derecho sobre el nombre de la
funcin
y
seleccionar
Recall
Function Panel (Ctrl+P).

Esto nos mostrar el siguiente asistente:


Podemos ver que algunos parmetros son llenados
con informacin por default. Desafortunadamente
en la mayora de los casos, no dispondremos de
una ayuda descriptiva sobre par que son cada
unos de los parmetros de las funciones de un
control ActiveX. Sin embargo, con un poco de
prctica podremos ir dominando esta falta de ayuda
hasta que podamos manejar cualquier control
ActiveX en LabWindows.

39

En los dos parmetros que se encuentran en blanco, el primero nos est solicitando lo que
llama Server Object. Esto no es ms que la variable donde actualmente tenemos
almacena la referencia de nuestro control Calendario.
El segundo, est solicitando el nombre que tendr nuestra funcin callback que se asociar
con el evento que hemos seleccionado. Para este caso la he llamado MiFuncion.
Al final, nuestra lnea de cdigo quedara como sigue:

Hasta este momento hemos registrado la funcin callback, ahora hace falta crear la funcin
misma. Para ello, la estructura que debe tener la funcin es la siguiente:
HRESULT CVICALLBACK Callback (CAObjHandle caServerObjHandle,
void *caCallbackData);
Por lo tanto, nuestra funcin quedara como sigue:

40

Es importante definir el prototipo de nuestra funcin al principio, esto para que el compilador
tenga conocimiento de la misma.
Ahora s, ya tenemos lista nuestra funcin callback en la cual podemos insertar el cdigo
necesario para leer informacin del control Calendario. Estas funciones las encontraremos en
el segundo grupo de funciones de la librera creada.
Lo que necesitamos conocer del control calendario es la fecha seleccionada, para ello
requerimos funciones que nos informen el da, mes y ao activos.

Complementando las funciones con sus parmetros e incluyendo el cdigo para actualizar la
interfaz de usuario, nuestro cdigo quedara:

Finalmente, necesitamos incluir cdigo para que el botn de comando restablezca el control
Calendario a la fecha actual.
Si revisamos en la lista de funciones disponibles del control Calendario, encontraremos una
que se llama
Nuestra funcin quedara como sigue:

41

Listo, nuestra aplicacin que opera con el ActiveX de Calendario de Windows est terminada.
Con este ejemplo hemos visto el proceso de insertar, generar cdigo y utilizar funciones de
un control ActiveX. Para cualquier control ActiveX es el mismo proceso, el reto al que nos
estaremos enfrentando es el comprender el contenido de las funciones del mismo.
Veremos que existen controles con unas cuantas funciones que son sencillas de entender y
en algunos casos, pueden resultar algo extensas en su nmero de funciones y relaciones
que guardan entre ellas.
Por ejemplo, para el caso del reproductor Windows Media Player, los grupos de funciones
disponibles son los siguientes:

Y cada grupo puede tener una lista extensa de

funciones disponibles.
Complicado?. La verdad es que es ms sencillo de
lo que aparenta ser.

42

Para muchos controles ActiveX ayuda tener presentes el concepto de programacin


orientada a objetos (POO).
Si bien, el compilador de Ansi C de LabWindows no tiene soporte para una POO, los ActiveX
al momento de su construccin pudieron haber sido escritos bajo este paradigma.
Entonces, cmo se manejara un ActiveX de este tipo en LabWindows?. Dado que un
objeto pudiera ser el resultado de una serie de herencias de clases ms altas, antes de
comenzar a utilizar una funcin en particular de un ActiveX, necesitamos obtener la
referencia de la clase ms alta y comenzar a bajar clase por clase, hasta llegar a nuestra
funcin con la referencia correcta.
Cmo identificar las clases dentro de mi librera .fp?
Una clase sera un grupo de funciones en nuestra librera .fp Entonces, necesitaramos
obtener la referencia de ese grupo, para despus, con esa referencia obtener una segunda
de otro grupo y as sucesivamente hasta llegar al grupo que contiene la funcin que nos
interesa utilizar.
Aqu es donde tenemos que deducir nosotros esa relacin que pudieran guardar los grupos
de funciones entre s.
Algunas aplicaciones que nos ofrecen controles ActiveX y que podemos utilizar en nuestros
proyectos de LabWindows son:
-

Adobe Acrobat Reader


Flash Player
Reproductor Windows Media Player
Quick Time Player
Etc.

Con la experiencia de este ejercicio paso a paso, estamos en posibilidad de construir una
nueva aplicacin utilizando otro control ActiveX.

43

Ejercicio utilizando el ActiveX de Adobe Reader


Este ejercicio consistir en construir una aplicacin en LabWindows que nos permita
visualizar archivos PDF embebidos en nuestro panel.
El aspecto de nuestra interfaz de usuario sera la siguiente:

Les complemento
adicionales.

con

algunas

pantallas

El botn de Seleccionar archivo, deber


permitir buscar archivos de extensin PDF.

44

Una vista de cmo lucira nuestro visor de archivos PDF.

Listo, adelante con la construccin de su aplicacin.

45

Manejo de bases de datos


LabWindows nos permite interactuar prcticamente con cualquier base de datos que
necesitemos trabajar. Para lograr esto se auxilia de un toolkit denominado LabWindows/CVI
SQL Toolkit, el cual proporciona un grupo de funciones de alto nivel que permiten establecer
la comunicacin con la base de datos.
Algunas de las caractersticas de este toolkit, son el que soporta comunicacin con bases de
datos a travs del estndar ADO (Active Data Object) y con manejadores ODBC (Open
Database Connectivity).
Entre las funciones que disponemos para el manejo de la informacin de la base de datos,
tenemos las que nos permiten leer el tipo de dato de la columna que se est consultando,
crear tablas, ejecutar selecciones, inserciones, actualizaciones y eliminar a travs de
sentencias SQL.
Antes de comenzar a utilizar bases de datos con LabWindows, daremos un repaso de
algunos conceptos bsicos de bases de datos.

Conceptos de base de datos


Una base de datos es una coleccin organizada de datos. Las aplicaciones de administracin
de bases de datos ms actuales (MySQL, SQL Server, Oracle, etc), implementan esta
organizacin a travs de lo que se conoce como tablas.
Las tablas estn organizadas en registros tambin conocidos como renglones y en campos,
tambin conocidos como columnas.
Cada tabla de una base de datos debe tener un nombre nico. Lo mismo aplica para los
nombres de los campos que integran una tabla.
Las tablas de una base de datos pueden tener diversos usos. La siguiente tabla es un
ejemplo en donde se utiliza para almacenar informacin de los resultados de un programa
que lleva a cabo pruebas secuenciales. La tabla tiene columnas para el nmero de unidad
bajo prueba (UUT), nombre de la prueba, resultado de la prueba y dos mediciones.

Los datos al interior de una tabla no tienen un orden especfico. Ordenarlos, agruparlos y otro
tipo de operaciones con la informacin ocurre cuando de utiliza la sentencia SELECT para
46

extraer la informacin de la tabla. Un rengln puede tener columnas vacas, lo cual significa
que el rengln contiene valores nulos (NULL). Hay que destacar que el valor nulo en una
base de datos, no es lo mismo que el valor nulo utilizado en la programacin en lenguaje C.
Cada columna en una tabla tiene un tipo de dato definido. La disponibilidad de los datos
depender de cada administrador de base de datos (DBMS). El toolkit de SQL de
LabWindows usa un grupo comn de tipos de datos.
La siguiente tabla muestra los tipos de datos soportados por el LabWindows/CVI Toolkit SQL.

Structured Query Language (SQL)


El SQL consiste de un estndar ampliamente soportado para el acceso a bases de datos.
Los comandos de SQL son utilizados para manipular los renglones y columnas en las tablas
de una base de datos. Los comando de SQL se dividen en dos tipos de sentencias: DDL y
DML.
-

DDL (Data Definition Languaje - lenguaje de definicin de datos): las


sentencias DDL nos sirven para crear tablas y sus componentes: tablas, ndices,
relaciones, disparadores (triggers), procedimientos almacenados, etc.
DML (Data Manipulation Languaje - lenguaje de manipulacin de datos): las
sentencias DML son aquellas utilizadas para insertar, borrar, modificar y consultar
los datos de una base de datos.

A lo largo de este documento, nos enfocaremos en mayor medida a las sentencias DML.
La siguiente es una lista de los comandos ms comunes de SQL:
-

CREATE TABLE. Permite crear una nueva tabla especificando el nombre y tipos
de datos para cada una de las columnas.
SELECT. Extrae todos los renglones en una tabla que cumplen con la condicin
especificada.
INSERT. Agrega un nuevo registro a la tabla. Esto permite asignar los valores
deseados a cada una de las columnas.
47

UPDATE. Actualiza los valores en las columnas especificadas para todos los
renglones que cumplan con la condicin definida.
DELETE. Elimina todos los registros que cumplan con la condicin especificada.

Ejercicios con cdigo SQL


Vamos a realizar algunos ejercicios utilizando cdigo SQL con Microsoft Access.
Debido a que Access tiene limitaciones para procesar cdigo SQL por lotes, ser necesario
que ejecutemos una a una las siguientes lneas de cdigo SQL. El objetivo es que al final
tengamos lista una base de datos con tres tablas e informacin incluida con la que
trabajaremos.
Primero necesitamos crear una base de datos en blanco, para ello abriremos Access.

1. Primero pulsaremos clic sobre el icono de Base de datos en blanco. Esto nos
habilitar la seccin nmero 2.
2. En esta parte definiremos el nombre de nuestra base de datos y la ubicacin de la
misma.
3. Indicaremos que Access proceda con la creacin de nuestra base de datos en blanco
(sin tablas).

48

Veremos la siguiente pantalla.


Por default nos propone una tabla en blanco con
el nombre Tabla1.
Esta tabla no la necesitamos, por lo que
procedemos a indicarle a Access que la cierre de
la siguiente manera:

Ahora con nuestro entorno de desarrollo limpio, buscaremos abrir el editor de SQL desde el
men principal en la opcin Crear y posteriormente clic en la opcin Diseo de consulta.

Access nos mostrar la siguiente pantalla, misma que podemos cerrar.

49

Ahora habilitaremos el editor de SQL pulsando clic en el siguiente botn:

Listo!! Tenemos nuestro editor para recibir sentencias de SQL.

Bien, a continuacin se encuentran las sentencias de SQL que deberemos ejecutar una a la
vez. Esto ser, copiar la sentencia de este documento y pegar reemplazando lo que exista en
el editor (donde dice SELECT;). Posteriormente pulsar clic en el botn
confirmando la accin.
Comencemos!

50

Las siguientes sentencias son para crear nuestras tres tablas.


a) CREATE TABLE Frecuentan(bebedor varchar(20) NOT NULL,bar varchar(20) NOT
NULL);
b) CREATE TABLE Sirven(bar varchar(20) NOT NULL,cerveza varchar(20) NOT NULL);
c) CREATE TABLE Le_Gusta_Beber(bebedor varchar(20) NOT NULL,cerveza varchar(20)
NOT NULL);

Al concluir esta parte deberemos ver lo siguiente en Access.

Ya tenemos listas nuestras 3 tablas, ahora comencemos a insertar datos en cada una de
ellas ejecutando de igual manera las siguientes sentencias.
Para la tabla Frecuentan:
a)
b)
c)
d)
e)
f)
g)
h)

insert
insert
insert
insert
insert
insert
insert
insert

into
into
into
into
into
into
into
into

Frecuentan
Frecuentan
Frecuentan
Frecuentan
Frecuentan
Frecuentan
Frecuentan
Frecuentan

VALUES('Hugo','Los Correa');
VALUES('Hugo','Los Tres Amigos');
VALUES('Hugo','El Portal');
VALUES('Paco','Los Tres Amigos');
VALUES('Paco','El Cortijo');
VALUES('Luis','Los Correa');
VALUES('Luis','El Portal');
VALUES('Tere','El Fuerte');

Para la tabla Sirven:


a)
b)
c)
d)
e)
f)
g)
h)
i)
j)
k)
l)
m)

insert
insert
insert
insert
insert
insert
insert
insert
insert
insert
insert
insert
insert

into
into
into
into
into
into
into
into
into
into
into
into
into

Sirven
Sirven
Sirven
Sirven
Sirven
Sirven
Sirven
Sirven
Sirven
Sirven
Sirven
Sirven
Sirven

VALUES('Los Correa','Budweiser');
VALUES('Los Correa','Heineken');
VALUES('Los Correa','Tecate');
VALUES('Los Correa','Modelo Especial');
VALUES('Los Tres Amigos','Budweiser');
VALUES('Los Tres Amigos','Heineken');
VALUES('Los Tres Amigos','Tecate');
VALUES('Los Tres Amigos','Corona');
VALUES('El Portal','Budweiser');
VALUES('El Portal','Corona');
VALUES('El Portal','Sol');
VALUES('El Fuerte','Modelo Especial');
VALUES('El Cortijo','Indio');

51

Para la tabla Le_Gusta_Beber:


a)
b)
c)
d)
e)
f)
g)
h)
i)

insert
insert
insert
insert
insert
insert
insert
insert
insert

into
into
into
into
into
into
into
into
into

Le_Gusta_Beber
Le_Gusta_Beber
Le_Gusta_Beber
Le_Gusta_Beber
Le_Gusta_Beber
Le_Gusta_Beber
Le_Gusta_Beber
Le_Gusta_Beber
Le_Gusta_Beber

VALUES('Hugo','Budweiser');
VALUES('Hugo','Modelo Especial');
VALUES('Hugo','Corona');
VALUES('Paco','Heineken');
VALUES('Paco','Corona');
VALUES('Luis','Heineken');
VALUES('Luis','Tecate');
VALUES('Luis','Corona');
VALUES('Tere','Negra Modelo');

Qu informacin hemos ingresado a nuestras tablas?


Vamos a revisar la informacin de cada una de nuestras tablas. Para ello comenzaremos a
utilizar nuestra sentencia SELECT de la siguiente forma.
En el mismo editor de SQL, comencemos con lo siguiente:
select * from Frecuentan;

al ejecutar esta sentencia, Access nos mostrar la siguiente vista:

Aqu tenemos una vista que contiene el nombre de la persona (columna bebedor) y el
nombre del bar (columna bar) que acostumbra visitar.
He resaltado el nombre de la pestaa que tiene el nombre Consulta1, porque lo que
estamos viendo es el resultado de la consulta, no la tabla en s misma. As ocurrir con cada
SELECT que ejecutemos, el resultado ser una vista con la informacin que hayamos
solicitado.
Si quisiramos ver el contenido de la tabla, bastar con dar doble clic en el nombre de la
tabla.

52

Para ingresar una nueva consulta, bastar pulsar clic derecho sobre el nombre de la pestaa
y seleccionar Vista SQL.

Continuemos con nuestra segunda consulta, select * from Sirven:

En este caso, tenemos una tabla que nos muestra el bar (columna bar) con sus respectivos
tipos de cervezas que sirven (columna cerveza).
53

Concluyamos con la tercer sentencia select * from Le_Gusta_Beber:

En esta ocasin, tenemos el nombre de la persona (columna bebedor) y la cerveza que es de


su agrado tomar (columna cerveza).
En resumen, tenemos la informacin de los bares que les gusta visitar a cada una de las
personas, as como la cerveza que ofrecen cada uno de los bares y la cerveza que le gusta
tomar a cada uno de ellos.
Con esta informacin comenzaremos a realizar algunas consultas interesantes. No
entraremos en detalle sobre la explicacin de cada una de las consultas en este documento,
sin embargo, podemos discutir su funcionamiento, el objetivo principal es tener una idea del
potencial que tenemos al utilizar el comando SELECT. Para ampliar la informacin sobre
SQL, recomiendo consultar un tutorial sobre SQL.
Comencemos:
a) Queremos imprimir todos los bares que
tiene registrados el sistema.
SELECT bar FROM frecuentan
UNION
SELECT bar FROM sirven;

54

b) Queremos imprimir todas las


marcas de cerveza que tiene
registradas el sistema.
SELECT cerveza FROM sirven
UNION
SELECT cerveza FROM
Le_Gusta_Beber;

c) Queremos imprimir todos los


bebedores
que
se
tienen
registrados en el sistema.
SELECT bebedor FROM frecuentan
UNION
SELECT bebedor FROM
Le_Gusta_Beber;

d) Queremos imprimir los bares que sirven


una cerveza que le gusta beber a Hugo.
select DISTINCT bar from sirven where
cerveza IN
(select cerveza from Le_Gusta_Beber
where bebedor LIKE 'Hugo');

e) Imprimir los bebedores que frecuentan bares donde sirven alguna cerveza que les
gusta.
SELECT DISTINCT f.bebedor FROM Frecuentan f, Sirven s, Le_Gusta_Beber l
WHERE f.bar = s.bar AND s.cerveza = l.cerveza AND f.bebedor = l.bebedor;

55

f) Imprimir el bar que sirve la mayor cantidad


de marcas de cerveza.
SELECT bar,COUNT(*) AS Bares FROM
Sirven GROUP BY bar
HAVING COUNT(*) >=ALL
(SELECT COUNT(*) FROM Sirven
GROUP BY bar );

g) Imprimir el bar que sirve la menor


cantidad de macas de cerveza.
SELECT bar,COUNT(*) AS Bares FROM
Sirven GROUP BY bar
HAVING COUNT(*) <=ALL
(SELECT COUNT(*) FROM Sirven
GROUP BY bar );

56

h) Imprimir a los bebedores que frecuentan


bares donde sirven ms marcas de
cerveza que la cantidad de marcas que a
ellos les gusta. Imprimir al bebedor y al
bar que frecuentan.
SELECT bebedor, bar FROM Frecuentan f
WHERE EXISTS (
SELECT bar FROM Sirven s
WHERE f.bar = s.bar
GROUP BY s.bar
HAVING COUNT(*) > (SELECT COUNT(*)
FROM Le_Gusta_Beber l
WHERE f.bebedor = l.bebedor))
ORDER BY bebedor;

Cada una de estas sentencias de SQL las podemos ejecutar tal cual dentro de
LabWindows/CVI, ms adelante comenzaremos a analizar como lograremos esto.
Por ahora continuemos revisando los requisitos de configuracin previos a trabajar con
LabWindows.

LabWindows/CVI Toolkit SQL


Al inicio de esta seccin se mencion que LabWindows puede conectarse con bases de
datos a travs de un toolkit.
Este toolkit lo podemos encontrar en los DVDs de instalacin de la Suite de National
Instruments. Para el caso de la Suite 2009 Tercer Cuarto, se encuentra en el tercer DVD.
En necesario instalar este toolkit antes de comenzar a trabajar con LabWindows.
La instalacin no requiere de configuracin alguna, basta con seguir el asistente hasta
concluir la misma.

Adminstrador ODBC
La mayora de las ocasiones al trabajar con una base
de datos en LabWindows, requeriremos hacer algunas
modificaciones de configuracin al administrador de
orgenes de datos que tiene Windows.
Esto administrador al ejecutarlo mostrar la siguiente
ventana.

57

Aqu definiremos el nombre de nuestro nuevo origen de datos, que no es ms que


seleccionar un controlador para el tipo de base de datos a utilizar y asociarlo en su caso, con
nuestra base de datos.
Para ello, cuando pulsamos en el
Agregar, veremos la siguiente ventana.

botn

De la lista de controladores existentes,


seleccionaremos el que corresponda a nuestro
tipo de base de datos a utilizar:
- Microsoft Access
- Visual FoxPro
- Oracle
- SQL Server
- MySQL
- PostgreSQL
- Etc.
Para cada tipo de controlador se requerir una configuracin en particular. En algunos casos
como Microsoft Access, bastar con definir un nombre para identificar a nuestro origen de
datos (este nombre lo ocuparemos al interior de nuestro cdigo en LabWindows) y la ruta
donde se encuentra la base de datos a utilizar.
En otros casos habr que definir un usuario, contrasea, ubicacin del servidor y la base de
datos a utilizar.
Concluyendo el proceso anterior, tendremos listo nuestro origen de datos para ser utilizado
por nuestra aplicacin.
En algunas ocasiones es posible que nuestro sistema Windows no cuente con el controlador
de base de datos que necesitamos. En este caso tendremos que buscar el controlador para
instalarlo.
Por ejemplo, si necesitamos
nuestro conector ODBC
para MySQL bajo sistemas
Windows,
podramos
recurrir a un buscador en
web y buscar de la siguiente
forma.

58

Encontraremos el conector para descargar con informacin referente a su versin, plataforma


de trabajo, tipo de instalador, etc.

Una vez instalado el controlador correspondiente, dispondremos del mismo en nuestra


ventana de configuracin de administrador de orgenes de datos.

LabWindows y bases de datos


Comenzaremos conociendo las relaciones que existen entre las funciones del toolkit para el
manejo de bases de datos con la siguiente figura.

59

Qu nos indica la figura anterior?


Primero consideraremos nuestras acciones sobre una base de datos en dos grupos:
1) Para consultar informacin (implica la sentencia SELECT)
2) Para insertar, actualizar o borrar informacin (INSERT, UPDATE o DELETE)
En el primer caso, la secuencia que debemos seguir en el diagrama es la siguiente:

Para el segundo caso, la secuencia a seguir es la siguiente:

60

Cmo realizar una consulta en LabWindows?


En este momento estamos ms familiarizados con el concepto de referencias en
Labwindows. As como un panel o un control ActiveX requieren que obtengamos una
referencia a ellos, en base de datos tendremos algo similar.

Primero comenzaremos por establecer nuestra conexin a la base de datos a travs de


nuestro ODBC (origen de datos) previamente configurado. De este ODBC lo que
necesitamos conocer es el nombre que hayamos asignado.
Para establecer la conexin contamos con la siguiente funcin:
iRefODBC = DBConnect(nombre del ODBC);
La variable que reciba la referencia (tipo entero), se conseja sea de mbito global, ya que
ser utilizada para diferentes funciones relacionadas con la base de datos.
El nombre del ODBC debe ir entre comillas, ya que el parmetro que espera es un string.
La conexin a la base de datos basta que se realice una vez al iniciar la aplicacin y
concluirla cuando se cierre la aplicacin.

El siguiente paso es ejecutar nuestra sentencia SELECT deseada. Por ejemplo, consultemos
el contenido de la tabla Frecuentan.
La funcin a utilizar es la siguiente:
iRefConsulta = DBActivateSQL(iRefODBC, select * from Frecuentan);

Recordemos de nuestros ejercicios de consulta con Access, que al ejecutar una sentencia
SELECT nos retornaba una vista con el contenido de la informacin solicitada.
Para la sentencia que estamos ejecutando, el asterisco (*) significa que queremos ver todas
las columnas de la tabla frecuentan.

61

LabWindows no puede mostrar una vista como lo hace Access, sin embargo, nos retorna una
referencia a dicha vista (para el ejemplo en la variable entera iRefConsulta). Con esta
referencia podremos leer el contenido de la vista.
iRefConsulta = DBActivateSQL(iReferenciaODBC, select * from Frecuentan);

iRefConsulta

Lo siguiente que analizaremos, es cmo LabWindows puede vincular en base a la referencia


obtenida, el contenido de cada columna de la vista que se ha generado.

iRefConsulta

Para poder vincular la informacin de la vista que hemos generado, necesitamos conocer el
tipo de dato de cada una de las columnas contenidas para identificar la funcin de lectura
adecuada en LabWindows.
Por ejemplo:
Tipo texto
Vista generada

Tipo texto

62

Las funciones que nos ofrece LabWindows para vincular nuestro cdigo con el contenido de
una columna en una vista, son las siguientes:
-

DBBindColChar. Nos servir para leer informacin de una columna de tipo


carcter o string.

Donde:

resCode. Retorna el estado de ejecucin de la funcin. En caso de


error, aqu podemos saberlo.
statementHandle. Espera la variable que contiene la referencia a la
vista que se ha consultado.
columnNumber. Nmero de columna a leer. Para el ejemplo que
estamos manejando tendramos:
1

maxLen. Longitud de la cadena en bytes.


locationForValue[]. Apuntador a la variable arreglo de char donde
se almacenar la cadena a leer.
*locationForStatus. Apuntador a la variable que almacenar el
estado de la lectura de la informacin indicando si la informacin fue
truncada o se ley un NULL.
formatString[]. Se utiliza para dar formato a la cadena a leer.

DBBindColShort. Utilizada para leer informacin de una columna con un tipo de


dato short.

Donde:

locationForValue. Apuntador a la variable tipo short int donde se


almacenar la cadena a leer.

DBBindColInt.

63

Donde:

locationForValue. Apuntador a la variable tipo short int donde se


almacenar la cadena a leer.

DBBindColFloat.

Donde:

locationForValue. Apuntador a la variable tipo float donde se


almacenar la cadena a leer.

DBBindColDouble. Utilizada para leer informacin de una columna con


informacin de tipo doble.

Donde:

*locationForValue. Apuntador a la variable de tipo doble donde se


almacenar el dato a leer.

Es importante que el nmero de columna que se ingrese en cada una de las funciones
anteriores, corresponda con el orden de las columnas que existe en la vista que
hemos generado.
Volviendo a nuestro ejemplo de consulta a la tabla Frecuentan, nuestro cdigo desde la
conexin a la base de datos hasta vincular la vista a variables de cdigo quedara como
sigue:

La longitud de los arreglos de tipo char se han definido de 21 bytes, porque al construir
nuestra tabla Frecuentan, definimos que el ancho de cada una de las columnas fuera de 20
caracteres. El byte adicional es para que se pueda incluir el carcter de fin de cadena.

64

Una vez que tenemos establecida la vinculacin con las columnas de la vista, el siguiente
paso es leer rengln por rengln de la vista generada.
Para este efecto, LabWinidows nos ofrece las siguientes funciones:
-

DBFetchNext. Permite avanzar al siguiente registro disponible.

Donde:

statementHandle. Espera la variable que contiene la referencia a la


vista que se ha consultado.

La funcin retornar un valor diferente a cero cuando no haya ms registros a


dnde saltar.
Cuando se realiza la vinculacin de variables (seccin anterior), nuestro cursor en
la vista no se ha posicionado an sobre los datos, necesitamos ejecutar por lo
menos una vez la funcin DBFetchNext para tener acceso a los datos.
cursor

Despus de ejecutar DBFetchNext:


cursor

DBFetchPrev. Permite regresar el cursor al registro inmediato anterior.

DBFetchRandom. Cuando conocemos la cantidad de registros que existen en la


vista que hemos generado, podemos dar saltos a registros especficos a travs de
esta funcin.

65

Donde:

recordNumber. El nmero de registro al que deseamos saltar.

Al ejecutar estas funciones, dnde se encuentra la informacin leda?. Recordemos nuestro


cdigo donde vinculamos variables a las columnas de la vista.
Variables vinculadas

Cada vez que ejecutemos por ejemplo DBFetchNext, el contenido de estas variables se
actualizar con la informacin correspondiente a donde se encuentre nuestro cursor.
Veamos la siguiente secuencia:
Nmero de ejecucin
De DBFetchNext

Variable
cBebedor

Variable
cBar

Cursor en la
vista

Ninguna

Primera

Hugo

Los Correa

Segunda

Hugo

Los Tres Amigos

Tercera

Hugo

El Portal

Cuarta

Paco

Los Tres Amigos

As sucesivamente podemos ir recorriendo el contenido de nuestra vista.

66

Cmo quedara nuestro cdigo para leer todo el contenido de la vista?. A continuacin se
muestra una propuesta.

Es un ciclo que se ejecutar mientras el resultado de la funcin DBFetchNext sea igual a la


constante DB_SUCCESS que tiene un valor de cero.
Una vez que se alcance el final de la vista, se dejar de ejecutar el ciclo.

Cada vez que se termine de utilizar la informacin de una vista, es necesario liberar la
referencia a la misma. Para ello disponemos de la funcin DBDeactivateSQL.

Finalmente, cuando se determine que no es necesario mantener abierta la conexin con la


base de datos, disponemos de la funcin DBDisconnect para cerrar la misma.

Nuestro cdigo final quedara como sigue:

67

Ejercicio para leer el contenido de la tabla Frecuentan


Disearemos una interfaz como la siguiente:

El objetivo es que al pulsar el botn Leer tabla, leamos el contenido y lo coloquemos en la


pantalla para lograr lo siguiente:
MS Access

Para este ejercicio, introduciremos una nueva instruccin de nombre Fmt.


A continuacin incluyo algunos ejemplos de uso de esta instruccin:

68

Para mayor informacin sobre el uso de esta funcin, pueden referirse a la ayuda de
LabWindows.

69

Cmo realizar una insercin, una actualizacin o eliminacin de registros?


Para llevar a cabo estas acciones, necesitaremos disponer solamente de la referencia al
ODBC que comunica con la base de datos.
Al inicio de esta seccin, se hizo el ejercicio de insertar informacin en una base de datos de
Access. Sentencias similares son las que utilizaremos ms adelante.

Para ejecutar esta funcin, necesitaremos previamente haber construido la sentencia SQL
que deseamos ejecutar y tenerla lista en una arreglo char.

Donde:

connectionHandle. Es la variable que contiene la referencia a


nuestra conexin con la base de datos.
*SQLStatement. La cadena con la sentencia SQL a ejecutar

Un ejemplo de cdigo para insertar el nombre de una persona y el bar que le gusta
frecuentar, quedara como sigue:

70

Ejercicio para insertar informacin a la tabla Frecuentan


Modificaremos nuestra aplicacin anterior para lograr lo siguiente:

Con esta nueva aplicacin, lo que haremos es, dados un nombre de bebedor y un nombre de
bar que frecuenta, a travs del botn Insertar registro sern agregados a la tabla
Frecuentan.
Para verificar que esto se haya llevado a cabo, bastar con pulsar en el botn Leer tabla
para actualizar la lista con el contenido.

Comandos UPDATE y DELETE


A continuacin veamos informacin sobre el uso de estas dos instrucciones.
Update. Crea una consulta de actualizacin que cambia los valores de los campos de una
tabla especificada basndose en un criterio especfico. Su sintaxis es:
UPDATE Tabla SET Campo1=Valor1, Campo2=Valor2,... CampoN=ValorN WHERE Criterio;

UPDATE es especialmente til cuando se desea cambiar un gran nmero de registros o


cuando stos se encuentran en mltiples tablas. Puede cambiar varios campos a la vez.
UPDATE no genera ningn resultado. Para saber qu registros se van a cambiar, hay que
examinar primero el resultado de una consulta de seleccin que utilice el mismo criterio y
despus ejecutar la consulta de actualizacin.
Si en una consulta de actualizacin suprimimos la clusula WHERE todos los registros de la
tabla sealada sern actualizados.

71

Delete. Crea una consulta de eliminacin que elimina los registros de una o ms de las
tablas listadas en la clusula FROM que satisfagan la clusula WHERE. Esta consulta
elimina los registros completos, no es posible eliminar el contenido de algn campo en
concreto. Su sintaxis es:
DELETE FROM Tabla WHERE criterio

Una vez que se han eliminado los registros utilizando una consulta de borrado, no puede
deshacer la operacin. Si desea saber qu registros se eliminarn, primero examine los
resultados de una consulta de seleccin que utilice el mismo criterio y despus ejecute la
consulta de borrado.

Ejercicio para eliminar informacin a la tabla Frecuentan


Modificaremos nuestra aplicacin para lograr lo siguiente:

El objetivo es que dado el nombre de un bebedor, procedamos a eliminar todos sus registros
y verifiquemos la accin mediante el botn Leer tabla.

Apuntes finales sobre SQL


Como hemos observado en los ejercicios anteriores, las acciones que se realizan sobre la
base de datos dependen directamente de la sentencia SQL que se estructure, LabWindows
es solamente el intermediario para llevarlas a cabo. Por lo tanto, el realizar consultas
sofisticadas, ordenar informacin en consultas, agrupar, etc., requerir el que ampliemos
nuestro conocimiento de SQL.
Dado que las variantes en el uso de SQL es extenso, resultara complicado tratar de abordar
cada tema en este curso, sin embargo, recomiendo para quien est interesado, se auxilie de
un tutorial sobre SQL y experimente su uso con LabWindows. Cualquier duda sobre su
implementacin la podemos discutir.
72