Hojas de cálculo en Excel - página principal

Modificar datos utilizando un formulario

En una entrega anterior, habíamos visto como introducir datos a través de un formulario. Si vamos a utilizar la técnica de los formularios para introducir datos en Excel, es más que probable que necesitemos en alguna ocasión, modificar los datos introducidos, bien porque nos hayamos equivocado al darlos de alta, o por cualquier otro motivo.

Pues hoy vamos a ver precisamente eso, como modificar datos de una hoja de cálculo, utilizando un formulario. He utilizado un ejemplo muy parecido al que habíamos visto en aquella entrega, para que sea más sencillo. Eso sí, una observación: si queréis integrar de forma conjunta el alta de datos y la modificación de datos, utilizando estos ejemplos, copiando y pegando los macros, deberéis tener en cuenta que en el artículo donde os hablaba de cómo introducir datos a través de un formulario, los controles (ComboBox, TextBox, etc.) no tienen el mismo nombre que en este artículo que estáis leyendo. Por ejemplo, en aquel artículo, el TextBox de la cantidad de producto, se llamaba TextBox2, y en este artículo lo llamaremos TextBox1.

Una vez dicho todo esto, vamos a ponernos manos a la obra. Necesitaremos una tabla con datos -eso es evidente-, pues lo que haremos será modificarlos. Necesitaremos que los datos estén de forma continua, sin líneas en blanco, para que nos funcione este ejemplo, aunque se puede utilizar para otros ejemplos donde no se cumpla esta condición. Simplemente tendremos que cambiar un par de líneas. Más adelante os comentaré de qué estamos hablando.




Los dos macros que colocaremos dentro de un módulo serán estos:


Sub Auto_open()
'Protegemos la hoja
ActiveSheet.Protect
End Sub


Sub introducir_datos()
'llamamos al formulario
UserForm1.Show
End Sub

Dentro del Formulario (UserForm), tendremos el resto del código. Utilizaremos un macro llamado ComboBox1_Enter() que se ejecutará como su nombre indica, al hacer clic en el ComboBox1. Tendremos también otro llamado ComboBox1_Change(), que nos servirá para cargar en los TextBox los datos correspondientes al productos elegido. También utilizaremos dos macros que evalúen si estamos cambiando la cantidad de producto, y el precio unitario, para recalcular el total, a través de un TextBox1_Change() y de un TextBox2_Change(). Utilizaremos otro macro llamado CommandButton1_Click() que contendrá el código al pulsar el botón para grabar datos, y otro llamado CommandButton2_Click() que servirá, no para borrar los datos del formulario, como en el ejemplo donde introducíamos datos a través de un formulario, sino para eliminar el artículo o producto, de la tabla de Excel.

Vamos a ver el código de todos ellos:

Private Sub ComboBox1_Enter()
'En caso de error, que continúe
On Error Resume Next
'limpiamos los datos del Combobox
ComboBox1.Clear
'Al inciar el formulario,
'seleccionamos la hoja con los datos

Hoja1.Select
'Seleccionamos la celda B5
Range("B5").Select
'Vamos a llenar dinámicamente el combobox
'con los nombres de los artículos, hasta
'encontrar una fila vacía

Do While Not IsEmpty(ActiveCell)
'ponemos el nombre del producto
ComboBox1.AddItem ActiveCell.Value
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Loop
End Sub

En el caso de que no tengamos los datos de forma continua, y hayan filas en blanco, si usamos el bucle Do While del macro anterior, solo se nos cargarán en el ComboBox1 los datos que haya hasta esa fila vacía. Si queremos usarlo correctamente y tenemos filas vacías en la tabla cuyos datos queremos modificar, tendremos que sustituir el bucle Do While por un bucle For para que recorra todas las filas, desde la fila inicial hasta la fila final. Eso sí, se nos cargarán también en el ComboBox1 las filas vacías, aunque podemos omitirlas, añadiendo solo aquellas celdas al combo que contengan datos (que no estén vacías), con un sencillo condicional que evalúe si la celda está vacía o no.

Bien, seguimos con el resto del código que utilizaremos, y que será el siguiente:

Private Sub ComboBox1_Change()
'Miramos en qué fila está el producto
'seleccionado en el ComboBox, y le sumaremos
'4 porque empezamos los productos en la fila
'5 (celda B5). Sumaremos también un 1, porque
'los elementos del combobox empiezan a numerarse
'desde cero. Con lo cual sumaremos 4 + 1 = 5.
'Seleccionaremos esa fila, de la columna B, es
'decir, de la columna 2 (el producto)

Cells(ComboBox1.ListIndex + 5, 2).Select
'cargamos los datos correspondientes
'al producto elegido

TextBox1 = ActiveCell.Offset(0, 1)
TextBox2 = ActiveCell.Offset(0, 2)
TextBox3 = ActiveCell.Offset(0, 3)
End Sub


Private Sub TextBox1_Change()
'Si cambiamos la cantidad, modificaremos
'el precio total

