Enviando una consulta a EXCEL

2 comentarios

Hay muchas formas de enviar el resultado de una consulta a una planilla Excel, aquí veremos una de esas formas.

NOTA: el código fuente está basado en Visual FoxPro pero puede ser fácilmente adaptado a otros lenguajes de programación.

La ventaja de este método es que nos resultará muy fácil enviar la consulta que queremos, al libro Excel que queremos, a la hoja Excel que queremos, en el rango que queremos mostraremos la consulta, y esa consulta puede estar basada en cualquier tabla o en cualquier vista de nuestra Base de Datos del Firebird.

Primero, creamos la función que se encargará de realizar la tarea.

Listado 1.

FUNCTION ENVIAR_EXCEL_CON_DSN
LParameters tcDSN, tcUsuario, tcPassword, tcConsulta, tcRango
Local lcMensajeError, lcConsulta, loExcel, loLibro, loHoja, loTabla, lcConexion, lcBaseDatos

  lcMensajeError = ""

  tcRango = iif(VarType(tcRango) <> "C", "A1", tcRango)    && Si no se definió donde colocar la tabla, se la coloca en la celda A1

  *-- Tratamos de crear un objeto Excel
  if Empty(lcMensajeError)
    loExcel = CreateObject("Excel.Application")
    lcMensajeError = iif(VarType(loExcel) <> "O", "No se pudo crear el objeto EXCEL, verifica si está instaldo EXCEL", lcMensajeError)
  endif

  *-- Si todo OK, tratamos de crear un libro Excel
  if Empty(lcMensajeError)
    loLibro = loExcel.Workbooks.Add
    lcMensajeError = iif(VarType(loLibro) <> "O", "No se pudo crear el libro de EXCEL", lcMensajeError)
  endif

  *-- Si todo OK, tratamos de crear una hoja en el libro Excel
  if Empty(lcMensajeError)
    loHoja = loLibro.Worksheets(1)
    lcMensajeError = iif(VarType(loHoja) <> "O", "No se pudo crear la hoja en el libro EXCEL", lcMensajeError)
  endif

  *-- Si todo OK, creamos el string de conexión a la Base de Datos del Firebird, usando el DSN de esa Base de Datos
  if Empty(lcMensajeError)
    lcConexion = "ODBC;DSN=" + tcDSN + ";USER=" + tcUsuario + ";PASSWORD=" + tcPassword
  endif

  *-- Si todo OK, tratamos de conectarnos a la Base de Datos del Firebird
  if Empty(lcMensajeError)
    loTabla = loHoja.QueryTables.Add(lcConexion, loHoja.Range(tcRango), tcConsulta)
    lcMensajeError = iif(VarType(loTabla) <> "O", "No se pudo crear la tabla de consulta en la planilla Excel", lcMensajeError)
  endif

  *-- Si todo OK, insertamos la tabla en la planilal Excel
  if Empty(lcMensajeError)
    #DEFINE xlInsertEntireRows 2
    loTabla.RefreshStyle = xlInsertEntireRows
    loTabla.Refresh
  endif

  *-- Si todoOK, mostramos la planilla Excel
  if Empty(lcMensajeError)
    loExcel.Visible = .T.
  endif

  *-- Liberamos de la memoria los objetos que habíamos creado
  loTabla = .NULL.
  loHoja  = .NULL.
  loLibro = .NULL.
  loExcel = .NULL.

Return(lcMensajeError)
*
*

Y después llamamos a esa función, con los parámetros que deseemos usar.

Listado 2.

Local lcDSN, lcUsuario, lcPassword, lcConsulta, lcMensajeError, lcRango

  lcDSN = "AUTOMUNDO-FIREBIRD"

  lcUsuario = "SYSDBA"
  lcPassword = "masterkey"

   lcConsulta = "SELECT " ;
              + "   ASC_ANOEJE, " ;
              + "   ASC_CODSUC, " ;
              + "   ASC_FECHAX, " ;
              + "   ASC_NUMERO " ;
              + "FROM " ;
              + "   V_CONTA_ABM_ASIENTOS " ;
              + "WHERE " ;
              + "   ASC_NUMERO >= 100 AND " ;
              + "   ASC_NUMERO <= 120"

  lcRango = "B5"

  lcMensajeError = ENVIAR_EXCEL_CON_DSN(lcDSN, lcUsuario, lcPassword, lcConsulta, lcRango)

  *-- Si ocurrió algún error, mostramos un mensaje al usuario
  if !Empty(lcMensajeError)
    #DEFINE MSG_ICONO_ERROR 16
    #DEFINE MSG_BOTON_ACEPTAR 0
    =MessageBox(lcMensajeError, MSG_ICONO_ERROR + MSG_BOTON_ACEPTAR, "Hay un problema...")
  endif

