Está en la página 1de 14

GESTIÓN ALMACÉN1

INTRODUCCIÓN
Como bien indica su nombre, vamos a crear una aplicación
para gestionar los movimientos de un almacén. Sin
embargo, nuestra aplicación no sólo registrará entradas y
salidas, sino que, en el momento de sacar un producto, nos
dejará sacarlo siempre y cuando haya existencias del
mismo. Aprovechando la programación también avisaremos
si el stock queda por debajo de una cantidad “crítica”. De la
misma manera, podremos calcular el stock existente en el
momento actual.

El funcionamiento será muy sencillo (aunque la mecánica interna quizá no lo sea tanto).
Tendremos un formulario donde daremos recepción a los materiales que entren en el almacén,
y otro formulario que nos permitirá sacar los productos del almacén (no utilizaremos
subformularios para este ejemplo porque ello lo complicaría demasiado, pero si sois capaces de
adaptar el ejemplo funciona igual de bien).

Yo voy a utilizar, para el ejemplo, unos campos que considero mínimos, pero ello no es
obstáculo para que, lógicamente, en vuestra aplicación añadáis todos los campos que queráis.

La finalidad es que os quedéis con la idea de cómo puede ir Access controlando las salidas, y
de qué manera podemos conseguir un informe sobre el stock global o de un producto en
concreto.

Vámonos pues...

PLANIFICANDO NUESTRA APLICACIÓN


¿Qué vamos a necesitar? Los elementos mínimos de nuestra BD deberían ser los siguientes:

– Una tabla donde tengamos los productos → Con un formulario para darlos de alta
– Una tabla donde tengamos las entradas de productos → Con un formulario para dar de
alta dichas entradas.
– Una tabla donde tengamos las salidas de productos → Con un formulario para dar de
alta dichas salidas.
– Un formulario que nos haga de menú para “movernos” por la aplicación.
– Una serie de consultas (lo veremos más adelante)
– Un informe (más los que queramos) para ver el stock existente.

En principio, si no me dejo nada, con esto nos bastaría.

Vamos pues a ver cómo diseñamos las tablas.

CREANDO LAS TABLAS

Vamos a empezar por la tabla que recogerá la información de los productos. A esta tabla la
llamaremos TProductos. La creamos con la siguiente estructura:

1 La BD de ejemplo os la podéis bajar aquí.

1
Visítame en http://neckkito.eu5.org
IMPORTANTE

a) Punto 1

Fijaos que he puesto un autonumérico como identificador del registro. Lo he puesto así porque
he dado por supuesto que el código del producto será un código alfanumérico, y por ello he
tenido que crear el campo [CodProd], de tipo texto.

Poner un campo de tipo texto como clave principal no es recomendable, y sólo lo debemos
utilizar siempre y cuando no tengamos otra opción. Esto es simplemente un consejo.

Si nuestro código de producto fuera de tipo numérico no importaría incluir un autonumérico,


puesto que el propio código de producto nos serviría. En definitiva, que la estructura de la
tabla podría quedarnos así:

A medida que se vaya desarrollando el ejemplo, si utilizáis este segundo sistema, iré
remarcando las diferencias entre un sistema u otro.

b) Punto 2

Fijaos también que escribo los nombres de los campos sin espacios. Si vamos a programar os
recomiendo que no utilicéis espacios en los nombres. En el código, si el nombre no tiene
espacios, lo podemos escribir directamente; si tiene espacios lo deberemos enmarcar entre
corchetes (por ejemplo, [Codigo Producto].

Tampoco, en “elementos internos”, os recomiendo que utilicéis la acentuación gráfica, ni


caracteres “extraños” (como la letra eñe, la abreviatura de nº → esa º, etc.).

c) Punto 3

Quizá alguien pueda pensar, ¿y dónde está la cantidad para tener el stock? Como este va a ser
un dato variable no necesitamos almacenarlo en una tabla: una consulta nos servirá para crear
y obtener ese dato.

