lunes, 7 de mayo de 2018

VBA: Forzar siempre Mayúsculas

En algún foro en el que participo preguntaba un usuario por la manera de obligar al usuario de escribir siempre en mayúsculas.

Iremos un paso más allá, y aprenderemos una forma de forzar las minúsculas o a escribir en modo 'Nombre Propio'.


Una manera sería mediante eventos de hoja, en concreto un evento que detecte que se ha escrito algo en alguna celda. El evento buscado será el Worksheet_Change.
Nuestra macro detectaré el cambio en la celda y, evitando sen una fórmula o función lo que hayamos escrito, procederá al cambio buscado.

En diferentes alternativas usaremos las funciones de VB:
UCASE para mayúsculas
LCASE para minúsculas
podríamos usar la función de hoja de cálculo
Worksheetfunction.PROPER para forma de Nombre Propio

o bien emplear la función de VB
StrConv(string, conversion, [LCID])
siendo el parámetro conversion, entre otras posibilidades:
vbUpperCase - 1 - Convierte la cadena a caracteres en mayúscula.
vbLowerCase - 2 - Convierte la cadena a caracteres en minúscula.
vbProperCase - 3 - Convierte la primera letra de cada palabra de la cadena en mayúscula.


Vemos las opciones comentadas...

En la ventana de código de la hoja incluimos el siguiente evento _Change:

Private Sub Worksheet_Change(ByVal Target As Range)
'Convierte a mayúscula/minúscula cualquier celda de la hoja
'tras aceptar
''''''''''''''''''''''''''''''''''''''''''''

'controlamos no haya más de una celda seleccionada
'o que la celda no tenga fórmulas
If Target.Cells.Count > 1 Or Target.HasFormula Then Exit Sub
On Error Resume Next

Application.EnableEvents = False    'deshabilitamos momentáneamente los eventos de la hoja
'convertimos a mayúsculas la celda cambiada
'empleando las funciones de VBA UCASE o LCASE
Target.Value = VBA.UCase(Target.Value)      'LCase(Target.value) para minúsculas
Application.EnableEvents = True     'y los volvemos a habilitar
On Error GoTo 0
End Sub



Una alternativa más 'profesional', también en la ventana de código de la hoja:

Private Sub Worksheet_Change(ByVal Target As Range)
'Convierte a mayúscula la primera letra de cada palabra
'para cualquier celda de la hoja tras Aceptar
''''''''''''''''''''''''''''''''''''''''''''
'controlamos no haya más de una celda seleccionada
'o que la celda no tenga fórmulas
If Target.Cells.Count > 1 Or Target.HasFormula Then Exit Sub

On Error Resume Next
Application.EnableEvents = False    'deshabilitamos momentáneamente los eventos de la hoja
'empleamos la función
'StrConv(string, conversion, [LCID])
'siendo conversion:
'vbUpperCase - 1 - Convierte la cadena a caracteres en mayúscula.
'vbLowerCase - 2 - Convierte la cadena a caracteres en minúscula.
'vbProperCase - 3 - Convierte la primera letra de cada palabra de la cadena en mayúscula.
Target.Value = VBA.StrConv(Target.Value, vbProperCase)
Application.EnableEvents = True      'y los volvemos a habilitar
On Error GoTo 0
End Sub



Otra posibilidad algo más compleja por sus repercusiones sería emplear una API de Windows SetKeyboardState:

Declare Function SetKeyboardState Lib "user32" (lppbKeyState As Byte) As Long
Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long

Sub BloqueoMayuscula()
'OJO!! solo afecta a Excel.. nunca a otras aplicaciones!!
'por tanto cambairá los indicadores luminosos de NUM LOCK, CAPS LOCK o SCROLL LOCK del teclado.

Dim Resultado As Long
'matriz para el estado de las teclas virtuales existentes
Dim EstadoTeclas(0 To 255) As Byte

'Algunas teclas sobre las que trabajar
'Shift = &H10   
'Ctrl = &H11    
'Alt = &H12    
'CapsLock = &H14
'NumLock = &H90
'ScrollLock = &H91

'trabajamos sobre la mayúscula
EstadoTeclas(&H14) = 1 '1 - activa, 0 - desactiva

Resultado = SetKeyboardState(EstadoTeclas(0))

End Sub


Esta macro la podemos asociar al evento Open del Workbook o cualquiera otro mediante el que controlemos la acción deseada...

4 comentarios:

  1. BUENAS POR FAVOR SI ME PUEDEN AYUDAR EN ESTO.TENGO ESTE EJERCICIO EN UNA HOJA DE EXCEL 265 PARTICIPANTES Y TENGO OTRA HOJA DE WORD EL DIPLOMA EN IMAGEN Y NECESITO PASAR ESTOS DATOS, Nº DE IDENTIDAD,NOMBRE Y APELLIDO ,LUGAR DE NACIMIENTO,FECHA DE NACIMIENTO,FECHA DE EXPEDICIÓN,Y AÑO DE INGRESO.PASAR A WORD,ES DECIR QUE CUANDO REALICE UN CAMBIO DE DATOS EN CUADRO EN EXCEL ESTOS SE CAMBIEN EN EL DIPLOMA EN WORD. HE TRATADO PERO NO HE PODIDO.NO SE SI HAY ALGUNA MANERA DE HACERLO,DE ANTE MANO GRACIAS.

    ResponderEliminar
    Respuestas
    1. Hola Carlos,
      lo más sencillo sería desde Word haciendo una Combinación de correspondencia que se vincule a ese Excel con los 256 participantes..

      Otras formas requerirían programación y desarrollar alguna macro para tu caso concreto

      Saludos

      Eliminar
  2. Hola Ismael, gracias por tu aporte. Tengo una duda, cómo se podría hacer para que cuando se copie un rango, por ejemplo 5 celdas con letras en minúsculas, y se pegue en la hoja1, todas las celdas pegadas se transformen en mayúsculas. La alternativa que nos presentas aplica solo si se pega una celda o se escribe en una sola celda.

    Gracias de antemano.

    ResponderEliminar
    Respuestas
    1. Hola Alvaro,
      se podría usar la función de VB UCASE que convierte en mayúscula lo que se indique...
      habría que hacer un loop que recorra cada celda

      En todo caso en breve escribiré un post con otra solución más elegante

      Saludos

      Eliminar

Nota: solo los miembros de este blog pueden publicar comentarios.