Return
*
*

Y así obtendremos una planilla similar a la siguiente:

EXCEL01

Captura 1. Si haces clic en la imagen la verás más grande

Por lo tanto, nos resultará muy sencillo crear una planilla Excel con los datos que el usuario pueda necesitar. Inclusive podríamos tener en nuestra aplicación una opción que le muestre todas las vistas disponibles y que le permita crear consultas personalizadas, a su gusto y paladar. Ya depende de la creatividad de cada uno hacer algo así.

Artículos relacionados:

Usando EXCEL para leer bases de datos de Firebird

Planillas EXCEL dinámicas con Firebird (1)

Planillas EXCEL dinámicas con Firebird (2)

El índice del blog Firebird21

El foro del blog Firebird21

 

Guardando y recuperando fotografías y vídeos

1 comentario

Si usas Visual FoxPro con Firebird entonces podría serte útil descargar un archivo .ZIP dentro del cual hay unos .PRG y un formulario en cuyos códigos fuente podrás ver:

  • Como mostrar una fotografía guardada en el disco duro
  • Como guardar esa fotografía en una tabla de Firebird
  • Como recuperar esa fotografía para poder mostrarla
  • Como mostrar un vídeo guardado en el disco duro
  • Como grabar ese vídeo en una tabla de Firebird
  • Como recuperar ese vídeo para poder mostrarlo
  • Como conectarse a una webcam
  • Como mostrar lo que está filmando la webcam
  • Como guardar una captura de lo que está filmando la webcam
  • Como desconectarse de la webcam

FOTOS_VIDEOS_1Captura 1. Si haces clic en la imagen la verás más grande

FOTOS_VIDEOS_1

Captura 2. Si haces clic en la imagen la verás más grande

 FOTOS_VIDEOS_3Captura 3. Si haces clic en la imagen la verás más grande

 FOTOS_VIDEOS_4Captura 4. Si haces clic en la imagen la verás más grande

NOTAS:

  •  No necesitas estar conectado a la Base de Datos para elegir y ver fotografías y vídeos que se encuentran en el disco duro o para usar la webcam
  • Para poder guardar o recuperar las fotografías y los vídeos en una tabla de Firebird evidentemente sí tendrás que estar conectado a la Base de Datos
  • Con la opción de vídeos no solamente podrás elegir vídeos sino también archivos .MP3 y .WAV, para escuchar música y sonidos. Usé un control VMPlayer.OCX7 en este formulario, pero por supuesto que tú puedes usar cualquier otro que te guste
  • Si quieres, puedes hacer clic en el checkbox “Mostrar contraseña” para ver la contraseña que se escribe en el campo de texto “Contraseña”. Es opinión del autor de este blog que esa opción siempre debería existir cuando se pide una contraseña
  • El código fuente es muy profesional pero por supuesto que podría mejorarse, si no programas de esta manera podría serte útil fijarte y revisar muy bien el código fuente, podrías aprender algo. Una mejora evidente es crear una clase que tenga todas esas opciones para que cuando necesites tener gráficos, fotografías, vídeos, o webcam, te resulte muy fácil conseguirlo.
  • El archivo .ZIP puedes descargar desde:

http://www.mediafire.com/download/9xdqn838zbu2jyh/SQL_FOTOGRAFIAS.zip

 Artículos relacionados:

Guardando y mostrando fotografías

El índice del blog Firebird21

El foro del blog Firebird21

 

 

Guardando y leyendo una columna de tipo TIMESTAMP en VFP

2 comentarios

Si programas usando el lenguaje Visual FoxPro entonces puedes tener dos dudas:

  1. ¿Cómo hago para guardar un dato en una columna de tipo TIMESTAMP?
  2. ¿Cómo hago para leer una columna de tipo TIMESTAMP?

1. Guardando una columna de tipo TIMESTAMP

Las columnas TIMESTAMP del Firebird se guardan como una fecha, un espacio en blanco, y una hora. Algo como:

03/08/2014 11:48:25

Que significa: “tres de agosto de dos mil catorce, once horas, cuarenta y ocho minutos, veinticinco segundos”.