Sigamos con nuestras tablas: vamos a crear la tabla de las entradas de productos, que
llamaremos TEntradas. Tendrá la siguiente estructura:

2
Visítame en http://neckkito.eu5.org
Una vez la tengamos creada vamos a establecer una
relación con TProductos. Para ello nos situamos sobre el
campo [IdProd] y, en tipo de datos, seleccionamos
“Asistente para búsquedas”. Cuando se inicie el asistente lo
configuramos de la siguiente manera:

– Buscar los valores en una tabla


– Seleccionamos la tabla TProductos
– Seleccionamos todos los campos de la tabla
– Ordenamos por el campo que más útil nos sea. Yo he ordenado ascendente por la
descripción del producto.
– Ocultamos la columna clave y redimensionamos a nuestro gusto. Si utilizamos el campo
[CodProd] como clave principal, y nos interesa ver también el código del producto,
desmarcamos este check
– Dejamos la etiqueta que le habíamos puesto al campo
– Guardamos la tabla para que se generen las relaciones.

¿Qué hemos conseguido con esto? Pues hemos relacionado ambas tablas y ahora el valor que
se nos va a guardar en la tabla va a ser el valor recogido en la clave principal de TProductos, a
pesar de que, cuando vayamos a rellenar este campo, lo que veremos será los campos que
hemos dicho que se muestren en el asistente.

Cerramos la tabla.

Lo que vamos a hacer ahora, para ahorrarnos trabajo, es copiar la tabla TEntradas y guardarla
con el nombre de TSalidas. Una vez hecho esto la editamos y cambiamos su estructura así:

Guardamos la tabla.

Ahora, para ser puristas, deberíamos identificar las relaciones entre las tres tablas. Para ello:

– Sacamos la ventana “Relaciones” (doy por supuesto que sabéis dónde está)
– Mostramos tabla → Mostramos la tabla TSalidas
– De la tabla TProductos seleccionamos el campo [Id] y lo “arrastramos” sobre el campo
[IdProd] de TSalidas (si el campo clave utilizado es [CodProd] pues es este el que
arrastramos). En la ventana que nos sale aceptamos sin más2.

2 No entraremos, en este ejemplo, a explicar como definir a fondo las relaciones. En la web, en el apartado Objetos → Tablas, podéis
encontrar una explicación para este “asunto”.

3
Visítame en http://neckkito.eu5.org
Veremos que ambos campos se nos han unido por una línea: ya tenemos establecida la
relación.

Nos debería haber quedado una cosa así:

Y, en principio, nuestra estructura de tablas ya está creada.

CREANDO LOS FORMULARIOS DE TRABAJO


Basándonos en la tabla TProductos creamos un formulario para dar de alta los productos, que
llamaremos FProductos. En el encabezado del formulario vamos a insertar un botón de
comando. Le ponemos de nombre cmdCerrar3.

Vamos a programar ese botón. Sacamos sus propiedades y nos vamos a la pestaña Eventos →
Al hacer click, y generamos el siguiente código4:


Private Sub cmdCerrar_Click()
'Cerramos el formulario actual
DoCmd.Close acForm, Me.Name
'Abrimos FMenu
DoCmd.OpenForm "FMenu"
End Sub

Como vemos, el código nos cierra el formulario en el que estamos en ese momento (que será
FProductos) y nos abre el formulario FMenu, que aún no hemos creado pero que crearemos en
breve.

Por ejemplo, a mí me ha quedado una cosa así:

3 De ahora en adelante, si os indico “le ponemos de nombre”, me estaré refiriendo al nombre del control, no a su título. ¿Y cómo
ponemos nombre a un control? Sacamos sus propiedades y nos vamos a la Pestaña Otras → Nombre, y ahí le escribimos el nombre.
4 Para generar código nos ponemos en la parte en blanco junto al evento que queramos, y veremos cómo nos aparece un pequeño
botón de puntos suspensivos. Si hacemos click sobre él nos aparecerá una ventana. Le decimos que queremos generar código.
Se nos abrirá el editor de VB, con dos líneas por defecto (Private Sub... y End Sub). Esas dos líneas no deben tocarse. El código lo
escribimos entre dichas líneas

