buscarvariasbds.pdf

7
BUSCAR EN VARIAS BD'S 1 Bueno... Puede ser que, por temas de operativa, por temas de tamaño o simplemente porque a nosotros, como administradores, nos va bien así, tengamos la información relativa a un año en una BD. Finaliza ese año y empezamos una BD nueva para el nuevo año. En definitiva, que guardamos la información diferentes BD's en función del año. De todas maneras tened en cuenta que lo anterior es lo que se me ocurre en un supuesto al que le veo cierta lógica, pero el ejemplo funcionaría igual si tenemos varias BD's, independientemente de si la información se ajusta al supuesto que yo he planteado líneas más arriba. Lo que sí debemos tener claro son los siguientes puntos: La ruta (y nombre) de cada una de las BD's en las que vamos a realizar la búsqueda. El nombre de la tabla que contiene la información donde queremos buscar. El nombre del campo que contiene los datos donde queremos buscar. ¿Cuál será la mecánica que vamos a seguir? A nivel de usuario se va a solicitar un valor a través de un InputBox al pulsar un botón, y se van a mostrar los resultados en una tabla. A nivel de funcionamiento interno vamos a valernos de una tabla de información operada sólo por el administrador, donde vamos a informar de la ruta y nombre de las BD's antiguas, y de una tabla auxiliar cuya información se irá reconstruyendo cada vez que el usuario pulse el botón. ¿Dónde debemos llevar cuidado? Para que la BD de ejemplo funcione en vuestros ordenadores, si os la bajáis, yo he cambiado ligeramente la mecánica de funcionamiento a la hora de desarrollar este ejemplo. Es decir, que yo he utilizado una carpeta llamada <<BDsAntiguas>>, que se halla situado en el mismo directorio donde tenemos la BD principal. Y eso me obliga a no poder definir, en la tabla que os comentaba de las rutas, rutas absolutas, sino que he tenido que definir rutas relativas. De todas maneras os daré, a la hora de desarrollar el código y a lo largo del ejemplo, las indicaciones oportunas para poder adaptar esto a vuestra situación. De esta manera podréis ver cómo hacerlo si utilizamos rutas absolutas y rutas relativas. Y dicho esto, que quizá ahora pueda sonaros un poco “lioso”, no os preocupéis porque lo iremos entendiendo (espero) a medida que vayamos desarrollando este ejemplo. PREPARANDO LA ESTRUCTURA INICIAL Como necesito una “materia prima” antes de poder realizar el ejemplo os indico lo que he hecho para “preparar el terreno”. 1 La BD de ejemplo os la podéis bajar aquí 1 Visítame en http://neckkito.siliconproject.com.ar

Upload: lsalinas11790

Post on 28-Aug-2015

219 views

Category:

Documents


1 download