En Visual FoxPro para convertir un string en un timestamp se usa la función CTOT(). Veamos un ejemplo:

MiFecha = DATE()
MiHora ="11:48"
MiColumna = CTOT(DTOC(MiFecha) + " " + MiHora)

La función DTOC() significa “date to character” y convierte una fecha a caracter. La función CTOT() significa “character to timestamp” y convierte un caracter a timestamp.

Hay que usar la función DTOC() para poder concatenar la fecha, el espacio en blanco, y la hora.

Fíjate que no es obligatorio completar los segundos, si no pones los segundos el Firebird asumirá que es “00”

Otro ejemplo:

MiFecha = DATE()
MiHora ="11:48:25"
MiColumna = CTOT(DTOC(MiFecha) + " " + MiHora)

 Aquí sí se establecieron los segundos. Es opcional.

Otro ejemplo:

MiFecha = DATE(2014, 8, 3)
MiHora = TIME()
MiColumna = CTOT(DTOC(MiFecha) + " " + MiHora)

 Aquí se usó la función DATE() para establecer la fecha deseada y la función TIME() para establecer la hora deseada.

2. Leyendo una columna de tipo TIMESTAMP

Muy bien, ya has guardado una columna de tipo TIMESTAMP en tu tabla del Firebird, pero ahora quieres leer el contenido de esa columna. ¿Cómo lo haces?

Aquí tienes dos posibilidades:

  1. Dejar el resultado en una variable de tipo timestamp
  2. Separar la columna timestamp para tener en una variable la fecha y en otra variable la hora

Si la que te interesa es la primera posibilidad nada tienes que hacer, la columna que has leído de tu tabla Firebird ya está en el formato adecuado y puedes usarla sin problemas.

Si lo que te interesa es separar el contenido de la columna de tipo TIMESTAMP para tener en una variable la fecha y en otra variable la hora esto es lo que debes escribir:

MiFecha = TTOD(MiColumna)
MiHora = TTOC(MiColumna, 2)

La función TTOD() significa “timestamp to date” y retorna la parte de la fecha de un TIMESTAMP

La función TTOC() significa “timestamp to character” y cuando su segundo argumento es el número 2 retorna la parte de la hora de un TIMESTAMP.

Conclusión:

Usar columnas y variables de tipo TIMESTAMP entre Visual FoxPro y Firebird es sencillo, ninguna complicación, solamente hay que recordar cuales son las funciones adecuadas para usar, eso es todo.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Parámetros de las transacciones usando Visual FoxPro

12 comentarios

Como ya seguramente sabes, todas las operaciones (INSERT, UPDATE, DELETE, SELECT, FETCH, EXECUTE PROCEDURE, etc.) que puedes realizar con las bases de datos de Firebird requieren ser realizadas dentro de transacciones, sí o sí, en el 100% de los casos.

Esas transacciones deben tener un comienzo y un fin.

Antes de comenzar una transacción puedes (si quieres) establecer cuales serán los parámetros que se usarán en esa transacción. Si tú no los estableces entonces el Cliente del Firebird lo hará por tí.

Parámetros por defecto de las transacciones

Si tú no indicas cuales serán los parámetros que utilizará la siguiente transacción entonces el Cliente del Firebird determina los siguientes:

  • READ WRITE
  • WAIT
  • SNAPSHOT

READ WRITE significa que la transacción podrá cambiar el contenido de las tablas. La alternativa es READ ONLY que significa que se puede leer el contenido de las tablas pero no cambiarlos.

WAIT significa que si encuentra un conflicto con otra transacción entonces esperará hasta que la otra transacción termine. La alternativa es NO WAIT lo cual significa que si encuentra un conflicto con otra transacción inmediatamente se elevará una excepción con un mensaje de error.

SNAPSHOT significa que si otra transacción realizó cambios a las tablas después que esta transacción haya empezado, esta transacción no se enterará de esos cambios. Las alternativas son READ COMMITTED que le permite a esta transacción enterarse de todos los cambios que otras transacciones hayan realizado y confirmado (se confirma con un COMMIT) y SNAPSHOT TABLE STABILITY que abre a todas las tablas que usa esta transacción en forma exclusiva, impidiendo por lo tanto a las otras transacciones realizar cambios a esas tablas.

Especificando los parámetros de la siguiente transacción