If TextBox1 <> "" And IsNumeric(TextBox1) And _
TextBox2 <> "" And IsNumeric(TextBox2) Then
TextBox3 = TextBox1 * TextBox2
End If
End Sub


Private Sub TextBox2_Change()
'Si cambiamos el precio unitario, modificaremos
'el precio total

If TextBox1 <> "" And IsNumeric(TextBox1) And _
TextBox2 <> "" And IsNumeric(TextBox2) Then
TextBox3 = TextBox1 * TextBox2
End If
End Sub


Private Sub CommandButton1_Click()
'Desprotegemos la hoja
ActiveSheet.Unprotect
'Miramos en qué fila está el producto
'seleccionado en el ComboBox, y le sumaremos
'4 porque empezamos los productos en la fila
'5 (celda B5). Sumaremos también un 1, porque
'los elementos del combobox empiezan a numerarse
'desde cero. Con lo cual sumaremos 4 + 1 = 5.
'Seleccionaremos esa fila, de la columna B, es
'decir, de la columna 2 (el producto)

Cells(ComboBox1.ListIndex + 5, 2).Select
'grabamos los datos modificados
'comenzando con la cantidad

ActiveCell.Offset(0, 1) = CDbl(TextBox1)
'el precio unitario
ActiveCell.Offset(0, 2) = CDbl(TextBox2)
'y ahora el precio total
ActiveCell.Offset(0, 3) = CDbl(TextBox3)
'limpiamos los datos
ComboBox1.Clear
TextBox1 = ""
TextBox2 = ""
TextBox3 = ""
'ponemos el focus en el TextBox1
TextBox1.SetFocus
'protegemos la hoja
ActiveSheet.Protect
End Sub


Private Sub CommandButton2_Click()
'Desprotegemos la hoja
ActiveSheet.Unprotect
'borramos esa línea entera
Selection.EntireRow.Delete
'reiniciamos los datos del formulario
ComboBox1.Clear
TextBox1 = ""
TextBox2 = ""
TextBox3 = ""
End Sub

Desde aquí podéis descargar el fichero, con el ejemplo que hemos visto en este artículo.



23 comentarios:

Unknown dijo...

Muchas gracias por la información. ME ha sido muy util

asico

ElProfe dijo...

Apreciado Javier:

Interesante ejercicio, con la ventaja adicional que te propones presentarlo de una manera tan sencilla que hasta yo lo entendí (je je).

Gracias por tu generosidad al compartir tus ideas y conocimiento.

Saludos,

ElProfe

Javier Marco dijo...

Muchas gracias a ambos por vuestros comentarios, en especial a ElProfe, que siempre estás por estos lares de Dios.

Comentarios como los vuestros, son el mejor regalo que me puede hacer Papa Noel :-)

diego dijo...

Gracias Javier,
Estoy integrando los 2 ejemplos en un solo documento y cambiando los nombres de los campos para usarlos en el inventario de mi herramienta. Ya he usado con gran exito una macro que me ayudaste a crear hace tiempo.
Felices fiestas y de nuevo Gracias por este blog tan util. Diego

Javier Marco dijo...

Muchas gracias por tu comentario.

Feliz año :-)

Rosalía dijo...

Tu Blog es bastante bueno, he aprendido mucho, gracias por compartirlo.

Martin Rodriguez dijo...

jAVIER, VI QUE POSTEAS TEMAS DE MACROS MUY BUENAS, NECESITARIA UNA MACRO PARA COPIAR DESDE UNA BASE DE DATOS DE 10 COLUMNAS Y 77 FILAS "SOLO" LAS CELDAS QUE CONTENGAN DATOS, O SEA, DESDE LA A96 HASTA LA J170 TIENEN VALORES, EL RESTO PARA ABAJO NO, QUIERO QUE COPIE SOLO ESAS CELDAS Y LAS PEGUE EN OTRO ARCHIVO DE EXCEL, tener en cuenta que no siempre las mismas tendran datos, pero si siempre dentro del mismo rango A1:J172. MUCHAS GRACIAS.

ecurico dijo...

hola primero agradecerte ya que tus macros me han servido muchisimo y lo principal que he aprendido mas.
Me gustaria que me ayudaras con esta planilla ya que en el combobox tengo mucho datos ingresados cerca de 8000.Al ingresar algunas caracteristicasdel producto lo encuentra enseguida pero cuando carga la lista se demora mucho ya que los registros son demasiados y tiene que ser asi.sino me equibooco en esta linea carga los productos

Do While Not IsEmpty(ActiveCell)
ComboBox1.AddItem ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Loop

me gustaria saber si hay alguna manera de cargar los elementos del combobox mas rapido ya que son muchos los datos que tengo que agregar a los productos.

De ante mano muchas gracias.

Javier Marco dijo...

La forma como llenas el Combo es correcta, pero pone como primera línea esto:

Application.ScreenUpdating = False

Luego al final, lo pones a true, y listo. Acabo de probarlo con 10.000 filas cargando en un Combobox, y me tarda aproximadamente 1 segundo en llenarlo. Claro, son 10.0000 datos.

Prueba de esta otra forma también, a ver si es algo más rápido (aunque puede que incluso sea unas milésimas o centésimas de segundo más lento):