4
Visítame en http://neckkito.eu5.org
A continuación vamos a crear nuestro formulario FEntradas.
Para ello, lo creamos lógicamente sobre la tabla TEntradas.
En la cabecera del formulario vamos a repetir lo que hemos
hecho con FProductos, que es añadir un botón para cerrar
el formulario. Añadimos pues ese botón, le ponemos de
nombre cmdCerrar y le generamos el siguiente código en el
evento “Al hacer click” (ahora el código ya sin comentarios):


Private Sub cmdCerrar_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FMenu"
End Sub

NOTA: Con este formulario podremos dar entrada a los productos que ya estén dados de
alta, pero, así como lo tenemos, si el producto no está dado de alta... pues mal lo tenemos
(deberíamos salir del formulario, darlo de alta y volver a registrar la entrada). La solución a
este problema sería estudiar el ejemplo “Alta en form desde form” de la web y aplicar las
“enseñanzas” de ese ejemplo a nuestra aplicación.

NOTA: Si queremos ser muy puristas con el tema de diseño os recomiendo tener un simple
archivo txt (o algún sucedáneo de bloc de notas) para ir anotando los elementos que queremos
tengan un aspecto homogéneo en nuestra aplicación. Por ejemplo, si sacamos las propiedades
del botón cerrar y nos vamos a la pestaña Formato veremos dos propiedades, “Alto” y “Ancho”,
con unos valores. Si tomamos nota de esos valores podemos aplicar los mismos valores a
todos los botones cerrar que creemos (lo que nos libra de “dibujarlos” con cuidado) en el
momento de crearlos: dibujamos el botón a lo rápido y le establecemos los valores que
tenemos apuntados; el botón se redimensionará según esos valores. Lo mismo podríamos
hacer, por ejemplo, con las dimensiones del campo para el código de producto, el campo para
la fecha, etc.

A mí me ha quedado una cosa así:

5
Visítame en http://neckkito.eu5.org
Realizamos el mismo proceso, pero con un formulario
basado en la tabla TSalidas, que llamaremos FSalidas. No
creo que haga falta repetir cómo hacerlo. También le
incluimos un botón de comando para cerrar el formulario,
con el mismo nombre y código que los anteriores.

Finalmente, vamos a crearnos nuestro formulario FMenu.


Para ello, creamos un formulario en blanco. Vamos a
realizar, en principio, las operaciones siguientes:

1.- Creamos un botón de comando, que llamaremos cmdAltaProductos. Le asignamos, en el


evento “Al hacer click”, el siguiente código:


Private Sub cmdAltaProductos_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FProductos", , , , acFormAdd
End Sub

Si observáis el código veréis que el argumento acFormAdd lo que nos permite es abrir el
formulario preparado para la introducción de nuevos productos.

2.- Copiamos el botón que hemos creado y lo pegamos (CTRL+C / CTRL +V). Nos aparecerá
abajo. A este nuevo botón le ponemos de nombre cmdAltaEntradas y le generamos el siguiente
código:


Private Sub cmdAltaEntradas_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FEntradas", , , , acFormAdd
End Sub

3.- Copiamos este último botón y lo volvemos a pegar, para que nos aparezca abajo. A este
nuevo botón le ponemos de nombre cmdAltaSalidas y generamos el código:


Private Sub cmdAltaSalidas_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FSalidas", , , , acFormAdd
End Sub

NOTA: Si quisiéramos poder abrir el formulario, sin más, y navegar por los registros y
poder añadir registros nuevos la línea de código que abre el formulario sería, simplemente,

DoCmd.OpenForm "NombreFormulario"

Si quisiéramos abrir el formulario sólo para editar los datos, pero no poder añadir registros
nuevos, las líneas deberían ser:

DoCmd.OpenForm "FSalidas", , , , acFormEdit