Una vez que una transacción empezó ya no puedes cambiar los parámetros de la misma. Eso implica que todos los parámetros debes establecerlos antes de que la transacción comience. Y recuerda que si tú no estableces los parámetros de una transacción entonces el Cliente del Firebird los establece por tí usando los valores por defecto (READ WRITE, WAIT, SNAPSHOT), como vimos más arriba.

Esto es importante recordar, porque puede prestarse a confusión: una transacción nunca hereda los parámetros de la transacción anterior. Los parámetros de una transacción los estableces tú específicamente con los valores que deseas o los establece el Cliente del Firebird, pero en ambos casos solamente se aplican a la siguiente transacción, a ninguna otra.

La clase SQL_CLASES

Si programas con el lenguaje Visual FoxPro entonces puedes descargar SQL_CLASES.PRG, allí encontrarás propiedades y métodos que te facilitarán grandemente el uso de Firebird.

http://www.mediafire.com/view/l36nar3o6ap19b9/SQL_CLASES.PRG

A continuación, la explicación sobre las propiedades y métodos relacionados con las transacciones.

Propiedades

cTransaccionAcceso           = "READ WRITE"     && la alternativa es   : READ ONLY
cTransaccionAislamiento      = "READ COMMITTED" && las alternativas son: SNAPSHOT, SNAPSHOT TABLE STABILITY
cTransaccionModoBloqueo      = "WAIT"           && la alternativa es   : NO WAIT
cTransaccionRecordVersion    = "RECORD_VERSION" && la alternativa es   : NO RECORD_VERSION
cTransaccionReservacion      = "SHARED"         && las alternativas son: PROTECTED, READ, WRITE
cTransaccionTablasReservadas = ""               && la alternativa es   : RESERVING MisTablas FOR PROTECTED WRITE
cTransaccionTipo             = ""               && las alternativas son: ABM, INFORME
nTipoTransaccion             = 2                && 1 = Transacción automática, 2 = Transacción manual.

Estas propiedades serán luego usadas por la función .Abrir_Transaccion(), la cual como su nombre lo indica se encarga de abrir las transacciones.

Métodos

.Abrir_Transaccion() abre una transacción utilizando los valores que tienen las propiedades. Es en esas propiedades donde determinamos como queremos que sea la transacción que se abrirá.

.Abrir_Transaccion_ABM() abre una transacción que será utilizada para realizar cambios a las tablas (INSERT, UPDATE, DELETE). Primero, les asigna valores a las propiedades y luego llama a la función .Abrir_Transacción(), que vimos en el párrafo anterior. Desde luego que podrías tener funciones .Abrir_Transaccion_ABM_2(), .Abrir_Transaccion_ABM_3(), etc. con valores distintos.

.Abrir_Transaccion_Informe() abre una transacción que será utilizada solamente con el comando SELECT. Primero, le asigna valores a las propiedades y luego llama a la función .Abrir_Transaccion(). Si tus necesidades aumentan podrías tener funciones .Abrir_Transaccion_Informe_2(), .Abrir_Transaccion_Informe_3(), etc.

En realidad, podríamos tener solamente la función .Abrir_Transaccion(), sin necesidad de las otras dos funciones. Pero están allí para facilitarnos la vida, así cuando queremos una transacción que cambiará el contenido de alguna tabla llamamos a la función  .Abrir_Transaccion_ABM() y cuando queremos una transacción que solamente realizará consultas llamamos a la función .Abrir_Transaccion_Informe(). Si no tuviéramos a esas dos funciones entonces antes de llamar a .Abrir_Transaccion() tendríamos que establecer los valores de las propiedades, lo cual nos haría escribir más y con el riesgo de equivocarnos alguna vez. Gracias a estas dos funciones escribimos menos y nos aseguramos que las propiedades siempre tengan los valores correctos.

.Ejecutar() se encarga de ejecutar el comando que le enviamos como parámetro. Pero antes de ello verifica que tengamos una transacción abierta con la función .Abrir_Transaccion_ABM() o con la función .Abrir_Transaccion_Informe(). ¿Por qué? Porque así nos aseguramos que la transacción cumpla con nuestros requisitos. Si queremos ejecutar un comando y no tenemos una transacción abierta por nosotros entonces el comando no será ejecutado. En otras palabras, no aceptamos transacciones abiertas automáticamente por el Cliente del Firebird, todas las transacciones debemos abrirlas nosotros usando o la función .Abrir_Transaccion_ABM() o la función .Abrir_Transaccion_Informe(). De esta manera nos aseguramos que la transacción siempre tenga los valores que deseamos que tenga. Si el comando que queremos ejecutar es un COMMIT o un ROLLBACK entonces sabemos que allí la transacción finaliza y se coloca en la propiedad .cTransaccionTipo el valor “”, de esa manera podemos saber que no hay una transacción abierta.