Application.ScreenUpdating = False
Range("A1").Select
For i = 0 To Selection.End(xlDown).Row
ComboBox1.AddItem ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Next
Application.ScreenUpdating = true

ecurico dijo...

muchas gracias por tu pronta respuesta.Me ayudo ya que ahora esta mas rapido. pero tengo una duda mas, a mi, la lista del combobox no me sirve mucho ya que comprenderas que con 10.000 registros es un poco complicado ubicarlos ,lo que me sirve es que al insertar parte del nombre me lo completa de inmediato el que mas se asemeja.no existe la posiblidad de eliminar la lista y que siga haciendo el mismo proceso de busqueda y autocompletado.

Esto agilizara aun mas el combobox?

espero que me puedas ayudar.

de ante mano muchas gracias

saludos

Javier Marco dijo...

Tendrás que adaptar una utilidad que hizo un compañero de foros del web. En este hilo de Foros del Web, tienes el ejemplo: http://www.forosdelweb.com/f90/ayuda-con-macro-comodines-734714/

Un saludo.

ecurico dijo...

Te vuelvo a repetir muchas gracias.Me haz ayudado mucho.


Gracias

rodrigo dijo...

buenas tardes

mi consulta es la siguente :

como puedo editar los registros q ingreso en este formulario ???

se me ocurre q se debe ingresar el folio y cargar los datos en el formulario y luego editarlos . estoy recien comenzando a trabajar con userforms , ojala me puedan ayudar

Adjunto el archivo

http://www.mediafire.com/?yenkzgommm2

saludos cordiales

Anónimo dijo...

Hola Javier marco, Soy un novato en esto de codigo VBA en Excel tu blogger tiene muy buena información al respecto, pero es que tengo un problema para crear un formulario de modificación de dato, tu ejemplo es muy bueno pero yo quisiera saber si en vez utilizar un combobox, utilizar textbox para buscar un dato determinado y editar sus componente. Ej. Una agenda de telefono: nombre, CI. edad, telf, direc. Al colocar la CI. En el textbox me aparezca su información; nombre, edad, telf, direc y poderla modificar.

Anónimo dijo...

Tengo Una pregunta, hice lo que tu indicas, y sale bien, pero si quiero trasladar la informacion a otra hoja. Como hago para que cuando este en la hoja1, el macro al desplegar el ComboBox1 no se vaya hasta la Hoja2, sabes como anular ese movimiento, que pueda hacerlo pero internamente sin que al usuario lo dezplace a la hoja2????

Javier Marco dijo...

Por como primera línea del macro esta:

Application.ScreenUpdating = False

Y como última línea del macro esta otra:

Application.ScreenUpdating = True

De esa forma no se verá la ejecución del macro en pantalla.

Saludos.

Anónimo dijo...

esta muy bueno lo aplique la cosa es que no entendi como hacer para que obvie las filas en blanco porqeu si tengo filas en blanco

alexguajo dijo...

Hola amigo esyo me sirvio muucho, pero tengo una duda estoy haciendo un sistema de invenaroo de equipos quisiera validar por ejemplo q un dato q quiro editar ya está asiganado a otro usuario o loalidad como podria hacerlo

fito dijo...

en vez de que me busque el dato con el combobox quisiera seleccionar la fila y al presionar el boton me cargue los datos como se hace?

JuanVen dijo...

Buen día Javier, digamos que a la base de datos como el ejemplo que muestras, tiene una dato adicional que es el código de barras (EAN) del producto. Ahora, yo quiero consultar ese producto empleando para ello el código de barras y que el formulario me muesre todos los demás datos a modo de consulta, de manera que el usuario pueda sólo consultar, más no modificar, menos eliminar, dichos datos como en tu ejemplo.

La idea es que el usuario abra el libro de Excel y automáticamente le salga el formulario y sin más ni más, inicie la consulta usando dicho código de barras. Que realice esta consulta N cantidad de veces. Sólo ver los datos. No haría falta un botón de "salir" del formulario, mas bien con cerrar el libro bastaria. Piensa que lo va emplear un usuario con muy limitados conocimientos. Ni siquiera haría falta guardar los datos ya que los mismos estarían previamente guardados en una hoja oculta en el mismo libro.

Saludos,

Miguel dijo...

Hola Javier:
Llevo mirado solo un par de ejemplos, y creo que tenemos que agradecerte el trabajo.
Soy formador Excel y ando a la busqueda de ejercicios, y parece que he encontrado un filon...
Insisto. Gracias por todo

Carlos Soto dijo...

Buen día, este ejemplo me ayuda mucho en mi proyecto, solo tengo la siguiente duda, si tengo registros que se repiten, a la hora de abrir el combobox me muestra toda la lista con todo y los repetidos, como haria para que, primero me ordene en orden asendente y depues no me muestre los registros repetidos? gracias de antemano, un saludo.

Javier Marco dijo...

Mírate este artículo donde hay 3 ejemplos, y uno de ellos te servirá para lo que pides: sacándoles provecho a los combobox