Pequeño gran proceso

Estoy pasando a otra etapa de mis conocimientos en powre gracias a ti, y mi problema es el siguiente :
Tengo un proceso que hacer en power y la verdad es que no tengo mucha idea de como encararlo y se trata de lo siguiente :
Son 3 tablas
MOVIMIENTO (Contiene los datos para hacer movimientos a una determinada bodega)
SUS CAMPOS SON :
Tipo de movimiento (entrada o salida)
Numero de bodega
Cantidad (cant a sumar o restar)
Código producto (producto afectado)
ID_USUARIO
KARDEX :
Sus campos son
Código de producto (clave única)
Descripción del producto
BODEGA_1
BODEGA_2
BODEGA_3
Movimientos aceptados
Ídem a movimientos
Proceso :
Lee la tabla movimientos, busca el producto en la tabla kardex, si el tipo es E (Entrada), debe sumar la cantidad indicada a la bodega indicada en movimientos.
Si el tipo es salida (S), debe restar la cantidad indicada a la bodega correspondiente (bodega_1 bodega_2 o bodega_3) también indicada en movimientos.
Una vez procesado ese registro, debe ser grabado tal cual en tabla movimientos aceptados, y luego ir a leer otro registro de movimientos.
Una vez que haya finalizado con la lectura de todos los registros de movimientos, estos deben ser borrados.
El proceso en realidad tiene otras complejidades como por ejemplo, procesar solo registros de un usuario indicado, no borrar aquellos en donde la cantidad a sacar no tiene saldo suficiente en el kardex.
Pero me conformo con que me des una idea de como hacerlo.
1

1 Respuesta