Funciones de Visual FoxPro

Para escribir menos y facilitarnos la vida, en lugar de llamar a las funciones de SQL_CLASES llamamos a otras funciones que realizan la misma tarea. A esta técnica se le llama “enmascarar” y podemos leerla en este artículo:

Enmascarando los stored procedures

Las funciones enmascaradoras que usamos son:

  • ABRIR_TRANSACCION_ABM()
  • ABRIR_TRANSACCION_INFORME()

Como ves, tienen los mismos nombres que los usados en SQL_CLASES pero en este caso se trata de funciones independientes, no son funciones dentro de una clase.

FUNCTION ABRIR_TRANSACCION_ABM
Local lcAlias, llResultadoOK

   lcAlias = Alias()

   llResultadoOK = _SCreen.goSQL.ABRIR_TRANSACCION_ABM()

   if !Empty(lcAlias)
      select (lcAlias)
   endif

Return(llResultadoOK)
*
*
FUNCTION ABRIR_TRANSACCION_INFORME
Local lcAlias, llResultadoOK

   lcAlias = Alias()

   llResultadoOK = _SCreen.goSQL.ABRIR_TRANSACCION_INFORME()

   if !Empty(lcAlias)
      select (lcAlias)
   endif

Return(llResultadoOK)
*
*
FUNCTION CERRAR_TRANSACCION
LParameters tcModo
Local lcAlias, llResultadoOK

   if !Empty(_Screen.goSQL.cTransaccionTipo) && Solamente cierra las transacciones abiertas
      lcAlias = Alias()
      tcModo = iif(VarType(tcModo) <> "C", "COMMIT", tcModo)
      llResultadoOK = iif((tcModo == "COMMIT" .or. tcModo == "ROLLBACK"), .T., .F.)
      if llResultadoOK
         llResultadoOK = SQL_Ejecutar(tcModo, "CUR_CERRAR")
      endif
      if !llResultadoOK .and. tcModo == "COMMIT" && Si no se pudo conseguir que la transacción finalice con un COMMIT, hay que finalizarla con un ROLLBACK
         =SQL_Ejecutar("ROLLBACK", "CUR_CERRAR")
         do MENSAJE_ERROR with "Falló el COMMIT, eso es un error grave.*Se finalizó la transacción con un ROLLBACK"
      endif
      _Screen.goSQL.cTransaccionTipo = ""
      if !Empty(lcAlias) .and. Used(lcAlias)
         select (lcAlias)
      endif
   else
      llResultadoOK = .T.
   endif

Return(llResultadoOK)
*
*

Lo que hacen las dos primeras funciones es, primero guardar el nombre de la tabla .DBF que tenemos abierta (si hay alguna tabla .DBF abierta, por supuesto), segundo llamar a la función de SQL_CLASES que nos interesa y tercero si había una tabla .DBF abierta volver a seleccionarla. Esas funciones nos devuelven un valor indicando si la transacción se pudo abrir exitosamente o no.

La función Cerrar_Transaccion() como su nombre lo indica se encarga de cerrar la transacción que tenemos abierta. Si no le indicamos si queremos cerrarla con un COMMIT o con un ROLLBACK entonces asume que queremos cerrarla con un COMMIT, ya que eso es lo más común. Para que sepamos que ya no hay una transacción abierta le asigna “” a la propiedad .cTransaccionTipo.

Ejemplos de uso de las transacciones

Ahora que ya hemos visto la clase y las funciones relacionadas con las transacciones veamos algunos ejemplos de como usarlas.

=Abrir_Transaccion_Informe()
llResultado = SQL_Ejecutar("SELECT * FROM PERSONALIZAR WHERE PER_USUARI = " + lcUsuario)
=Cerrar_Transaccion()

En este caso queremos realizar una consulta entonces se llamó a la función enmascaradora Abrir_Transaccion_Informe(), se realizó la consulta y se cerró la transacción.

TEXT TO lcComando NOSHOW
   EXECUTE PROCEDURE GRABAR_PERSONALIZACION (?lcUsuario, ?lcImagenFondo, ?lnColorTextoMensajesAyuda, ?lcArchivoSonido)