6
Visítame en http://neckkito.eu5.org
Forms!FSalidas.AllowAdditions = False

Y si quisiéramos abrir el formulario sólo para consultar los registros (pero no poder editarlos o
añadir nuevos) la línea sería

DoCmd.OpenForm "FSalidas", , , , acFormReadOnly

Lógicamente, podríamos, en FMenu, crear tantos botones


como necesitáramos.

4.- Añadimos finalmente un último botón (por ahora) que nos


permitirá cerrar la aplicación. A ese botón lo llamaremos cmdQuit,
y su código sería:


Private Sub cmdQuit_Click()
DoCmd.Quit
End Sub

CREANDO NUESTRAS CONSULTAS


Hasta aquí tenemos una aplicación “normal”, en el sentido que ya es una aplicación totalmente
operativa. Sin embargo, el compromiso era gestionar el stock de productos. Así que para ello
vamos a auxiliarnos de unas consultas.

El “meollo “ del asunto radica en que vamos a necesitar un conjunto entrelazado de consultas
para poder llegar a los resultados previstos. Así pues...

1a.- Creamos una primera consulta, que llamaremos CEntradas, que nos va a dar la
información de todos los productos que han entrado. Es decir, creamos la consulta en vista
diseño y añadimos la tabla TProductos y la tabla TEntradas. Los campos [Id] e [IdProd]
deberían habernos salido unidos por una línea.

1b.- Nos situamos, con precisión, sobre esa línea de relación y hacemos click con el botón de la
derecha. En el menú emergente debería aparecernos una opción llamada “Propiedades de la
combinación”

Si hacemos click sobre esa opción nos aparecerá una ventana que nos pedirá el tipo de
combinación. Debemos marcar la tipo 2

7
Visítame en http://neckkito.eu5.org
¿Por qué hacemos esto? Para forzar a la consulta para que nos dé la información de todos los
productos que haya en la BD, independientemente de si han tenido algún movimiento de
entrada o no.

1c.- Arrastramos al grid de la consulta el campo [CodProd]. En la segunda columna del grid
vamos a escribir, en la primera línea (la correspondiente a “Campo:”), la siguiente expresión:

Entrada: SiInm(EsNulo([CantE]);0;[CantE])

En definitiva, esto:

Ya tenemos los datos como queríamos: todos los detalles de los productos que han salido y, si
no han salido, indicados con valor cero, que es lo que devuelve la función SiInm()

Guardamos la consulta.

2a.- Creamos una nueva consulta en vista diseño, que guardaremos con el nombre de
CEntradas2. Añadimos la consulta que acabamos de crear.

2b.- Añadimos los dos campos de que consta la consulta, y la convertimos en una consulta de
totales. En el campo [Entrada] indicamos que queremos agrupar por suma.

8
Visítame en http://neckkito.eu5.org
Guardamos la consulta.

Ahora vamos a hacer lo mismo, pero con los datos de la tabla TSalidas.

3a.- Creamos en vista diseño una consulta que llamaremos CSalidas, basada en la tabla
TProductos y TSalidas. Su diseño sería el siguiente:

Tened en cuenta que, como se muestra en la línea de relación, el tipo de combinación es la 2.

Por si no se ve claro, la expresión es:

Salida: SiInm(EsNulo([CantS]);0;[CantS])

3b.- Creamos una nueva consulta, basada en la consulta anterior, añadiendo los dos campos
que hay. Convertimos esa consulta en una consulta de totales y agrupamos el campo [Salida]
por suma.

9
Visítame en http://neckkito.eu5.org
4 a.- Creamos una última consulta, que estará basada sobre la tabla TProductos, CEntradas2 y
CSalidas2. Guardamos esa consulta con el nombre de CStock.

Hacemos click sobre el campo [CodProd] de <TProductos> y lo “arrastramos” sobre el mismo


campo en CEntradas2. Hacemos lo mismo con TProductos y CSalidas2. Se nos deberían crear
dos líneas de relación entre las tres tablas.