107.925 pts. clipper todas sus versiones (manejo total) power...
Mi propuesta es la siguiente.
Primero y para no tener conflictos con el objeto de conexión, creas un datawindow object.
En el cual determines por ejemplo la carga del maestro de artículos
Una vez construido este datawindow, creas una instancia de un datastore, y asignas el datawindow object a el datastore.
Ahora por medio de un ciclo controlado FOR, recorres uno a uno secuencialmente cada elemento del datastore, y por cada registro haces una sumatoria de las entradas y las salidas, las cuales depositas en 2 variables distintas y la diferencia la asignas a la tabla que necesitas.
Digamos algo así: (asumo que ya tienes el datawindow object. Digamos que tiene el nombre de dw_mae_articulos, igualmente asumo que el código del producto es numérico)
DATASTORE lds_local
LONG ll_retrieve
LONG ll_for
DECIMAL{0} ldc_producto
DECIMAL{0} ldc_entradas
DECIMAL{0} ldc_salidas
DECIMAL{0} ldc_existencia
STRING ls_error
BOOLEAN lb_commit
lds_local = CREATE DATASTORE
lds_local.dataobject = 'dw_mae_articulos'
lds_local.settransobject(SQLCA)
ll_retrieve = lds_local.retrieve()
FOR ll_for = 1 to (lds_local.ROWCOUNT())
ldc_producto = lds_local.GetItemDecimal(ll_for, 'producto')
SELECT SUM(ISNULL(CANTIDAD, 0))
INTO :ldc_entradas
FROM MOVIMIENTOS
WHERE (PRODUCTO = :ldc_producto)
AND (TIPO_DE_MOVIMIENTO = 'E')
USING SQLCA;
SELECT SUM(ISNULL(CANTIDAD, 0))
INTO :ldc_entradas
FROM MOVIMIENTOS
WHERE (PRODUCTO = :ldc_producto)
AND (TIPO_DE_MOVIMIENTO = 'S')
USING SQLCA;
ldc_existencia = (ldc_entradas - ldc_salidas)
UPDATE MOVIMIENTOS_ACEPTADOS
SET CANTIDAD = :ldc_existencia
WHERE (PRODUCTO = :ldc_producto)
USING SQLCA;
lb_commit = ((SQLCA.SQLCode = 0) AND (SQLCA.SQLCADBCode = 0))
ls_error = SQLCA.SQLErrText
IF lb_commit THEN
COMMIT USING SQLCA;
ELSE
ROLLBACK USING SQLCA;
MESSAGEBOX('ERROR', ls_error)
EXIT
END IF
NEXT
DESTROY lds_local;
En el script anterior, como veras recorre la tabla de productos uno a uno, suma los totales de las entradas y las salidas, y actualiza en la tabla de movimientos aceptados, en caso de no hacer una actualización simplemente reemplázalo por una instrucción INSERT
El resto del script casi te puedo asegurar que funcionará.
Sin embargo esto lo he hecho a ojo de buen cubero, si algún error provoca el correspondiente, entonces con mucho gusto lo corrijo.
Gracias, vamos por buen camino, pero el resultado que debo lograr es el siguiente :
La tabla movimientos ya esta digitada y los datos los tengo en pantalla en una DW, el kardex es una tabla que ya existe y en cuyos campos bodega_1, bodega_2 o bodega_3 debo mantener los saldos, y la tabla movimientos_aceptados también existe.
La idea es recorrer la tabla movimiento, leer su contenido, con el dato código (string) del producto, busco en kardex, al encontrarlo debo sumar al campo bodega_1 o bodega_2 o bodega_3 (depende de que bodega indica el campo numero de bodega de movimientos) la cantidad indicada del campo cantidad de movimientos, se suma o se resta dependiendo del tipo si es E o S.
Y a medida que va leyendo cada registro, este debe ser grabado en movimientos aceptados y luego borrado para no ser nuevamente procesado.
Espero haberte aclarado más el tema.
Te hago el algoritmo con palabras :
Área movimientos
Voy a inicio
Leo registro
Busco en kardex
Si tipo movimiento=E incremento campo del kardex, dependieno del numero de bodega indicada en movimientos:
bodega_x=bodega_x+cantidad
else
digo bodega_x=bodega_x-cantidad
Grabo el registro en tabla movimientos_aceptados
Elimino el registro de movimientos
Leo el siguiente hasta terminar el bucle.
Espero haberte aclarado como debe ser el proceso,
Gracias y por favor tenme paciencia
Me parece bien, con respecto a lo actualizar, te adelanto un poco, power builder en su datawindow contiene 2 eventos, uno es UPDATESTART() y el otro UPDATEEND(), cada uno es disparado en el inicio y el fin de las actualizaciones.
Se me ocurre que aquí puedes introducir el área adicional que en este caso será la actualización de tus bodegas. De tal forma que cuando pulses el botón actualizar y ejecute simplemente
dw_1.update()
(Por suponer algo, aunque faltan un par de lineas más)
Esto active el evento updatestart(), y dentro de este puedas actualizar tus almacenes leyendo tu datawindow secuencialmente, sin aun todavía hacer un commit, sino que añadiendo los pendientes a la transacción global
Y con mucho gusto veo el script del botón actualizar.
Muchas gracias, te recuerdo que soy nuevo en el tema, y muy pronto te enviare mi propuesta de script para tus observaciones.
OK OK OK, La única diferencia es que yo permito ingresar varios registros, y una vez revisados (pueden ser 1 o 10 o 20 o 50) con el botón procesar, actualizo el kardex con las existencias.
¿Qué te parece si hago yo la programación del botón procesar y te la envío en una nueva pregunta y tu me haces tus aportes?
Disculpa mi insistencia, y lo hago, porque confío mucho en tu capacidad. Lo que pasa es que la tabla de movimientos es solo de paso y se usa solo para digitar, luego en el proceso es leída para modificar saldos del kardex, y cada registro leído, se graba en otra tabla llamada movimientos aceptados. Te doy otro ejemplo (la verdad es que los tipos de movimientos los resumí en E y ES, pero en realidad son más )
Tabla movimientos
Tipo código cantidad bodega
11 RIA0101 10 1
11 RID0101 5 1
21 RIF0101 4 1
Leo el primer registro, busco en kardex, debo sumar 10 a la bodega 1
segundo registro, debo sumar 5 a la bodega 1
tercer registro, debo restar 4 a la bodega 1
al leer y procesar cada registro, lo voy grabando tal cual en la tabla movimientos aceptados y luego lo borro.
Ahora te explico por que los tipos reales son números y no (e o s), lo que pasa que del 11 al 19 son entradas y del 21 al 29 son salidas, y según el numero, aparte de incrementar o restar, debe hacer otro calculo con el producto como por ejemplo promediar el costo etc. en las preguntas anteriores yo mencionaba solo tipos e y s, solo para simplificar el tema.
Espero que ahora entiendas mi intentar, pero si te causo muchos problemas, solo me avisas y cerramos la pregunta y de todas maneras quedare agradecido por tus aportes.
Gracias
Es posible que creas que no estoy sintonizado con tu pregunta, pero considero que tener de base la tabla de movimientos, te va a ser más complicado para el proceso que pretendes, pues según entiendo esta tabla contiene todos los movimientos del articulo.
Por lo que aquí vas a encontrar cualquier cantidad de lineas o registros.
Tendrás que hacer un proceso que lea todas las lineas y las clasifique por código para sumar las que corresponden con un articulo en especial.
Creo que si cambias tu planteamiento, deberías utilizar una tabla piloto, en donde el numero de repeticiones sea mínima, digamos ninguno.
Por ejemplo la tabla maestra de artículos.
Aquí no creo que tendas lineas con código dubplicado, entonces la idea es recorrer el maestro de artículos en forma secuencial desde el principio hasta el final.
Por cada uno lees los movimientos y sumas entradas y salidas por separado,
luego en una variable incluyes la operación de restas salidas a entradas y esta la asignas a la existencia en la bodega o bodegas que necesites.
La sumatoria puede ser descriminada por bodega (por ejemplo), eso si esta se encuentra integrada en su tabla de movimientos.
Cuando finalice el proceso la actualización que necesitas se encontrara hecha
Por cierto,
Cuando hagas una acción de UPDATE, te recomiendo efectúes inmediatamente, una acción de COMMIT, o en su caso de error ROLLBACK y por supuesto en este ultimo abortar el proceso.
Lo que sucede es que tu base de datos guarda un espacio determinado para actualizaciones, y este puede llegar a saturarse si intentas hacer una actualización hasta el final.
Perona si insisto pero creo que la solución esta en cambiar tu planteamiento de información base.
Hola, para reforzar lo anterior te detallo para que uso cada tabla :
MOvimientos : Se usa para la digitación de los mismos.
Kardex : Es el maestro de productos, contiene descripciones, precios y saldos.
Movimientos aceptados : Contiene el detalle de todos los movimientos que pasan las validaciones, desde esa tabla obtengo los detalles de los movimientos (todas las entradas y salidas de cada uno)
Muchas gracias por atenderme.
No quiero ser mal interpretado, con mucho gusto tienes mi respaldo, te propongo ahora una opción, si esta no se acerca a lo que necesitas, sino te importa cierras esta pregunta e iniciamos una nueva.
Bien entiendo entonces (perdona pero estoy tratando de imaginarlo), que la integración de los datos en la tabla de movimientos es manual.
Cada vez que un registro de datos es asentado necesitas actualizar tus bodegas.
Espero ahora dar en el blanco.
Bien, imagino que para grabar tienes un proceso, por ejemplo un botón que ponga grabar.
Cuando grabas el registro es el momento en el que puedes hacer tu actualización.
Y dependiendo del valor del movimiento simplemente añades o restas
podrias por ejemplo utilizar una instruccion CASE
digamos
CHOOSE CASE tipo_movimiento
CASE 1, 2, 3, 4, 5
Actualiza sumando
...
...
...
CASE 20, 21, 22, 23, 24
Actualiza restando
...
...
...
END CHOOSE
La ventaja de hacer esto en el momento de la actualización, es que puede integrar toda tu actualización en una sola transacción
y con esta, garantizar que la transacción es acentada completamente o rechazada completamente.
Por ultimo, mantengo lo que al principio expongo, puedes contar conmigo, sin embargo creo conveniente no hacer tan largas
las preguntas por cuestión de limitaciones de la página.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas