Update columna a mayúscula cada palabra

Desarrollo de Macros y programación en UNO, usar las API, llamar programas externos...
Responder
Longi
Mensajes: 804
Registrado: Dom Ene 20, 2013 9:05 pm
Ubicación: Ourense, Galicia, España

Update columna a mayúscula cada palabra

Mensaje por Longi »

Buenas!
Esto no es una pregunta, sino que es para compartir una solución:
Supongo que a la gente que maneja Base se le ha cruzado en alguna ocasión la columna "Apellidos" (más de una palabra) y que alguien escribió de diferentes maneras al haber varias personas que la cubrieron en tiempos (mayúsculas, minúsculas, etc). Así mismo, la tabla, al ser vieja, también es amplia, y se le quiere dar un 'refresco' para poder mandar e-mails o similar.
Opciones hay varias, pero yo opté por lo siguiente:
Establecí una macro que separa cada palabra y después pone la primera letra con mayúscula y las siguientes con minúscula, haciendo un update para cada uno de los casos.
Esta funcionalidad encontró dos problemas: la existencia de comillas simples ( que no sé porqué estaban ahí), y la existencia de dos o más espacios en blanco (esto era problemático ya que el corte entre palabras se hace teniendo en cuenta la localización de espacios únicos en blanco)
Esto me obligó a generar dos funciones que arreglasen esos problemas y después ya hacer el update del total de la columna.
En el inicio de la macro hay tres parámetros que nos permiten poner el nombre de la tabla, el campo que queremos manipular y luego un campo que yo lo usé con el campo ID (en mi caso el DNI de cada persona), que usaremos para que el UPDATE final no se equivoque de línea.
El procedimiento es lento, y seguramente era mejor haber sacado todo a un calc y usando fórmulas hacer los cambios y después volver a cargar la tabla, pero no lo hice así, pero como creo que me ha salido bien (aunque seguro que el código es fráncamente mejorable) he decidido colgarlo aquí para compartirlo.

Código: Seleccionar todo