TRANSCRIPT

  • BUSCAR EN VARIAS BD'S1

    Bueno... Puede ser que, por temas de operativa, por temas de tamao o simplemente porque a nosotros, como administradores, nos va bien as, tengamos la informacin relativa a un ao en una BD. Finaliza ese ao y empezamos una BD nueva para el nuevo ao.

    En definitiva, que guardamos la informacin diferentes BD's en funcin del ao.

    De todas maneras tened en cuenta que lo anterior es lo que se me ocurre en un supuesto al que le veo cierta lgica, pero el ejemplo funcionara igual si tenemos varias BD's, independientemente de si la informacin se ajusta al supuesto que yo he planteado lneas ms arriba.

    Lo que s debemos tener claro son los siguientes puntos:

    La ruta (y nombre) de cada una de las BD's en las que vamos a realizar la bsqueda. El nombre de la tabla que contiene la informacin donde queremos buscar. El nombre del campo que contiene los datos donde queremos buscar.

    Cul ser la mecnica que vamos a seguir?

    A nivel de usuario se va a solicitar un valor a travs de un InputBox al pulsar un botn, y se van a mostrar los resultados en una tabla.

    A nivel de funcionamiento interno vamos a valernos de una tabla de informacin operada slo por el administrador, donde vamos a informar de la ruta y nombre de las BD's antiguas, y de una tabla auxiliar cuya informacin se ir reconstruyendo cada vez que el usuario pulse el botn.

    Dnde debemos llevar cuidado?

    Para que la BD de ejemplo funcione en vuestros ordenadores, si os la bajis, yo he cambiado ligeramente la mecnica de funcionamiento a la hora de desarrollar este ejemplo. Es decir, que yo he utilizado una carpeta llamada , que se halla situado en el mismo directorio donde tenemos la BD principal. Y eso me obliga a no poder definir, en la tabla que os comentaba de las rutas, rutas absolutas, sino que he tenido que definir rutas relativas.

    De todas maneras os dar, a la hora de desarrollar el cdigo y a lo largo del ejemplo, las indicaciones oportunas para poder adaptar esto a vuestra situacin. De esta manera podris ver cmo hacerlo si utilizamos rutas absolutas y rutas relativas.

    Y dicho esto, que quiz ahora pueda sonaros un poco lioso, no os preocupis porque lo iremos entendiendo (espero) a medida que vayamos desarrollando este ejemplo.

    PREPARANDO LA ESTRUCTURA INICIALComo necesito una materia prima antes de poder realizar el ejemplo os indico lo que he hecho para preparar el terreno.

    1 La BD de ejemplo os la podis bajar aqu

    1Vistame en http://neckkito.siliconproject.com.ar

  • Tened en cuenta que, a efectos de simplificar el ejemplo, la informacin que va a aparecer en las BD's de ejemplo puede ser que no tenga demasiado sentido en un supuesto real. Sin embargo, no perdis de vista que lo que interesa es la mecnica de cmo se hace la bsqueda, y no tanto la informacin que pueda haber en el ejemplo.

    Creamos una BD (que yo he llamado ) y, en ella, creamos una tabla, a la que llamaremos TDatos, que va a servirnos como una simple tabla donde tenemos los datos en los cuales queremos buscar la informacin. He construido TDatos con la siguiente estructura:

    En el mismo directorio donde tenemos la BD creamos una nueva carpeta, a la que llamaremos BDsAntiguas (esto no sera necesario si vamos a utilizar rutas absolutas).

    Copiamos nuestra BD y la pegamos dos veces dentro de . A la primera copia la llamamos Ejercicio2011.mdb y a la segunda Ejercicio2012.mdb2

    A continuacin he rellenado la tabla TDatos de cada una de las BD's con algunos registros inventados. Para que os hagis una idea os muestro algunos de estos registros:

    Y ahora s... vamos al meollo del asunto...

    CREANDO NUESTRA TABLA DE RUTASVamos a crearnos una tabla en la BD principal, a la que llamaremos TRutas. Dicha tabla tendr la siguiente estructura:

    2 Como estoy desarrollando el ejemplo sobre Access 2003 yo utilizo la extensin mdb. Lgicamente, si vosotros trabajis con Access 2007 2010, la extensin que deberis utilizar es accdb.

    2Vistame en http://neckkito.siliconproject.com.ar

  • Cmo vamos a rellenar la tabla? Pues eso va a depender de si estamos utilizando rutas absolutas o rutas relativas.

    Si utilizamos rutas absolutas debemos indicar la ruta completa donde tenemos las BD's. Supongamos que las tenemos en una carpeta llamada , que est en la carpeta , que a su vez est en la unidad C. Luego deberamos rellenar la tabla con los siguientes datos:

    Si utilizamos rutas relativas (os recuerdo que, en este sentido, estoy queriendo decir que las BD's se hallan dentro de una carpeta que est en el mismo directorio donde tenemos la BD principal), y aplicado a este ejemplo, deberamos rellenarla simplemente con el nombre de la carpeta. Es decir:

    Tambin os recuerdo que yo estoy utilizando Access 2003, y de ah que utilice la extensin mdb. Si usamos una versin posterior de Access deberamos indicar la extensin correcta, esto es, accdb

    CREANDO NUESTRA TABLA DE RESULTADOSA continuacin vamos a crear una nueva tabla, que llamaremos TResultados, que tendr la siguiente estructura:

    CREANDO NUESTRO BOTN DE BSQUEDAEn el formulario que queramos (un formulario tipo Men, un formulario de consultas...) aadimos un botn de comando. Vamos a ponerle de nombre cmdBuscaTablas3. En el evento Al hacer click generamos el siguiente cdigo4:

    3 Para asignar un nombre a un control lo que debemos hacer es sacar las propiedades de ese control e irnos a la Pestaa Otras Nombre. Ah escribimos el nombre que queramos.

    4 Para generar cdigo debemos sacar las propiedades del control Pestaa Eventos, y nos situamos en la parte blanca a la derecha del evento que queremos programar. Veremos un pequeo botn de puntos suspensivos. Si hacemos click sobre l nos aparecer una ventana que nos pedir qu operacin deseamos realizar. Le indicamos que queremos generar cdigo.

    3Vistame en http://neckkito.siliconproject.com.ar

  • Private Sub cmdBuscaTablas_Click() 'Declaramos las variables Dim vBuscado As Variant 'Solicitamos la informacin al usuario vBuscado = InputBox("Introduzca el valor a buscar", "BSQUEDA") 'Detectamos la pulsacin del botn CANCELAR If StrPtr(vBuscado) = 0 Then Exit Sub 'Llamamos al procedimiento realizoBusqueda Call realizoBusqueda(vBuscado)End Sub

    Como podemos ver el botn lo nico que hace es reclamar la informacin al usuario para, a continuacin, realizar una llamada a un procedimiento que explicaremos a continuacin.

    CREANDO NUESTRO MDULO Y CDIGOLa creacin del mdulo es un proceso simple. El cdigo que explicar aqu se refiere a referencias relativas. Es decir, que si utilizamos referencias absolutas deberemos utilizar el mismo cdigo pero en el epgrafe siguiente os explicar qu lneas debemos modificar para adaptarlo a dicho tipo de referencias.

    Para crear ese nuevo mdulo nos vamos al editor de VB (si no lo tenemos visible pulsamos la combinacin de teclas ALT+F11 y se nos abrir el VBE) y nos vamos a Men Insertar Mdulo.

    Una vez creado ese mdulo lo guardamos con el nombre mdlBuscaTablas

    Para los sufridos usuarios de Access 2003 vamos a necesitar registrar una referencia (si no la tenemos registrada ya), que es la referencia Microsoft DAO 3.6 Object Library5

    En ese mdulo vamos a escribir nuestro procedimiento realizoBusqueda(). Si sabemos algo de VB veremos que hay elementos que se pueden simplificar. Sin embargo, a efectos pedaggicos, he preferido realizar una versin extensa para que entendemos mejor el funcionamiento.

    Su cdigo es el siguiente (est comentado para que sepis que hace prcticamente cada una de las lneas):

    Public Sub realizoBusqueda(vBusc)'Neckkito --- 19/01/13'Requiere registro de la referencia "Microsoft DAO 3.6 Object Library" o'mdulo equivalente 'Inserto un control de errores por si no se encontrara la ruta o la BDOn Error GoTo sol_err 'Declaro las variables Dim dbsRuta As DAO.Database Dim dbs As DAO.Database Dim rstTDatos As DAO.Recordset Dim rstTRuta As DAO.Recordset Dim rstTResultados As DAO.Recordset Dim rst As DAO.Recordset Dim rutaCompleta As String Dim vCampo As String 'Eliminamos los registros que pudiera contener TResultados DoCmd.SetWarnings False 'Desactivamos los warnings

    5 Para registrar una referencia debemos irnos, en el editor de VB, a Men Herramientas Referencias... Se nos abrir una ventana mostrndonos todas las referencias disponibles. Buscamos la que nos interese, marcamos su check y aceptamos.

    4Vistame en http://neckkito.siliconproject.com.ar

  • DoCmd.RunSQL ("DELETE FROM TResultados") DoCmd.SetWarnings True 'Reactivamos los warnings

    'Definimos dbs Set dbs = CurrentDb 'Abrimos el recorset sobre nuestra tabla TRutas Set rstTRuta = dbs.OpenRecordset("TRutas", dbOpenSnapshot) 'Abrimos el recordset sobre nuestra tabla TResultados Set rstTResultados = dbs.OpenRecordset("TResultados", dbOpenTable) 'Nos movemos al primer registro de TRutas rstTRuta.MoveFirst 'Empezamos el anlisis de la rutas de TRutas Do Until rstTRuta.EOF 'Construimos la ruta entera de la BD donde debemos buscar rutaCompleta = Application.CurrentProject.Path & "\" _ & rstTRuta.Fields("Ruta").Value & "\" & rstTRuta.Fields("Archivo").Value

    Set dbsRuta = DBEngine.OpenDatabase(rutaCompleta) 'Abrimos un recorset sobre la tabla TDatos de la BD analizada Set rstTDatos = dbsRuta.OpenRecordset("TDatos", dbOpenSnapshot) 'Nos situamos en el primer registro rstTDatos.MoveFirst 'Iniciamos el recorrido de registros Do Until rstTDatos.EOF 'Analizamos la coincidencia con el valor buscado vCampo = rstTDatos.Fields("Estados").Value If InStr(1, vCampo, vBusc) 0 Then 'Si hay coincidencia... 'Escribimos la coincidencia en TResultados rstTResultados.AddNew rstTResultados.Fields("Nombre").Value = rstTDatos.Fields("Nombre").Value rstTResultados.Fields("Estado").Value = rstTDatos.Fields("Estados").Value rstTResultados.Fields("EnBD").Value = rstTRuta.Fields("Archivo").Value rstTResultados.Update End If 'Nos movemos al siguiente registro rstTDatos.MoveNext Loop 'Nos movemos a la siguiente BD a analizar rstTRuta.MoveNext Loop 'Buscamos en la BD actual Set rst = dbs.OpenRecordset("TDatos", dbOpenSnapshot) 'Nos movemos al primer registro rst.MoveFirst 'Iniciamos el recorrido de registros Do Until rst.EOF 'Analizamos la coincidencia con el valor buscado vCampo = rst.Fields("Estados").Value If InStr(1, vCampo, vBusc) 0 Then 'Escribimos la coincidencia en TResultados rstTResultados.AddNew rstTResultados.Fields("Nombre").Value = rst.Fields("Nombre").Value rstTResultados.Fields("Estado").Value = rst.Fields("Estados").Value rstTResultados.Fields("EnBD").Value = "Actual" rstTResultados.Update End If 'Nos movemos al siguiente registro rst.MoveNext Loop 'Abrimos la tabla de resultados en modo slo lectura DoCmd.OpenTable "TResultados", , acReadOnly 'Cerramos conexiones y liberamos memoria rst.Close rstTDatos.Close rstTRuta.Close rstTResultados.Close dbs.Close dbsRuta.Close Set rst = Nothing Set rstTDatos = Nothing Set rstTRuta = Nothing Set rstTResultados = Nothing Set dbs = Nothing

    5Vistame en http://neckkito.siliconproject.com.ar

  • Set dbsRuta = NothingSalida: Exit Sub

    sol_err: If Err.Number = 3044 Then 'No encontramos la ruta MsgBox "No se encuentra la ruta a la base de datos", vbCritical, "ERROR" Resume Salida End If If Err.Number = 3024 Then 'No encontramos la BD MsgBox "No se encuentra la base de datos", vbCritical, "ERROR" Else MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description, vbCritical, "ERROR" End If

    End Sub

    SI LAS REFERENCIAS SON ABSOLUTAS...Si nuestras referencias son absolutas debemos realizar lo siguiente:

    1.- Nos situamos en la lnea de cdigo que definen la variable rutaCompleta, que son:

    'Construimos la ruta entera de la BD donde debemos buscar rutaCompleta = Application.CurrentProject.Path & "\" _ & rstTRuta.Fields("Ruta").Value & "\" & rstTRuta.Fields("Archivo").Value

    2.- Las cambiamos por las siguientes:

    'Construimos la ruta entera de la BD donde debemos buscar rutaCompleta = rstTRuta.Fields("Ruta").Value & "\" & rstTRuta.Fields("Archivo").Value

    UNOS COMENTARIOS SOBRE EL CDIGO La estructura del cdigo en cuanto a bsqueda y escritura de resultados, en abstracto, es la siguiente:

    Localizo la ruta y la BD a examinar (a travs del recordset rstTRuta)

    Abro la tabla TDatos de esta primera BD que examino y recorro los registros (a travs de rstTDatos)

    Si encuentro alguna coincidencia la escribo en TResultados (a travs de rstTResultados)

    Cuando he acabado con esa BD me muevo a la siguiente BD a analizar (a travs de rstTRuta.movenext / Loop)

    Repito el proceso con TDatos, pero de la nueva BD a analizar

    Cuando acabo con los registros de TRutas me centro en la BD actual, realizando el mismo proceso de lectura (de TDatos) y de escritura (de TResultados).

    La bsqueda del valor la he hecho utilizando la funcin InStr(), que, para entendernos,

    6Vistame en http://neckkito.siliconproject.com.ar

  • funciona en este caso similar a un LIKE. Sabemos (y si no lo sabamos lo sabremos ahora) que si InStr() devuelve el valor 0 (cero). Por eso yo utilizo el IF diciendo que si devuelve un valor distinto de cero (0) es porque se ha producido alguna coincidencia, y por tanto s debo escribir ese valor como resultado.

    Si bien el cdigo lleva un control de errores para gestionar los dos principales errores que, desde mi punto de vista, podran producirse, que son que no exista la ruta a las BD's o que directamente no existan las BD's, lo que no lleva es un control de errores para registros. Qu significa esto? Pues simplemente que si un registro no tuviera valor en el campo [Estados] obtendramos un error de cdigo.

    Cmo solucionamos eso? Pues quiz la manera ms sencilla es obligar a que haya un valor, aunque no lo haya. Y eso se consigue con la funcin NZ().

    Es decir, que si me salta un error en la lnea:

    rst.Fields(Estados).Value

    porque en ese registro no hay ningn valor, podra sustituir esa expresin por

    Nz(rst.Fields(Estados).Value, )

    De manera que si no hay valor devolvera una cadena vaca (representada por las dos comillas dobles del segundo argumento de Nz().

    PARA FINALIZAR EL EJEMPLO...Dado que este ejemplo no es precisamente de los ms sencillos es por ello por lo que lo he ubicado en la seccin Ejemplos Especiales de la Web.

    Creo que si lo analizamos con calma y sin prisas veremos como le podemos coger el tranquillo y entenderlo para aplicarlo a nuestra propia aplicacin (eso espero!).

    Como curiosidad os dir que, si queremos, en vez de abrir la tabla podramos crearnos un formulario basado en TResultados, mejor en vista de formularios continuos, para ver la informacin en un formulario. En este caso deberamos cambiar la lnea de cdigo

    'Abrimos la tabla de resultados en modo slo lectura DoCmd.OpenTable "TResultados", , acReadOnly

    Por

    'Abrimos el formulario de resultados en modo slo lectura DoCmd.OpenForm "NombreFormulario", , , , acFormReadOnly

    De una manera u otra deseo que os sea de utilidad.

    Un saludo, y...

    suerte!

    7Vistame en http://neckkito.siliconproject.com.ar

    PREPARANDO LA ESTRUCTURA INICIALCREANDO NUESTRA TABLA DE RUTASCREANDO NUESTRA TABLA DE RESULTADOSCREANDO NUESTRO BOTN DE BSQUEDACREANDO NUESTRO MDULO Y CDIGOSI LAS REFERENCIAS SON ABSOLUTAS...UNOS COMENTARIOS SOBRE EL CDIGOPARA FINALIZAR EL EJEMPLO...