ENDTEXT

=Abrir_Transaccion_ABM()
llGrabacionOK = SQL_Ejecutar(lcComando)
=Cerrar_Transaccion()

En este caso llamamos a un stored procedure que cambiará el contenido de una tabla, por lo tanto llamamos a la función enmascaradora Abrir_Transaccion_ABM(), ejecutamos el comando y cerramos la transacción.

IMPORTANTE:

En Firebird es extremadamente importante tener a las transacciones abiertas durante el menor tiempo posible. Cuanto menos tiempo dure una transacción mucho mejor, porque eso ayudará a evitar conflictos con otras transacciones que quieran acceder a las mismas filas de las mismas tablas.

Como puedes ver en los ejemplos anteriores el procedimiento es abrir la transacción, ejecutar un comando, e inmediatamente cerrar la transacción. Eso es lo correcto.

Conclusión:

Los parámetros de las transacciones los puede establecer el Cliente del Firebird o los podemos establecer nosotros. Si los establecemos nosotros entonces tenemos un mucho mayor control sobre el actuar de esa transacción.

El lenguaje Visual FoxPro nos permite crear clases, esa es una muy buena característica del lenguaje y debemos aprovecharla. Aquí vemos un ejemplo del uso de las clases, en este caso para usarlas con Firebird.

Enmascarar las llamadas a rutinas o funciones nos facilita la vida porque escribimos menos y nos aseguramos de que todo esté siempre correcto. Las transacciones deben durar el menor tiempo posible, por eso lo correcto es abrirlas, ejecutar operaciones en ellas, y cerrarlas inmediatamente, tal como se ha visto en los ejemplos.

Artículos relacionados:

Entendiendo las transacciones

Enmascarando los stored procedures

El índice del blog Firebird21

El foro del blog Firebird21

Obteniendo los nombres de todos los usuarios

2 comentarios

Alguna vez podrías necesitar conocer los nombres de todos los usuarios que tiene admitidos el Firebird, estos son los usuarios que pueden conectarse a cualquier Base de Datos, siempre y cuando se les otorguen los derechos correspondientes, por supuesto.

No conozco algún SELECT que nos provea esa información. Los nombres de los usuarios se encuentran en el archivo SECURITY2.FDB y el acceso a ese archivo está restringido por razones obvias. Entonces, ¿cómo hacemos para obtener los nombres de todos los usuarios?

Aquí se muestra una solución.

Si creamos un archivo batch similar al siguiente tendremos en el archivo USUARIOS.TXT los nombres de todos los usuarios de bases de datos de Firebird.

USUARIOS

Captura 1. Si haces clic en la imagen la verás más grande

Como puedes ver, el archivo batch se llama USUARIOS.BAT y lo que hace es ejecutar al programa GSEC pidiéndole que muestre los nombres de los usuarios (la opción -display hace eso). No cualquier usuario puede listar los nombres de los demás usuarios, solamente SYSDBA puede hacerlo. La salida se redirige a un archivo llamado USUARIOS.TXT, o sea que en lugar de mostrar los nombres de los usuarios en la pantalla guarda esos nombres en el archivo USUARIOS.TXT

¿Por qué redirigimos la salida del programa GSEC al archivo USUARIOS.TXT?

Para más tarde poder procesar el archivo USUARIOS.TXT y extraer de él los nombres de los usuarios, pues eso es lo que estamos intentando conseguir. Queremos tener los nombres de los usuarios para mostrarlos en un ComboBox o en un Grid, etc.

El siguiente código en Visual FoxPro nos muestra como podemos obtener los nombres de todos los usuarios:

