Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Segundo Post Dedicado A Excel
Segundo Post Dedicado A Excel
Hoy me he levantado muy temprano y de buen humor. Y es por eso mismo que en vez de
meterle mano al formulario del post anterior, he decidido brincarme todo el rollo y publicar una
propuesta de un archivo que nos permita imprimir una factura, incluyendo su modulo de
clientes y productos.
Antes de empezar, la configuracion de mi pc:
- Windows Home Basic.
- Office 2010
Consideraciones - el codigo VBA es el mismo de Visual basic 6, por lo que debe funcionar
tambien en versiones anteriores a excel 2010. De todos modos, el codigo que vamos a escribir
sera de lo mas sencillo para brincar esa cuestion. Se podria escribir un codigo bastante robusto
y optimo pero eso incrementaria las lineas al triple y podria causar confusion a los lectores
novatos en programacion.
En el post anterior tenemos un ejemplo de como insertar datos en hoja desde un formulario.
Esa es la misma mecanica que vamos usar, con la unica diferencia que ahora vamos a leer
datos de la hoja y a pasarlos al formulario.
FORMATEANDO LAS HOJAS
bueno, tons, primero abre excel y de inmediato guardas el libro como factura.xls o factura xlsm.
en excel 2010 debes guardarlo como libro con ejecucion de macros ( xlsm )
en 2007 creo que solo tienes que habilitar las macros.
en anteriores a 2007 da igual.
ahora, el libro nos crea automaticamente 3 hojas. vamos a cambiarles el nombre como sigue:
hoja1 = clientes
hoja2 = productos
hoja3 = facturas
bien, ahora inserta una hoja mas y le pones el nombre de impresion
la hoja productos
A1 = clave, B1 = descripcion, C1 = precio
ingresale unos cuantos datos
la hoja facturas
A1 = factura, B1 = fecha, C1 = razon, D1 = descripcion, E1 = precio, F1 = cantidad, G1 = total
Guarda el archivo para que no pierdas los cambios, (murphy dice que windows solo falla
cuando tienes algo sin guardar en pantalla)
DISEO DE LOS FORMULARIOS
Pulsa ALT + F11 y se abre la ventana de VBA.
la creacion de formularios e insercion de controles tambien sera omitida, pues esta en el post
anterior.
los prefijos que vamos a usar para los controles son:
lbl = etiqueta o label
txt = cuadro de texto o textbox
cmb = cuadro combinado o combobox
lst = cuadro de lista o listview
grb = marco o frame (grb de groupbox, no se nota la influencia de .net)
chk = casilla de verificacion o checkbox (el cuadrito que le pones o quitas una palomita)
Quiero hacer notar que existe un control grid que facilita la tarea de almacenar datos, pero
dado que hay que encontrar su referencia, y a que tambien varia su uso, ubicacion y existencia
con el uso de cada version de windows, no lo vamos a usar.
No vamos a agregar ningun control externo para hacer mas compatible este archivo entre
ordenadores con diferentes sistemas operativos.
bueno, una vez aclarados los puntos anteriores, vamos por el form mas culero:
FACTURACION
- agrega un nuevo formulario y le pones el nombre de frmFacturacion y caption
IMPRESION DE FACTURA
- ahora inserta 4 cuadros de lista afuera y por debajo del grbDatos Cliente con los siguientes
atributos
lstCantidad con width = 54 y height = 162
lstDescripcion con width = 227.25 y height = 162
lstPrecio con width = 67.55 y height = 162
lstImporte con width = 77.25 y height = 162
en el orden de creacion, ubicalos a la misma altura uno junto de otro.
ademas, inserta una etiqueta arriba de cada lista para que el usuario sepa que contiene cada
columna:
arriba de lstCantidad pones una lblCantidad con caption Cantidad
arriba de lst Descripcion pones un lblDescripcion con caption descripcion
y asi con las otras dos listas restantes.
-Agregar un boton de comando llamado cmdBuscar con caption = Buscar Cliente y lo ubicamos
en la parte de mas abajo del formulario a la izquierda.
-agrega un boton de comando llamado cmdProductos con caption = Productos y ubicalo a la
derecha de cmdBuscar
-agrega un boton de comando llamado cmdAceptar con caption = Aceptar y ubicalo a la
derecha de cmdProductos
-agrega una casilla de verificacion o checkbox con nombre chkImprimir y caption = Imprimir al
aceptar y ubicala a la derecha de cmdCancel
este es el aspecto final que deberia tener el formulario:
programar.
- escoge el control UserForm (osea, el formulario)
- VBA te va a insertar el encabezado y final del evento activate. Las lineas de codigo que
pongamos en ese espacio se van a ejecutar cuando formulario se active.
las lineas de abajo del evento click las podemos eliminar para no causar confusion.
y bueno, escribimos dentro del evento activate del formulario las siguientes lineas:
Private Sub UserForm_Activate()
Me.txtFecha.Text = Date
End Sub
a continuacion pulsa F5 y verifica que en el txtFecha se ha escrito la fecha automaticamente.
si hasta aqui todo va bien, continuamos con los eventos de los demas controles como sigue:
control cmdAceptar, evento Click
Private Sub cmdAceptar_Click()
If MsgBox( finalizar la captura de la factura?", vbQuestion + vbYesNo) = vbNo Then Exit Sub
guardarFactura
MsgBox (chkImprimir.Value)
If Me.chkImprimir.Value = True Then ImprimirFactura
End Sub
control cmdBuscar, evento Click
Private Sub cmdBuscar_Click()
frmBuscarCliente.Show ' mostrar el formulario de buscar clientes
End Sub
control cmdProductos, evento Click
Private Sub cmdProductos_Click()
frmAgregarProducto.Show ' mostrar el formulario de agregar productos
End Sub
control UserForm, evento activate
Private Sub UserForm_Activate()
Me.txtFecha.Text = Date ' para poner la fecha cuando se ejecute el form
End Sub
'-- al final de la ventana de codigo, vamos a crear tres procedimientos que no estan ligados al
evento de ningun control, y que pueden ser ejecutados cuando se requiera, aun sin ejecutar
ningun evento.
Public Sub sumarImporte() ' suma solo la ultima lista, osea, los importes
Dim i As Integer
lblClientes en la parte mas arriba, luego abajo el cmbClientes y abajo de este pones el
cmdAceptar.
los eventos:
control cmdClientes, evento Change
Private Sub cmbClientes_Change()
Cells.Find(What:=Me.cmbClientes.Text, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
End Sub
control cmdAceptar, evento Click
Private Sub cmdAceptar_Click()
With frmFacturacion
.txtRazon.Text = ActiveCell.Value
.txtRFC.Text = ActiveCell.Next.Value
.txtDireccion.Text = ActiveCell.Next.Next.Value
End With
Unload Me
End Sub
control UserForm, evento Activate
Private Sub UserForm_Activate()
Dim sUltimaCelda As String
Me.cmbClientes.Clear
Sheets( CLIENTEs ).Activate
If Trim(Range( A2 ).Value) = "" Then Exit Sub
If Trim(Range( A3 ).Value) = "" Then
Me.cmbClientes.AddItem (Range( A2 ).Value)
Exit Sub
End If
sUltimaCelda = Range( A1 ).End(xlDown).Address
For Each f In Range( A2:" & sUltimaCelda).Cells
Me.cmbClientes.AddItem (f.Value)
Next
End Sub
asi se debe ver en la ventana de codigo
Me.cmbClave.ListIndex = -1
Me.cmbClave.SetFocus
End Sub
Private Sub txtCantidad_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
' esto es para que el textbox solo acepte numeros
If KeyAscii < 48 Or KeyAscii > 57 Then
KeyAscii = 0
End If
End Sub
Private Sub UserForm_Activate()
Dim sUltimaCelda As String
Me.cmbClave.Clear
Sheets( PRODUCTOS" ).Activate
If Trim(Range( A2 ).Value) = "" Then Exit Sub
If Trim(Range( A3 ).Value) = "" Then
Me.cmbClave.AddItem (Range( A2 ).Value)
Exit Sub
End If
sUltimaCelda = Range( A1 ).End(xlDown).Address
For Each f In Range( A2:" & sUltimaCelda).Cells
Me.cmbClave.AddItem (f.Value)
Next
End Sub
- aqui estan las capturas pa que vean la identacion
ahora, hay que agregar un procedimiento mas al formulario de facturacion, ese procedimiento
sera el encargado de que por cada producto que se encuentre en la factura, sus existencia sea
descontada de la hoja.
ese procedimiento es sencillo:
Private Sub descontarExistencia(ByVal sDescripcion As String, ByVal nCantidad As Integer)
Dim sUltimaCelda As String
Dim hojaActiva As String
hojaActiva = ActiveSheet.Name ' para recordar la hoja activa
Sheets("PRODUCTOS" ).Activate ' nos pasamos a la hoja de productos
' aqui nomas fijamos los rangos, pa que no marque error si no hay nada en la lista
If Trim(Range("b2" ).value) <> "" Then
sUltimaCelda = Range("b1" ).End(xlDown).Address
Else
sUltimaCelda = "b2"
End If
'seleccionamos el rango de busqueda, para hacer mas rapido el proceso
Range("b2:" & sUltimaCelda).Select
' esto es para localizar la clave que nos interesa... mmm estoy pensando que
' esta parte deberia ser mas corta.
Selection.Find(What:=sDescripcion, After:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
' una vez localizada la clave, solo hacemos la resta
With Me
ActiveCell.Next.Next.value = Val(ActiveCell.Next.Next.value) - nCantidad
End With
'finalmente, regresamos a la hoja anterior, esto es para evitar errores
ActiveWorkbook.Sheets(hojaActiva).Activate
End Sub
' aqui esta la pantalla pa que vean la identacion
Next
End Sub
- quiero aprovechar para agradecer las 7000 visitas y sus putos 63 puntos, aunque con el
karma eso ya vale madres.