Sub Mayusculas()

    Campo= "Apellidos"                                                               ' Campo en el que vamos a hacer los cambios
    Clave= "NIF persona"                                                            ' Campo clave en la tabla a modificar
    TablaParaArreglar="MITABLA"                                                   ' Tabla en la que vamos a hacer los cambios
    '================================================================
    ' Llamamos a las funciones para eliminar elementos parásitos (Comisllas simples y dobles espacios)
    
    ComillaSimple(Campo,TablaParaArreglar, Clave)                                    ' Llamamos a la función de comillas simples
    DoblesEspacios(Campo,TablaParaArreglar, Clave)                                   ' Llamamos a la función de dobles espacios
    '===============================================================    
    ' Una vez que hemos limpiado de parásitos, empezamos con el ciclo
    
    Dim A$                                                                           ' Definimos la matriz
    A$=""                                                                            ' Vaciamos la matriz
    '----------------------------------------------------
    ' Determinamos un Result Set sobre el que trabajar, escogiendo los registros no vacíos
       
    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    oSQLQuery = "SELECT "& Campo &","""& Clave &""" FROM "& TablaParaArreglar &" WHERE "& Campo &" IS NOT NULL" ' Consulta
    oStat.setPropertyValue("ResultSetType",1005)                                     ' Características de la consulta
    oResultSet = oStat.executeQuery(oSQLQuery)                                       ' Se ejecuta la consulta
    oResultSet.last                                                                  ' Va al último registro para contar los registros que tiene
    oResultSet.first                                                                 ' Mueve el cursor al primer registro
    oResultSet.previous 
    '-----------------------------------------------------------------------
    ' Establecemos un array que recoge todos los datos de la consulta
   
    j = 0                                                                            ' Constante
    Dim ArrayDocumento()                                                             ' Definición del array  
    While oResultSet.next                                                            ' Recorremos todos los datos del Resultset
    Redim Preserve ArrayDocumento(j)                                                 ' Redimensionamos el array
    ArrayDocumento(j) = oResultset.getString(1)                                      ' Primer resultado del array
    j = j+1                                                                          ' Pasa al siguiente resultado del array
    '----------------------------------------------------------------------------
    ' Manejamos los datos del ResultSet
    
    Campo1=RTRIM(LTRIM(oResultSet.getString(1)))                                     ' Campo que queremos manipular
    Campo2= oResultSet.getString(2)                                                  ' Campo para filtrado en el update
    '------------------------------------------------------------------
    ' Aplicamos el código para dejar la primera letra de cada palabra con mayúscula, el resto con minúscula
    
    Dim mCadenas()
    sSepara = Left(" ", 1 )                                                          ' Array de separación
    mCadenas = Split( Campo1, sSepara )                                              ' Rompemos el campo en tantas palabras como tenga separadas por un espacio                                            
    for i= LBound(mCadenas()) to UBound (mCadenas())                                 ' Ciclo que recorre cada palabra                             
    if not (mCadenas(i)="S.L." or mCadenas(i)="S.A." or mCadenas(i)="S.A.T."  or mCadenas(i)=" " or mCadenas(i)="S.C." or mCadenas(i)="XXIII" or mCadenas(i)="S/N" or mCadenas(i)="  ") Then
    A$= A$ & Ucase (Left (mCadenas(i),1))& LCase(Right(mCadenas(i),Len(mCadenas(i))-1) & " " ' Array ya resuelto
    End if                                                                           ' Acabamos las excepciones
    Next                                                                             ' Vamos a la siguiente palabra
    '----------------------------------------------------------------
    ' Generamos la consulta de actualización

    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                    ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                      ' Creación de la conexión
    sSQL = "UPDATE "& TablaParaArreglar &" SET """ & Campo & """ = '"& A$ &"'  WHERE """& Clave &"""= '"& Campo2 &"'" 
    oStat.ExecuteUpdate(sSQL)                                                         ' Se ejecuta la consulta
    '--------------------------------------------------------------
    ' Vaciamos el array para que el siguiente registro vuelva a empezar desde cero
   
    A$=""                                                                            ' Vaciamos el array
    Wend                                                                             ' Acabamos el ciclo del ResultSet
    
End Sub  

Function DoblesEspacios(Campo,TablaParaArreglar,Clave)
    
    '---------------------------------------------------------------------
    ' Haremos un ciclo que recorrerá todos los registros con algún doble espacio, sustituyéndolo por espacio simple
    ' lo cual nos dejará en ocasiones aún dobles espacios (espacio simple + espacio simple, por lo que habrá que repetir ciclo hasta el arreglo total.
    
    do                                                                               ' Generamos el ciclo
    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    oSQLQuery="SELECT REPLACE( "& Campo &", '  ', ' ' ) ""Arreglo"", LOCATE( '  ', "& Campo &" ), """& Clave &""" FROM "& TablaParaArreglar &" "& TablaParaArreglar &" WHERE LOCATE( '  ', "& Campo &" ) <> '0'"       
    oStat.setPropertyValue("ResultSetType",1005)                                     ' Características de la consulta
    oResultSet = oStat.executeQuery(oSQLQuery)                                       ' Se ejecuta la consulta
    Valor=oResultSet.next                                                            ' Vamos al siguiente elemento del ResultSet
    oResultSet.last                                                                  ' Va al último registro para contar los registros que tiene
    oResultSet.first                                                                 ' Mueve el cursor al primer registro
    oResultSet.previous 
    '-----------------------------------------------------------------------
    ' Establecemos un array que recoge todos los datos de la consulta

    j = 0                                                                            ' Constante
    Dim ArrayDocumento1()                                                            ' Definición del array  
    While oResultSet.next                                                            ' Recorremos todos los datos del Resultset
    Redim Preserve ArrayDocumento1(j)                                                ' Redimensionamos el array
    ArrayDocumento1(j) = oResultset.getString(1)                                     ' Primer resultado del array
    j = j+1                                                                          ' Pasa al siguiente resultado del array
    '----------------------------------------------------------------------------
    ' Manejamos los datos del ResultSet
    
    Arreglo= RTRIM(LTRIM(oResultSet.getString(1)))                                   ' Cómo queremos dejar el campo después del arreglo
    Campo2=oResultSet.getString(3)                                                   ' Campo que queremos manipular
    '---------------------------------------------------------------------------
    ' Insertamos el arreglo (la desaparición de dobles espacios) en el campo de la tabla que estamos manipulando
    
    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    sSQL = "UPDATE "& TablaParaArreglar &" SET """& Campo &"""= '" & Arreglo &"' WHERE """& Clave &"""= '"& Campo2 &"'"
    oStat.ExecuteUpdate(sSQL)                                                        ' Se ejecuta la consulta
    Wend                                                                             ' Vamos al siguiente elemento del ResultSet
    '----------------------------------------------------------------------
    ' Una vez revisado todo el ResultSet, si teníamos algún elemento que quedó todavía con algún doble espacio, lo volvemos a revisar, revisando todo el nuevo ResultSet
   
    Loop While Valor="True"                                                          ' Consultaremos y ejecutaremos mientras el ResultSet tenga elementos.

End Function

Function ComillaSimple(Campo,TablaParaArreglar,Clave)
   
    '---------------------------------------------------------------------
    ' Haremos un ciclo que recorrerá todos los registros con alguna comilla simple, sustituyéndolo por espacio simple

    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    oSQLQuery="SELECT REPLACE( "& Campo &", CHAR( 39 ), ' ' ) ""Arreglo"", LOCATE( CHAR( 39 ), "& Campo &" ), """& Clave &""" FROM "& TablaParaArreglar &" "& TablaParaArreglar &" WHERE LOCATE( CHAR( 39 ), "& Campo &" ) <> '0'"
    oStat.setPropertyValue("ResultSetType",1005)                                     ' Características de la consulta
    oResultSet = oStat.executeQuery(oSQLQuery)                                       ' Se ejecuta la consulta
    Valor=oResultSet.next                                                            ' Va al siguiente registro
    oResultSet.last                                                                  ' Va al último registro para contar los registros que tiene
    oResultSet.first                                                                 ' Mueve el cursor al primer registro
    oResultSet.previous 
    '-----------------------------------------------------------------------
    ' Establecemos un array que recoge todos los datos de la consulta

    j = 0                                                                            ' Constante
    Dim ArrayDocumento1()                                                            ' Definición del array  
    While oResultSet.next                                                            ' Recorremos todos los datos del Resultset
    Redim Preserve ArrayDocumento1(j)                                                ' Redimensionamos el array
    ArrayDocumento1(j) = oResultset.getString(1)                                     ' Primer resultado del array
    j = j+1                                                                          ' Pasa al siguiente resultado del array
    '----------------------------------------------------------------------------
    ' Manejamos los datos del ResultSet
    
    Arreglo= RTRIM(LTRIM(oResultSet.getString(1)))                                   ' Cómo queremos que quede el campo
    Campo2=oResultSet.getString(3)                                                   ' Campo que queremos manipular
    '--------------------------------------------------------------------------
    ' Modificamos el registro que en un principio había y lo reemplazamos por otro sin comilla simple

    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    sSQL = "UPDATE "& TablaParaArreglar &" SET """& Campo &"""= '" & Arreglo &"' WHERE """& Clave &"""= '"& Campo2 &"'" ' Update del campo en cuestión
    oStat.ExecuteUpdate(sSQL)                                                        ' Se ejecuta la consulta
    Wend

End Function

Seguro que si alguien se pone a probarlo le empiezan a salir errores por aquí o por allá, pero a mí de momento no me ha dado ninguno.
Lo que no hace es substituir caracteres extraños (excepto las comillas simples). Para eso es mejor hacer un update con la función Replace para cada caso en concreto, aunque podríamos haber hecho un array de elementos extraños (incluyendo las comillas simples y los dobles espacios) y con una sola función recorriendo cada elemento del array limpiar todo de una atacada......
En fin, que esto es lo que hice y por si a alguien le viene bien.
:D
Un saludo!
Openoffice 4.1.7, en Windows 10
Libreoffice 6.4.2, en Windows 10
Longi
Mensajes: 804
Registrado: Dom Ene 20, 2013 9:05 pm
Ubicación: Ourense, Galicia, España

Re: Update columna a mayúscula cada palabra

Mensaje por Longi »

Como no podía ser de otra manera, ya empezó a dar problemas:
En el caso de que la tabla o el campo tengan un nombre con más de una palabra da error, pero con un muy pequeño parche ya está solucionado (pero solo este caso, los siguientes todavía no los ví, así que no pude intentar arreglarlos).
Aquí dejo la versión que funciona tanto con nombres de una palabra como para varias palabras:

Código: Seleccionar todo

Sub Mayusculas()

    Campo= "Apellidos"                                                               ' Campo en el que vamos a hacer los cambios
    Clave= "NIF persona"                                                            ' Campo clave en la tabla a modificar
    TablaParaArreglar="MITABLA"                                                   ' Tabla en la que vamos a hacer los cambios
    '================================================================
    ' Llamamos a las funciones para eliminar elementos parásitos (Comillas simples y dobles espacios)
    
    ComillaSimple(Campo,TablaParaArreglar, Clave)                                    ' Llamamos a la función de comillas simples
    DoblesEspacios(Campo,TablaParaArreglar, Clave)                                   ' Llamamos a la función de dobles espacios
    '===============================================================    
    ' Una vez que hemos limpiado de parásitos, empezamos con el ciclo
    
    Dim A$                                                                           ' Definimos la matriz
    A$=""                                                                            ' Vaciamos la matriz
    '----------------------------------------------------
    ' Determinamos un Result Set sobre el que trabajar, escogiendo los registros no vacíos
       
    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    oSQLQuery = "SELECT """& Campo &""","""& Clave &""" FROM """& TablaParaArreglar &""" WHERE """& Campo &""" IS NOT NULL" ' Consulta
    oStat.setPropertyValue("ResultSetType",1005)                                     ' Características de la consulta
    oResultSet = oStat.executeQuery(oSQLQuery)                                       ' Se ejecuta la consulta
    oResultSet.last                                                                  ' Va al último registro para contar los registros que tiene
    oResultSet.first                                                                 ' Mueve el cursor al primer registro
    oResultSet.previous 
    '-----------------------------------------------------------------------
    ' Establecemos un array que recoge todos los datos de la consulta
   
    j = 0                                                                            ' Constante
    Dim ArrayDocumento()                                                             ' Definición del array  
    While oResultSet.next                                                            ' Recorremos todos los datos del Resultset
    Redim Preserve ArrayDocumento(j)                                                 ' Redimensionamos el array
    ArrayDocumento(j) = oResultset.getString(1)                                      ' Primer resultado del array
    j = j+1                                                                          ' Pasa al siguiente resultado del array
    '----------------------------------------------------------------------------
    ' Manejamos los datos del ResultSet
    
    Campo1=RTRIM(LTRIM(oResultSet.getString(1)))                                     ' Campo que queremos manipular
    Campo2= oResultSet.getString(2)                                                  ' Campo para filtrado en el update
    '------------------------------------------------------------------
    ' Aplicamos el código para dejar la primera letra de cada palabra con mayúscula, el resto con minúscula
    
    Dim mCadenas()
    sSepara = Left(" ", 1 )                                                          ' Array de separación
    mCadenas = Split( Campo1, sSepara )                                              ' Rompemos el campo en tantas palabras como tenga separadas por un espacio                                            
    for i= LBound(mCadenas()) to UBound (mCadenas())                                 ' Ciclo que recorre cada palabra                             
    if not (mCadenas(i)="S.L." or mCadenas(i)="S.A." or mCadenas(i)="S.A.T."  or mCadenas(i)=" " or mCadenas(i)="S.C." or mCadenas(i)="XXIII" or mCadenas(i)="S/N" or mCadenas(i)="  ") Then
    A$= A$ & Ucase (Left (mCadenas(i),1))& LCase(Right(mCadenas(i),Len(mCadenas(i))-1) & " " ' Array ya resuelto
    End if                                                                           ' Acabamos las excepciones
    Next                                                                             ' Vamos a la siguiente palabra
    '----------------------------------------------------------------
    ' Generamos la consulta de actualización

    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                    ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                      ' Creación de la conexión
    sSQL = "UPDATE """& TablaParaArreglar &""" SET """ & Campo & """ = '"& A$ &"'  WHERE """& Clave &"""= '"& Campo2 &"'" 
    oStat.ExecuteUpdate(sSQL)                                                         ' Se ejecuta la consulta
    '--------------------------------------------------------------
    ' Vaciamos el array para que el siguiente registro vuelva a empezar desde cero
   
    A$=""                                                                            ' Vaciamos el array
    Wend                                                                             ' Acabamos el ciclo del ResultSet
    
End Sub  

Function DoblesEspacios(Campo,TablaParaArreglar,Clave)
    
    '---------------------------------------------------------------------
    ' Haremos un ciclo que recorrerá todos los registros con algún doble espacio, sustituyéndolo por espacio simple
    ' lo cual nos dejará en ocasiones aún dobles espacios (espacio simple + espacio simple, por lo que habrá que repetir ciclo hasta el arreglo total.
    
    do                                                                               ' Generamos el ciclo
    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    oSQLQuery="SELECT REPLACE( """& Campo &""", '  ', ' ' ) ""Arreglo"", LOCATE( '  ', """& Campo &""" ), """& Clave &""" FROM """& TablaParaArreglar &""" """& TablaParaArreglar &""" WHERE LOCATE( '  ', """& Campo &""" ) <> '0'"       
    'oSQLQuery="SELECT REPLACE( """& Campo &""", CHAR( 39 ), ' ' ) ""Arreglo"", LOCATE( CHAR( 39 ), """& Campo &""" ), """& Clave &""" FROM "& TablaParaArreglar &" "& TablaParaArreglar &" WHERE LOCATE( CHAR( 39 ), """& Campo &""" ) <> '0'"
    oStat.setPropertyValue("ResultSetType",1005)                                     ' Características de la consulta
    oResultSet = oStat.executeQuery(oSQLQuery)                                       ' Se ejecuta la consulta
    Valor=oResultSet.next                                                            ' Vamos al siguiente elemento del ResultSet
    oResultSet.last                                                                  ' Va al último registro para contar los registros que tiene
    oResultSet.first                                                                 ' Mueve el cursor al primer registro
    oResultSet.previous 
    '-----------------------------------------------------------------------
    ' Establecemos un array que recoge todos los datos de la consulta

    j = 0                                                                            ' Constante
    Dim ArrayDocumento1()                                                            ' Definición del array  
    While oResultSet.next                                                            ' Recorremos todos los datos del Resultset
    Redim Preserve ArrayDocumento1(j)                                                ' Redimensionamos el array
    ArrayDocumento1(j) = oResultset.getString(1)                                     ' Primer resultado del array
    j = j+1                                                                          ' Pasa al siguiente resultado del array
    '----------------------------------------------------------------------------
    ' Manejamos los datos del ResultSet
    
    Arreglo= RTRIM(LTRIM(oResultSet.getString(1)))                                   ' Cómo queremos dejar el campo después del arreglo
    Campo2=oResultSet.getString(3)                                                   ' Campo que queremos manipular
    '---------------------------------------------------------------------------
    ' Insertamos el arreglo (la desaparición de dobles espacios) en el campo de la tabla que estamos manipulando
    
    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    sSQL = "UPDATE """& TablaParaArreglar &""" SET """& Campo &"""= '" & Arreglo &"' WHERE """& Clave &"""= '"& Campo2 &"'"
    oStat.ExecuteUpdate(sSQL)                                                        ' Se ejecuta la consulta
    Wend                                                                             ' Vamos al siguiente elemento del ResultSet
    '----------------------------------------------------------------------
    ' Una vez revisado todo el ResultSet, si teníamos algún elemento que quedó todavía con algún doble espacio, lo volvemos a revisar, revisando todo el nuevo ResultSet
   
    Loop While Valor="True"                                                          ' Consultaremos y ejecutaremos mientras el ResultSet tenga elementos.

End Function

Function ComillaSimple(Campo,TablaParaArreglar,Clave)
   
    '---------------------------------------------------------------------
    ' Haremos un ciclo que recorrerá todos los registros con alguna comilla simple, sustituyéndolo por espacio simple

    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    oSQLQuery="SELECT REPLACE( """& Campo &""", CHAR( 39 ), ' ' ) ""Arreglo"", LOCATE( CHAR( 39 ), """& Campo &""" ), """& Clave &""" FROM """& TablaParaArreglar &""" """& TablaParaArreglar &""" WHERE LOCATE( CHAR( 39 ), """& Campo &""" ) <> '0'"
    oStat.setPropertyValue("ResultSetType",1005)                                     ' Características de la consulta
    oResultSet = oStat.executeQuery(oSQLQuery)                                       ' Se ejecuta la consulta
    Valor=oResultSet.next                                                            ' Va al siguiente registro
    oResultSet.last                                                                  ' Va al último registro para contar los registros que tiene
    oResultSet.first                                                                 ' Mueve el cursor al primer registro
    oResultSet.previous 
    '-----------------------------------------------------------------------
    ' Establecemos un array que recoge todos los datos de la consulta

    j = 0                                                                            ' Constante
    Dim ArrayDocumento1()                                                            ' Definición del array  
    While oResultSet.next                                                            ' Recorremos todos los datos del Resultset
    Redim Preserve ArrayDocumento1(j)                                                ' Redimensionamos el array
    ArrayDocumento1(j) = oResultset.getString(1)                                     ' Primer resultado del array
    j = j+1                                                                          ' Pasa al siguiente resultado del array
    '----------------------------------------------------------------------------
    ' Manejamos los datos del ResultSet
    
    Arreglo= RTRIM(LTRIM(oResultSet.getString(1)))                                   ' Cómo queremos que quede el campo
    Campo2=oResultSet.getString(3)                                                   ' Campo que queremos manipular
    '--------------------------------------------------------------------------
    ' Modificamos el registro que en un principio había y lo reemplazamos por otro sin comilla simple

    Conn = ThisDatabaseDocument.CurrentController.ActiveConnection                   ' Conectamos para recoger los datos de las tablas
    oStat=Conn.createStatement()                                                     ' Creación de la conexión
    sSQL = "UPDATE """& TablaParaArreglar &""" SET """& Campo &"""= '" & Arreglo &"' WHERE """& Clave &"""= '"& Campo2 &"'" ' Update del campo en cuestión
    oStat.ExecuteUpdate(sSQL)                                                        ' Se ejecuta la consulta
    Wend

End Function



Otro saludo!
Openoffice 4.1.7, en Windows 10
Libreoffice 6.4.2, en Windows 10
Responder