En el grid de la consulta vamos a añadir:

– El campo [Id] de TProductos. Si hemos utilizado [CodProd] como clave principal


lógicamente este campo no podríamos añadirlo.
– El campo [CodProd] de TProductos.
– El campo [DescProd] de TProductos
– El campo [SumaDeEntrada] de CEntradas2
– El campo [SumaDeSalida] de CSalidas2.

En la siguiente columna en blanco, en el grid, vamos a crear el campo calculado. Para ello, en
la línea superior (la correspondiente a “Campo:”) escribimos:

Stock: [SumaDeEntrada] – [SumaDeSalida]

10
Visítame en http://neckkito.eu5.org
CREANDO NUESTROS INFORMES
Vamos a crear un informe basado en CStock. Lo creamos a nuestro
gusto. Guardaremos ese informe como RStock.

Una vez tengamos ese informe creado lo situamos en vista


diseño. Vamos a “eliminar” (que no lo eliminaremos” el
campo [Id], porque es un campo de referencia interna y no
nos aporta ningún valor a nivel visual. Lo que haremos
será:

– Borrar su etiqueta
– Seleccionamos el campo [Id] y sacamos sus propiedades. Nos vamos a Pestaña
Formato → Visible, y ahí situamos la propiedad en NO. Una vez hecho esto podemos situar el
campo en algún rincón donde no moleste. Si no hemos utilizado este campo lógicamente no
hará falta realizar estas operaciones.

Arreglamos los detalles de diseño que queramos en ese informe. Por ejemplo, mi diseño final
ha quedado así:

Fijaos que no podéis ver mi campo [Id]. Ello es así porque está “escondido” detrás del campo
[CodProd] (si os fijáis bien se le ven “cuatro pelillos”... je, je...).

Cuando quede a nuestro gusto cerramos y guardamos el informe.

PROGRAMACIÓN DE FMENU
Vamos a situar nuestro formulario FMenu en vista diseño. Vamos a añadir un cuadro
combinado y un botón para poder abrir nuestro informe con toda la información o filtrado.

Así pues:

1.- Añadimos un cuadro combinado. Cuando se nos inicie el asistente lo configuramos de la


siguiente manera:

– Deseo buscar los valores en una tabla


– Seleccionamos la tabla TProductos

11
Visítame en http://neckkito.eu5.org
– Añadimos los tres campos que hay en esa tabla. Dos campos si no hemos utilizado [Id]
– Ordenamos por el campo que más nos interese (o
bien por [CodProd] o bien por [DescProd]), ascendente.
– Si hemos utilizado [Id] ocultamos la clave principal.
Si no hemos utilizado [Id] y no queremos ver el código de
producto (porque [CodProd] es nuestra clave principal),
pues ocultamos; si queremos ver el campo deberemos
desmarcar ese check. Redimensionamos a nuestro gusto.
– Como etiqueta podemos escribir algo como:
“Seleccione producto”

2.- Sacamos las propiedades del cuadro combinado y nos vamos a Pestaña Otras → Nombre, y
ahí escribimos cboProd

3.- Insertamos un botón de comando. Le ponemos de nombre cmdAbreRStock.

Por ejemplo, el diseño de estos dos controles yo lo he ideado así:

4.- En el evento “Al hacer click” de cmdAbreRStock generamos el siguiente código:


Private Sub cmdAbreRStock_Click()
'Declaramos las variables
Dim vProd As Long
'Cogemos el valor del combo
vProd = Nz(Me.cboProd.Value, 0)
'Si no hay valor devuelve el valor cero. En ese caso abrimos
'el informe sin más
If vProd = 0 Then
DoCmd.OpenReport "RStock", acViewPreview
Else
'Si hay valor abrimos el informe filtrándolo
DoCmd.OpenReport "RStock", acViewPreview, , "[Id]=" & vProd
End If
End Sub

Un par de comentarios:

– Si hemos utilizado [CodProd] como clave principal nuestra línea de código

DoCmd.OpenReport "RStock", acViewPreview, , "[Id]=" & vProd

debería ser

DoCmd.OpenReport "RStock", acViewPreview, , "[CodProd]=" & vProd

– El informe, con este código, se abre en vista preliminar. Si lo que queremos es enviarlo
directamente a la impresora debemos cambiar el argumento:

12
Visítame en http://neckkito.eu5.org
acViewPreview

por

acViewNormal

Y con esto nuestro formulario FMenu ya está listo para salir


del horno.

PROGRAMANDO FSALIDAS
Vamos a establecer un control en FSalidas, para evitar que podamos dar salida a un producto
que del cual no hay stock. Aprovecharemos para lanzar un mensaje de advertencia si quedan,
por ejemplo, 10 o menos unidades de ese producto.

1.- Situamos FSalidas en vista diseño. Seleccionamos el campo [CantS] y sacamos sus
propiedades. Nos vamos a Pestaña Eventos → Después de actualizar, y generamos el siguiente
código5:


Private Sub CantS_AfterUpdate()
'Declaramos las variables
Dim vProd As Long
Dim vCant As Integer, vCantStock As Integer
Dim rst As DAO.Recordset
'Cogemos el identificador del producto
vProd = Nz(Me.IdProd.Value, 0)
'Cogemos la cantidad introducida
vCant = Nz(Me.CantS.Value, 0)
'Si no hubiera cantidad introducida salimos del proceso
If vCant = 0 Then Exit Sub
'Creamos el recordset
Set rst = CurrentDb.OpenRecordset("CStock", dbOpenSnapshot)
With rst
'Nos situamos en el primer registro
.MoveFirst
'Iniciamos el recorrido de registros hasta encontrar la referencia
'con la que estamos trabajando en el formulario
Do Until .EOF
'Cuando lo encontramos...
If .Fields("Id").Value = vProd Then
'Cogemos el stock existente
vCantStock = .Fields("Stock").Value
'Le restamos la cantidad que estamos sacando
vCantStock = vCantStock - vCant
Select Case vCantStock
'Si el resultado es negativo no permitimos sacar esa cantidad
Case Is < 0
MsgBox "No hay stock suficiente de este producto" & vbCrLf & vbCrLf _
& "El stock actual del producto es " & vCantStock + vCant & _
" unidades", vbCritical, "SIN STOCK"
'Borramos la cantidad introducida
Me.CantS.Value = Null
'Es necesario hacer un rebote de foco para volver a situar
'el enfoque en CantS
Me.IdProd.SetFocus
Me.CantS.SetFocus
Exit Do
'Si queda stock, pero es inferior a 10 unidades, lanza un aviso
Case Is <= 10

5 El código utiliza DAO, por lo que debemos asegurarnos de que tenemos la referencia registrada. Para ello, en el editor de VB, nos
vamos a Menú Herramientas → Referencias, y debemos tener marcado el check de la librería “Microsoft DAO 3.6 Object Library”. Si
no la tuviéramos debemos buscarla, marcar su check y aceptar.

13
Visítame en http://neckkito.eu5.org
MsgBox "¡Atención! El stock que quedará de este producto es de " _
& vCantStock & " unidades", vbInformation, "STOCK CRÍTICO"
Exit Do
End Select
End If
.MoveNext
Loop
End With
'Cerramos conexiones y liberamos memoria
rst.Close
Set rst = Nothing
End Sub

Como veis el código está comentado y he intentado ir explicando lo que hace cada línea de
código.

Y ya tenemos, con esto nuestro FSalidas preparado para “supervisar” nuestras salidas y darnos
un “tirón de orejas” si intentamos sacar material que no existe.

Pues eso... Nuestra aplicación de gestión de inventario ya está totalmente operativa. Espero
que os sea de utilidad y que podáis adaptar algunas cosillas de las aquí explicadas a vuestras
aplicaciones.

Un saludo, y...

¡suerte!

14
Visítame en http://neckkito.eu5.org

También podría gustarte