Local lcComando, llComandoOK, loShell, lnRetorno, lcUsuarios, lnMemoWidth, lnTotalLineas, lnI, lcLinea

   *--- Nombre del archivo donde se guardarán los nombres de los usuarios
   lcArchivo = "USUARIOS.TXT"

   *--- Contenido que tendrá el archivo batch USUARIOS.BAT
   lcComando = ["C:\ARCHIVOS DE PROGRAMA\FIREBIRD\FIREBIRD_2_5\BIN\GSEC" -user SYSDBA -password masterkey -display > ] + lcArchivo

   *--- Se crea el archivo batch USUARIOS.BAT
   =StrToFile(lcComando, "USUARIOS.BAT")

   *--- Se supone que el archivo batch se ejecutará exitosamente
   llComandoOK = .T.

   *--- Se crea un objeto shell para ejecutar el archivo batch
   loShell = CreateObject("WScript.Shell")

   *--- Se intenta ejecutar el archivo batch, la bandera llComandoOK nos dirá si se ejecutó exitosamente o no
   TRY
      lnRetorno = loShell.Run("USUARIOS.BAT", 0, .T.)
   CATCH
      llComandoOK = .F.
   ENDTRY

   if llComandoOK     && Si la ejecución del archivo batch tuvo éxito
      *--- En la variable lcUsuarios se guarda el contenido del archivo que tiene los nombres de los usuarios
      lcUsuarios = FileToStr(lcArchivo)
      *--- Se obtiene la cantidad de caracteres que se usan en los campos memo
      lnMemoWidth = Set("MEMOWIDTH")
      *--- Se cambia la cantidad de caracteres a 96
      SET MEMOWIDTH TO 96
      *--- Se obtiene la cantidad de líneas que tiene el archivo donde están los nombres de los usuarios
      lnTotalLineas = MemLines(lcUsuarios)
      *--- Se guarda en la variable lcLinea el nombre de cada usuario
      For lnI = 3 to lnTotalLineas
         lcLinea = AllTrim(Left(MLine(lcUsuarios, lnI), 28))
         if !Empty(lcLinea)
            =MessageBox(lcLinea)     && Se muestra en la pantalla el nombre del usuario
         endif
      EndFor
      *--- Se pone la cantidad de caracteres original en los campos memo
      SET MEMOWIDTH to lnMemoWidth
   else     && Si ocurrió algún problema al ejecutar el archivo batch
      =MessageBox("No pude obtener los nombres de los usuarios")
   endif

   *--- Se borra el archivo USUARIOS.BAT porque ya no es necesario
   DELETE FILE USUARIOS.BAT

   *--- Se libera el objeto loShell

   loShell = NULL

   Release loShell

Return
*
*

Dentro del código fuente hay muchos comentarios, los cuales te ayudarán a entender que es lo que hace. Si tienes bastante experiencia con Visual FoxPro te resultará muy fácil entenderlo, aún sin los comentarios.

Conclusión:

Aunque no existe (que yo sepa, claro) un SELECT que nos devuelva los nombres de los usuarios escribir un programita que nos de esa información es muy fácil como se puede ver en este artículo.

Artículos relacionados:

Agregando, modificando y borrando usuarios

El índice del blog Firebird21

Conectándose con ADO a las bases de datos

6 comentarios

Como seguramente sabes, para conectarte a una Base de Datos de Firebird puedes utilizar varios métodos, uno de ellos es ADO (ActiveX Data Objects). Fue desarrollado por Microsoft y por lo tanto se usa principalmente con Windows.

Con ADO se pueden crear tablas, borrar tablas, insertar filas, modificar filas, borrar filas, consultar filas, etc., todas las operaciones normales.

El método más usado para conectarse a bases de datos de Firebird creo que es ODBC pero he leído que ADO es más rápido. No lo puedo afirmar ni negar porque aún no he realizado pruebas intensivas ni he encontrado alguna página donde las hayan hecho y muestren los resultados.

Lo primero que debes hacer si quieres conectarte por ADO es conseguir un proveedor, aquí encontrarás uno de ellos:

http://www.ibprovider.com/eng/documentation/firebird_interbase_odbc_drivers.html

ADO1

Captura 1. Si haces clic en la imagen la verás más grande

Después de descargarlo e instalarlo ya estará listo para ser usado.

Gracias a la colaboración de Jaume (ver los comentarios más abajo) también disponemos del IBOLE.DLL el cual dicen que es muy bueno. Puedes descargarlo desde:

http://www.mediafire.com/download/7hpf8ppyudpnn4k/IBOLE.dll

¿Cómo se utiliza ADO?

Primero, debes conectarte a la Base de Datos

Segundo, debes obtener un RecordSet, o sea un conjunto resultado con los datos que te interesan

Tercero, puedes manipular esos datos como desees

Cuarto, debes cerrar el RecordSet

Quinto, debes cerrar la conexión

Ejemplo. Mostrar los nombres de los clientes

En nuestra Base de Datos tenemos una tabla llamada CLIENTES y queremos obtener los nombres de los mismos, este pequeño programita desarrollado con Visual FoxPro cumplirá esa  tarea:

CLEAR

CLOSE ALL

