jueves, 13 de julio de 2023

74 - TEXTBOX (Parte 2) - Realizar cálculos y asignar formatos a otro tipo de controles.

 En el tema anterior aprendimos a controlar el tipo de caracteres que ingresamos en un control TextBox, con el fin de asignarle formatos moneda, números con decimales, y formatos especiales.

En este tema, veremos cómo realizar cálculos a medida que rellenamos una cierta cantidad de TextBox. Programaremos los eventos KEYPRESS y EXIT, guardando el acumulado en otro tipo de control, en este caso un LABEL.

También veremos cómo 'descontar' el valor que tiene un control a la hora de modificar su contenido. Y que esos cambios se reflejen en el total acumulado. Para esto trabajaremos con el evento ENTER de los TextBox.

En este ejemplo tenemos un formulario (Userform2) con 3 controles TextBox y un control Label donde guardaremos el acumulado.


En este ejemplo, incompleto, cada uno de los controles tendrá programados 2 eventos: 

- KEYPRESS para controlar que solo se ingresen valores numéricos, coma decimal y signo menos. También se puede optar por permitir el punto en caso de que ese sea el separador de decimales.

Desde Google encontramos gran cantidad de páginas que nos ofrecen la lista completa de caracteres Ascii necesarios para evaluar los caracteres que vamos tipeando en cada TextBox.

-EXIT para acumular el contenido de este control a un total que se va mostrando en un Label. Y a ese total, como así también al control de texto, se le asigna un formato moneda.

Por lo tanto cada control tendrá las siguientes 2 subrutinas, ajustando en cada grupo el nombre del TextBox.

Previamente declaramos una variable para ir guardando el acumulado.

Dim importe As Double     'guarda el acumulado como decimal.

 

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

If (KeyAscii < 48 And KeyAscii <> 44 And KeyAscii <> 45) Or KeyAscii > 57 Then

    KeyAscii = 0

    MsgBox "Solo ingresa números, signo menos y coma decimal"

End If

End Sub


Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)

    If TextBox1 <> "" Then importe = importe + CDbl(TextBox1.Value)

    Label2.Caption = Format(importe, "$ #,###,##0.00")

    TextBox1 = Format(TextBox1.Value, "$ #,###,##0.00")

End Sub

NOTA: para que se reconozca como un valor doble, es decir decimal, debemos convertir el contenido del TextBox con la función CDBL.

Pero este ejemplo no nos dará resultados correctos en caso de que modifiquemos alguna cifra, porque estaría sumando nuevamente el valor del control al momento de salir de él.

Por lo tanto necesitamos controlar, además, el evento ENTER. Allí guardaremos en una nueva variable el contenido del TextBox al momento de ingresar a él. Y al salir, en el evento Exit restaremos ese valor y acumularemos el nuevo importe.

Dim valorx As Double

 

Private Sub TextBox1_Enter()   'al ingresar al control se guarda el contenido para luego descontarlo

If TextBox1 <> "" Then valorx = CDbl(TextBox1.Value)

End Sub

Ahora sí ya tendremos todo el código necesario: las 2 variables 'double' y los 3 eventos para cada uno de los TextBox.

Como al salir de cada TextBox debemos realizar varias tareas, y serán las mismas para cada control, podemos agruparlas en una subrutina auxiliar. A esa subrutina solo necesitaremos pasarle como argumento el nombre del TextBox utilizado.

Por lo tanto vamos a reemplazar el evento Exit anterior por este otro. Y será igual en todos los controles.

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)  'al salir se acumula y se aplica formato

    Call calcular("TextBox1")

End Sub


Solo nos resta agregar la subrutina llamada 'calcular', en el mismo Userform.

Sub calcular(miCtrl)

'evaluamos entre todos los controles del Userform, el que se llame como el argumento miCtrl.

If Me.Controls(miCtrl).Value <> "" Then

   'si el textbox tiene un importe se acumula al total y se resta el valor que tenía al momento de ingresar en él

  importe = importe + CDbl(Me.Controls(miCtrl).Value) - valorx

Else

  'si el textbox quedó vacío solo se resta el valor que tenía al momento de entrar en él.

  importe = importe - valorx

End If

'se coloca el acumulado en el Label y se asigna formato moneda

Label2.Caption = Format(importe, "$ #,###,##0.00")

'también se coloca formato al textbox que llamó a esta subrutina.

Me.Controls(miCtrl) = Format(Me.Controls(miCtrl), "$ #,###,##0.00")

'se limpia la variable auxiliar

valorx = 0

End Sub



Ver video Nº 74 desde aquí.


El libro con los ejemplos presentados en videos 73 y 74 se puede descargar desde este enlace. O solicitarlo a mi correo: cibersoft.arg@gmail.com







jueves, 29 de junio de 2023

73 - TEXTBOX : Con formatos y control de contenidos.

Considerando que los controles TEXTBOX son controles de 'textos', para trabajarlos con valores numéricos tendremos que controlar su ingreso y además luego darle un formato apto para utilizarlos en cálculos numéricos.

Los principales eventos que utilizaremos en este primer ejemplo son: 

- KEYPRESS : nos permite controlar cada caracter (KeyAscii) introducido.  

- EXIT : nos permite asignar un formato al salir del control, y también controlar contenidos o aplicar  restricciones.

En el Userform1 tenemos 3 controles TextBox. 

                                  

En el primer control, TextBox1, no hay restricciones. Se reciben números, letras y caracteres alfanuméricos. Solo se indica que en caso de ser un contenido numérico, le aplique formato moneda corriente (ver NOTAS al pie).

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)  

'al salir se aplica formato

   If VBA.IsNumeric(TextBox1.Value) And TextBox1 <> "" Then

       TextBox1 = Format(TextBox1.Value, "$ #,###,##0.00")

   End If

End Sub

En el segundo control, TextBox2, solo se permiten números, coma decimal y signo -

Private Sub TextBox2_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

   If (KeyAscii < 48 And KeyAscii <> 44 And KeyAscii <> 45) Or KeyAscii > 57 Then

       KeyAscii = 0

       MsgBox "Solo ingresa números, signo menos y coma decimal"

   End If

End Sub


En este evento, el cursor permanecerá en el control TextBox2 hasta ingresar los valores correctos.

Y al salir del objeto, se aplicará formato moneda:

Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)

    TextBox2 = Format(TextBox2.Value, "$ #,###,##0.00")

End Sub


En el tercer objeto, TextBox3, solo se permiten números. 

Private Sub TextBox3_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

   If (KeyAscii < 48 Or KeyAscii > 57) Then

       KeyAscii = 0

       MsgBox "Solo ingresa números."

   End If

End Sub

La restricción que le aplicamos a este control, y que se evalúa en el evento EXIT, es decir al momento de salir de él, es que tenga un máximo de 6 caracteres. Y se le aplica un formato especial del tipo 000-000.

Private Sub TextBox3_Exit(ByVal Cancel As MSForms.ReturnBoolean)

    If Len(TextBox3) > 6 Then

        MsgBox "Máximo 6 dígitos"

        Cancel = True

    Else

        TextBox3 = Format(TextBox3.Value, "000-000")

    End If

End Sub



NOTAS: 

La función LEN nos devuelve el total de caracteres que presenta el control TextBox.

La instrucción Cancel = True hará que el cursor permanezca en el control hasta cumplir con la condición de los 6 caracteres.  Esto no sucede si utilizamos el evento AfterUpdate.

El formato 'moneda' puede ser indicado también de este modo, para que se tome la moneda corriente del usuario.

    TextBox2 = Format(TextBox2.Value, "Currency")


Descargar ejemplo del Userform1 desde aquí o solicitarlo al correo:  cibersoft.arg@gmail.com

Ver video Nº 73 desde aquí.





martes, 18 de abril de 2023