CLEAR ALL

Private oSQL, oRecordSet

*--- Primero, se conecta a la Base de Datos

oSQL = CreateObject("ADODB.Connection")

with oSQL
   .Provider = "LCPI.IBProvider.3.Lite"
   .ConnectionString = "User=SYSDBA;password=masterkey;Data Source=E:\SQL\DATABASES\BLOG_DB.FDB;auto_commit=true"
   .Open()
endwith

*--- Segundo, se crea un RecordSet

oRecordSet = CreateObject("ADODB.RecordSet")

*--- Tercero, se obtienen los datos que nos interesan

oRecordSet.Open("Select * From CLIENTES",oSQL)

*--- Cuarto, se procesan los datos obtenidos

do while !oRecordSet.EOF
   ? oRecordSet.Fields.Item("CLI_NOMBRE").Value
   oRecordSet.MoveNext()
enddo

*--- Quinto, se cierran y se eliminan los objetos que se habían creado

oRecordSet.Close()

oSQL.Close()

Release oRecordSet, oSQL

Después de ejecutarlo el resultado obtenido será algo similar a esto:

ADO2

Captura 2. Si haces clic en la imagen la verás más grande

Como puedes ver, en la pantalla se mostraron los nombres de los 4 clientes cuyos datos estaban guardados en la tabla respectiva.

A diferencia de ODBC aquí no obtendrás un cursor para trabajar con él. Un cursor es una tabla .DBF temporal y desde mi punto de vista es más útil porque puede ser indexada, mostrada en un browse, etc. La forma de usar ADO me parece más antigua, más manual, aunque sobre gustos…

Desde luego que siempre puedes enviar el contenido de los recordsets a cursores o a tablas .DBF pero sería un trabajo adicional y ¿vale la pena? eso ya no lo sé porque dependerá de tus circunstancias.

Propiedades, métodos y eventos de ADO

ADO tiene muchísimas propiedades, métodos y eventos que puedes usar, en el ejemplo anterior se mostró solamente una pequeñísima parte de ellos. Si te interesa el tema hay varias páginas con información útil en Internet, una de ellas es la siguiente:

http://www.w3schools.com/ado/default.asp

Conclusión:

Si quieres, puedes usar ADO para conectarte a una Base de Datos pero yo hasta ahora no le he encontrado alguna ventaja. Quizás sea más rápido que ODBC y en ese caso sí podría justificarse conectarse mediante ADO, pero eso es algo que aún no he verificado.

Usar cursores es más rápido y más sencillo (para mí, claro) que estar obteniendo los datos fila por fila. Esto lo notarás principalmente cuando quieras imprimir informes porque mientras un cursor o una tabla .DBF ya están preparados para ser usados en informes, los recordsets no lo están y deberán prepararse previamente y habría que ver si vale la pena el esfuerzo.

De todas maneras, siempre es bueno tener varias alternativas para hacer cualquier cosa y disponer de ADO aumenta nuestras posibilidades de conexión a las bases de datos, así que bienvenido.

Descargas de archivos .DLL para usarlos como Proveedor de ADO

http://www.ibprovider.com/eng/documentation/firebird_interbase_odbc_drivers.html

http://www.mediafire.com/download/7hpf8ppyudpnn4k/IBOLE.dll

Artículos relacionados:

w3schools.com

El índice del blog Firebird21

Un formulario para mostrar la transacción actual

Deja un comentario

Como conocer los datos de la transacción actual puede ser muy útil cuando estamos en la etapa de crear y depurar aplicaciones hice un pequeño formulario para que muestre esos datos.

Esta es una captura de pantalla del formulario cuando está en ejecución.

FORMULARIO1

Captura 1. Si haces clic en la imagen la verás más grande

Como puedes ver en la Captura 1, toda la información relevante se encuentra ahí. Además, colocando el cursor del mouse sobre cualquiera de los campos se muestra un corto mensaje explicativo, digamos que es un “ayuda memoria”.

Puedes descargar el formulario desde este enlace:

http://www.mediafire.com/download/566t3p6eryburfv/MOSTRAR_TRANSACCION.ZIP

NOTA: Debes reemplazar la llamada a la función SQL_Ejecutar() por una llamada a la función SQLEXEC() porque SQL_Ejecutar() es una función mía que aumenta la potencia de SQLEXEC()

Artículos relacionados:

Una vista para verificar la transacción actual

El índice del blog Firebird21

Older Entries