72 - Modificar hipervínculos masivamente.

 Cuando tenemos en un libro Excel vínculos hacia otras hojas u otras referencias de fila/columna, nos encontramos con el problema de que al moverlos siguen conectados al origen. 

Así, por ejemplo, si tenemos una hoja como en la siguiente imagen, donde cada vínculo nos lleva a un cuadro dentro de la Hoja1, al copiar esa hoja y asignarle otro nombre el vínculo siempre nos dirige a la hoja de origen, o sea a la Hoja1.

Para resolver esta situación, utilizaremos una macro de pocas instrucciones, donde vamos a cambiar el argumento SubAddress, o sea la dirección del vínculo. 

Y además, en este ejemplo, modificaremos otros 2 argumentos: 

. ScreenTip (el texto que se muestra al pasar el mousse por encima del vínculo) y 

. TextToDisplay (el texto o valor que se muestra en la celda).


En un módulo copiaremos esta macro:

Sub ModificarHipervinculos()        'modificar los hipervínculos dirigiéndolos a otra hoja

'x Elsamatilde

Dim anterior As String, nuevo As String, nvaDire As String, cadena As String

Dim x As Integer, y As Integer

Application.ScreenUpdating = False

anterior = "Hoja1": nuevo = ActiveSheet.Name     'nombres de hojas

Range("O:O").Clear                              'limpia col auxiliar

y = Range("A" & Rows.Count).End(xlUp).Row    'recorre la col A que tiene los hipervínculos a modificar

For x = 4 To y

    Range("O" & x) = Range("A" & x).Hyperlinks(1).SubAddress        'coloca en col auxiliar el hipervínculo

    Range("O" & x).Replace What:=anterior, Replacement:=nuevo       'reemplaza el texto anterior por el nuevo

    Range("A" & x).Select                                           'vuelve a crear el hipervínculo en la col donde se encontraba

    ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:="", _

    SubAddress:=nvaDire, _

    ScreenTip:=cadena, _

    TextToDisplay:=ActiveCell.Text

Next x

MsgBox "Fin del proceso."

End Sub

Luego se podrá ejecutar desde el menú Programador/Desarrollador estando en la hoja activa, es decir, donde se encuentra la lista de vínculos que deseamos actualizar.

NOTA: podemos incluir el valor de las variables directamente en la instrucción del Hyperlink, quedándonos así:

ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:="", _

    SubAddress:=Range("O" & x), _

    ScreenTip:=ActiveSheet.Name & "-" & Range("A" & x), _

    TextToDisplay:=ActiveCell.Text


El libro de ejemplo se puede descargar desde este enlace o solicitarlo al correo: cibersoft_arg@gmail.com

Ver video Nº 72 con el paso a paso desde aquí.





domingo, 19 de febrero de 2023

71 - Copiar y Pegar con VBA

CTRL C y CTRL V deben ser los atajos de teclado utilizados con mayor frecuencia, en Excel.

Pero a la hora de necesitar pegados especiales, con VBA, no siempre es tan fácil conocer o recordar las instrucciones.

En el libro que se adjunta, encontrarán una guía completa con los resultados obtenidos en cada situación y según las instrucciones utilizadas.

Se programaron las siguientes situaciones:

- Copiado de Rangos Filtrados.

- Copiar un rango .de una Tabla en otro destino. 

- Copiar un rango de celdas (no Tabla) en otro destino.

- Copiar rangos de Tabla o de celdas según los siguientes criterios:

  • Solo valores
  • Valores y Formatos de números.
  • Valores y Formatos de origen
  • Solo fórmulas (sin formatos)
  • Fórmulas y Formatos de números

- Copiado de Rangos Filtrados.

    Tablas filtradas, columnas totales o parciales.
    Rangos filtrados, columnas totales o parciales.
    Rango pegado sin formatos, solo fórmulas.

Descargar libro guía desde aquí.

* Si la descarga no se puede realizar solicitar los libros de ejemplos al correo: 

Ver video Nº 71 desde aquí.