Procedimiento perteneciente al modulo de productos terminados y asignado a las dos rejillas, al evento DobleClick:procedure TfrmProductosTerminados.db_grid_relacion_pt_mpDblClick(
Sender: TObject);
var
Relaciones: TFrmRelaciones;
begin
// creamos la ventana dinámicamente
Relaciones:= TFrmRelaciones.Create(Self);
// cerramos las tablas de relacion asignadas a las rejillas.
// De esa manera garantizamos la actualización al cerrar la ventana creada
Modulo1.DS_tabla_relacion_pt_mp.DataSet.Close;
Modulo1.DS_tabla_relacion_pt_pe.DataSet.close;
try
// la visualizamos impidiendo devolver el foco de control mientras no se cierre
Relaciones.showModal;
finally
//liberamos la memoria asignada a la variable. El proceso queda garantizado
// mediante el uso de finally
Relaciones.Free;
with Modulo1 do // con el modulo de datos que recoge todas las tablas
begin
// procedemos de nuevo a la apertura al transferir de nuevo el control a los productos terminados
DS_tabla_relacion_pt_mp.DataSet.Open;
DS_tabla_relacion_pt_pe.DataSet.Open;
// si esta en estado de edición o de inserción
if DS_tabla_productos_maestra.state in [dsInsert, dsEdit] then
//recalculamos los campos calculados
tabla_productos_maestraCalcFields(DS_tabla_productos_maestra.DataSet)
else // en caso contrario
begin
// ponemos la tabla en estado de edición para poder recalcular los campos calculados
DS_tabla_productos_maestra.DataSet.Edit;
// efectuamos el calculo
tabla_productos_maestraCalcFields(DS_tabla_productos_maestra.DataSet);
// volvemos a poner la tabla en el estado inicial que el de Visualización
DS_tabla_productos_maestra.DataSet.CheckBrowseMode;
end;
end; // endBegin with…do
end;// endTry
end;
La idea es la siguiente: al crear la ventana, iremos rellenando los tres TListView que intervienen. Uno para las materias primas, otro para los procesos especiales y un tercero para las materias primas y procesos especiales ya asignados al producto. Una vez que es activada la ventana debemos permitir mediante arrastre rellenar el tercer ListView. El usuario arrastrará un icono de las materias primas a dicho contenedor. Finalizado el proceso de arrastre, visualizará un cuadro de edición para rellenar la cantidad de materia prima asignada al producto. De igual forma con los procesos especiales.
En el caso de error al asignar puede con el ratón arrastrar el icono a la papelera.
Cuando finalmente, se cierra la ventana (que era modal) el procedimiento OnClose se encarga de grabar a las tablas de relación las distintas asignaciones efectuadas, incluyendo la cantidad insertada.
Dado que pueden existir miles de materias primas, incorporamos el filtro del campo categorías y un cuadro de edición para la búsqueda rápida, mostrándonos tan solo aquellos items que cumplan dichas condiciones.
Un proceso rápido y cómodo para el usuario.
Codigo del Modulo frmRelaciones:
unit Relaciones;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ExtCtrls, ComCtrls, Db, DBTables, CheckLst, ImgList;
type
TfrmRelaciones = class(TForm)
panHerramientas: TPanel;
labRegistro: TLabel;
lvw_materiasprimas: TListView;
labMateriasPrimas: TLabel;
DS_ConsultaRelaciones: TDataSource;
lvw_procesosespeciales: TListView;
labProcesosEspeciales: TLabel;
DS_enlacept: TDataSource;
Consulta_Relaciones: TQuery;
chklbx_categoria: TCheckListBox;
labCategoria: TLabel;
lvw_destino: TListView;
Image1: TImage;
Button1: TButton;
Button2: TButton;
imglst_3232: TImageList;
imglst_1616: TImageList;
Button3: TButton;
Button4: TButton;
ediCategoria: TEdit;
Label1: TLabel;
ediCodigoMateprim: TEdit;
labRotuloCategoria: TLabel;
labRotuloCodigo: TLabel;
panCantidad: TPanel;
labCantidad: TLabel;
labRotulo: TLabel;
ediCantidad: TEdit;
procedure FormShow(Sender: TObject);
procedure lvw_destinoDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure lvw_destinoDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure ediCategoriaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure ediCategoriaKeyPress(Sender: TObject; var Key: Char);
procedure Image1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure Image1DragDrop(Sender, Source: TObject; X, Y: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ediCantidadExit(Sender: TObject);
procedure ediCantidadKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure ediCantidadKeyPress(Sender: TObject; var Key: Char);
procedure lvw_destinoMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmRelaciones: TfrmRelaciones;
implementation
uses shellapi;
{$R *.DFM}
{En este procedimiento, correspondiente a la asignación del evento OnShow de la ventana procederemos al relleno de los distintos TListView y la nota de despiece asignada a la categoría. Podemos observar, que puesto que la ventana se visualiza de forma Modal nos da absolutamente igual que todo este código perteneciera al evento OnCreate o al OnActivate puesto que no va a perder el foco y dichos eventos tan solo se producirán una sola vez en la vida de la ventana.}
procedure TfrmRelaciones.FormShow(Sender: TObject);
var
F: TextFile;
NombreFichero: String;
begin
// asignamos a la casilla de edición el valor del campo categoría de la tabla de productos terminados
ediCategoria.text:= ds_enlacept.DataSet.fields[9].asString;
//Rellenamos el listview de Materias Primas
{Utilizaremos un TQuery para extraer los datos de las tablas y añadir un elemento en el TListview por cada uno de los registros. Este TQuery será utilizado en todas las tablas cambiando los parámetros de SQL.strings}
with consulta_Relaciones do
begin
Sql.clear; // vaciamos los strings
Close;
// seleccionamos la tabla y los campos
Sql.Add(‘Select COD_MATPRIM from MATERIASPRIMAS’);
// con la condición de que el campo categoría sea el del producto elegido
Sql.Add(‘Where CATEGORIA = ‘ + ds_enlacept.DataSet.fields[9].asString);
Sql.Add(‘order by COD_MATPRIM’); // la ordenamos
Open;
First; // vamos al primer registro
end;
while not consulta_Relaciones.eof do // mientras hayan registros
begin
with lvW_materiasprimas.items.add do // añadimos un item
begin
//asignamos al titulo del icono el valor del código de la materia prima
Caption:= Consulta_Relaciones.fields[0].asString;
ImageIndex:= 0; // utilizamos como imagen la asignada con índice 0
end;
Consulta_Relaciones.next; // siguiente registro mientras no llegue al final
end;
{Ahora efectuamos el mismo proceso pero con los registros de la tabla de procesos especiales. Estos procesos son independientes de la categoría del producto }
//Rellenamos el listview de Procesos Especiales
with consulta_Relaciones do
begin
Sql.clear; // vaciamos los strings
Close;
// selecionamos la tabla y los campos
Sql.Add(‘Select CODIGO_PROC_ESP from PROCESOS_ESPECIALES’);
Sql.Add(‘order by CODIGO_PROC_ESP’); // la ordenamos
Open;
First; // vamos al primer registro
end;
while not consulta_Relaciones.eof do // mientras hayan registros
begin
with lvw_ProcesosEspeciales.items.add do // añadimos un item
begin
//asignamos al titulo del icono el valor del código de proceso.
Caption:= Consulta_Relaciones.fields[0].asString;
ImageIndex:= 1; // utilizamos como imagen la asignada con índice 1
end;
Consulta_Relaciones.next; // siguiente registro mientras no llegue al final
end;
//Rellenamos el listview de Productos Terminados
// primero con las materias primas
with consulta_Relaciones do
begin
Sql.clear; // vaciamos los strings
Close;
// seleccionamos la tabla y los campos
Sql.Add(‘Select * from RELACION_PT_MP‘);
// con la condición de que el campo código del producto sea el del producto elegido. Se filtran solo aquellos materias primas que correspondan a ese producto
Sql.Add(‘Where CODIGO_PROD_TER = ‘ + Chr(39)+ ds_enlacept.DataSet.fields[0].asString + Chr(39));
Sql.Add(‘order by CODIGO_MATEPRIM’); // la ordenamos
Open;
First; // vamos al primer registro
end;
while not consulta_Relaciones.eof do // mientras hayan registros
begin
with lvW_destino.items.add do // añadimos un item
begin
//asignamos al titulo del icono el valor del código de materia prima.
Caption:= Consulta_Relaciones.fields[2].asString;
ImageIndex:= 0; // utilizamos como imagen la asignada con índice 0
// añadimos como subitem la cantidad existente en el campo [3] que es precisamente la cantidad de materia primas asignada a ese producto
SubItems.Add(Consulta_Relaciones.fields[3].asString);
end;
Consulta_Relaciones.next; // siguiente registro mientras no llegue al final
end;
//Ahora con los procesos especiales
with consulta_Relaciones do
begin
Sql.clear; // vaciamos los strings
Close;
// seleccionamos la tabla y los campos
Sql.Add(‘Select * from RELACION_PT_PE‘);
// con la condición de que el campo código del producto sea el del producto elegido. Se filtran solo aquellos procesos especiales que correspondan a ese producto
Sql.Add(‘Where CODIGO_PROD_TER = ‘ + Chr(39)+ ds_enlacept.DataSet.fields[0].asString + Chr(39));
Sql.Add(‘order by CODIGO_PROCESOS_ESP’); // la ordenamos
Open;
First; // vamos al primer registro
end;
while not consulta_Relaciones.eof do // mientras hayan registros
begin
with lvW_destino.items.add do // añadimos un item
begin
//asignamos al titulo del icono el valor del codigo de proceso.
Caption:= Consulta_Relaciones.fields[2].asString;
ImageIndex:= 1; // utilizamos como imagen la asignada con índice 1
// añadimos como subitem la cantidad existente en el campo [3] que es precisamente la cantidad de proceso asignada a ese producto
SubItems.Add(Consulta_Relaciones.fields[3].asString);
end;
Consulta_Relaciones.next; // siguiente registro mientras no llegue al final
end;
// visualizamos en la etiqueta superior el código del producto terminado sobre el que estamos realizando las asignaciónes
labRegistro.Caption:= ds_enlacept.DataSet.fields[0].asString;
// visualizamos en la etiqueta de categoría la asignada a ese producto en concreto
labCategoria.caption:=’CATEGORIA: ‘ + ds_enlacept.DataSet.fields[9].asString;
{vaciamos todo el contenido del CheckListBox. Este componente nos ayudará a mostrar al usuario el despiece habitual correspondiente a dicha categoría y que tan solo servirá como guía para realizar las asignaciones. Este listado será creado por el usuario y será almacenado en un fichero de texto y será único por cada categoría. Abrimos también la posibilidad, al tener la funcionalidad del checkbox, para futuros usos no previstos.}
chklbx_categoria.Items.clear;
// si exite el fichero éste es cargado
if FileExists(ExtractFilePath(Application.exename) +
‘CATEGORIA_’ +
ds_enlacept.DataSet.fields[9].asString +
‘.TXT’) then
chklbx_categoria.Items.LoadFromFile(ExtractFilePath(Application.exename) +
‘CATEGORIA_’ +
ds_enlacept.DataSet.fields[9].asString +
‘.TXT’)
else // en el caso de que no exista
begin
// visualizamos un cuadro de diálogo y le preguntamos si desea crearlo
if Messagedlg(‘El fichero ‘ +
ExtractFilePath(Application.exename) + ‘CATEGORIA_’ +
ds_enlacept.Dataset.fields[9].asString + ‘ no existe: ‘ + #10 +
‘¿Desea crearlo…?’, mtWarning, [mbOk, mbCancel], 0) = mrOk then
begin
NombreFichero:= ExtractFilePath(Application.exename) + ‘CATEGORIA_’ + ds_enlacept.DataSet.fields[9].asString + ‘.TXT’;
AssignFile(F, NombreFichero); // Asignamos la variable F al nombre del fichero
try
Rewrite(F); // Inicializamos para escribir sobre el
Append(F); // Preparamos el acceso a la escritura
Writeln(F, ‘ESCRIBE EN ESTE LUGAR LA LISTA CORRESPONDIENTE A ESTA CATEGORIA.’); // y escribimos la primera linea
finally
CloseFile(F); // liberamos la variable
end;
// abrimos el fichero con el programa asociado
ShellExecute(handle,
‘open’,
PChar(NombreFichero),
nil,
nil,
SW_SHOWNORMAL);
// rellenamos los items de la chuleta
chklbx_categoria.Items.LoadFromFile(NombreFichero);
end;
end;
end;
{Este procedimiento es empleado para aceptar el icono arrastrado sobre el tercer ListView tan solo si dicho objeto pertenece a la clase TListView. Utilizamos el operador IS, que como sabéis es utilizado en las Clases para saber si pertenece o no pertenece}
procedure TfrmRelaciones.lvw_destinoDragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
begin
// podemos ver el detalle de que dicha aceptación no esta restringida a que el objeto pertenezca a cualquiera de los TListView, incluso a si misma.
if source is TListView then
Accept:= true
else
Accept:= False;
end;
{Procedimiento de arrastre}
procedure TfrmRelaciones.lvw_destinoDragDrop(Sender, Source: TObject; X,
Y: Integer);
begin
if source is TListView then // si el origen es de la clase TListView
begin
with TListView(sender).Items.add do // utilizamos la variable sender para saber sobre que contenedor es soltado y añadimos un item al mismo
begin
// rellenamos su caption con el caption del elemento arrastrado
caption:= TListview(source).Selected.Caption;
// rellenamos el rotulo del panel que mostrará el edit para la inserción de la cantidad asignada
labRotulo.caption:= TListview(source).Selected.Caption;
// seleccionamos para este nuevo icono la misma imagen
ImageIndex:= TListview(source).Selected.ImageIndex;
end;
{ajustamos los valores a dicho panel para su presentación}
panCantidad.left:= (screen.ActiveForm.ClientWidth div 2) – (panCantidad.Width div 2);
panCantidad.top:= (screen.ActiveForm.ClientHeight div 2) – (panCantidad.Height div 2);
// Lo visualizamos
panCantidad.visible:= true;
// le trasferimos el foco a la casilla de edición de dicho panel.
ediCantidad.setfocus;
end;
end;
// Estos cuatro procedimientos todavía estan provisionales. La idea del programador es que al pulsar el botón derecho del ratón sobre cada ListView aparezca un donde pueda elegir las cuatro presentaciones. Permanecen mientras está en fase de pruebas y de hecho, como podeis comprobar, puesto que no están definidas las columnas del TlistView la presentación Report no tiene sentido
//*****************************************************
procedure TfrmRelaciones.Button1Click(Sender: TObject);
begin
lvW_materiasprimas.ViewStyle:= vsIcon;
lvw_ProcesosEspeciales.ViewStyle:= vsIcon;
lvw_Destino.ViewStyle:= vsIcon;
end;
procedure TfrmRelaciones.Button2Click(Sender: TObject);
begin
lvW_materiasprimas.ViewStyle:= vsSmallIcon;
lvw_ProcesosEspeciales.ViewStyle:= vsSmallIcon;
lvw_Destino.ViewStyle:= vsSmallIcon;
end;
procedure TfrmRelaciones.Button3Click(Sender: TObject);
begin
lvW_materiasprimas.ViewStyle:= vsList;
lvw_ProcesosEspeciales.ViewStyle:= vsList;
lvw_Destino.ViewStyle:= vsList;
end;
procedure TfrmRelaciones.Button4Click(Sender: TObject);
begin
lvW_materiasprimas.ViewStyle:= vsReport;
lvw_ProcesosEspeciales.ViewStyle:= vsReport;
lvw_Destino.ViewStyle:= vsReport;
end;
//*****************************************************
{Este procedimiento corresponde a la pulsación del teclado sobre la casilla de edición Categoría, que se encargará de efectuar un filtro a los items del ListView donde le enseñamos al usuario las materias primas existentes}
procedure TfrmRelaciones.ediCategoriaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key= vk_returnthen // si es pulsado el Enter
begin
// si el texto de la casilla es vacío o contiene un carácter en blanco
if ((ediCategoria.text = ») or (ediCategoria.text = ‘ ‘)) then
begin
// volvemos a asignar un valor correcto (el valor por defecto)
ediCategoria.text:= ds_enlacept.DataSet.fields[9].asString;
// avisamos al usuario
ShowMessage(‘Atención: Filtro de Categoría no puede tener valor o ‘);
end;
lvW_materiasprimas.items.clear; // vaciamos el contenedor
//Rellenamos el listview de Materias primas
// en el caso de que el filtro por texto este vació repetimos el proceso de creación e inserción de iconos ya comentado en el evento OnShow.
if ((ediCodigoMatePrim.text = ») or (ediCodigoMatePrim.text = ‘ ‘)) then
begin
with consulta_Relaciones do
begin
Sql.clear;
Close;
Sql.Add(‘Select * from MATERIASPRIMAS’);
Sql.Add(‘Where CATEGORIA = ‘ + EdiCategoria.text);
Sql.Add(‘order by COD_MATPRIM’);
Open;
First;
end;
end
else // en el caso de que estemos filtrando
begin
with consulta_Relaciones do
begin
Sql.clear;
Close;
Sql.Add(‘Select * from MATERIASPRIMAS’);
// Tenemos en consideración ambos filtros
Sql.Add(‘Where CATEGORIA = ‘ + EdiCategoria.text + ‘ AND ‘);
Sql.Add(‘COD_MATPRIM >= ‘ + Chr(39) + EdiCodigoMateprim.text + Chr(39));
Sql.Add(‘order by COD_MATPRIM’);
Open;
First;
end;
end;
{ una vez seleccionados los registros de la tabla procedemos a la creación del icono y la asignación del caption, que nos devolverá el nombre de cada materia prima}
while not consulta_Relaciones.Eof do
begin
with lvW_materiasprimas.items.add do
begin
Caption:= Consulta_Relaciones.fields[0].asString;
ImageIndex:= 0;
end;
Consulta_Relaciones.next;
end;
end;
end;
{Procedimiento correspondiente a la pulsación del cuadro edición del filtro de categorías. Una cosa que podemos destacar y que entra dentro de la sintaxis de Object Pascal es la utilización de parámetros por referencia en procedimientos. Podemos quedarnos con la idea de que cualquier procedimiento que declara Var un parámetro nos va a dejar la opción de poder redefinir dicho parámetro. El motivo es evidente:
Cuando un parámetro es pasado por referencia se establece un puntero a dicha variable y la modificación efectuada sobre el mismo es directa. En cambio, si el parámetro es pasado por valor, lo habitual, dicha variable declarada obtiene una copia del valor original y dicho valor será temporal y existirá localmente.}
procedure TfrmRelaciones.ediCategoriaKeyPress(Sender: TObject;
var Key: Char);
begin
if key <> #8 then // si es distinto de la tecla de retroceso
if ((key > ‘9’) or (key < ‘0’)) then // si es distinto de número
key := #0; // ignoramos la pulsación
end;
{Procedimiento que corresponde al momento en el que arrastramos un objeto sobre la papelera}
procedure TfrmRelaciones.Image1DragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
begin
if (source is TListView) then
if ((source as TListView).tag = 3) then
// solo aceptamos el objeto si es perteneciente al ListView que contiene los objetos asignados al producto
Accept:= true
else
Accept:= False;
end;
{Procedimiento que corresponde al momento de soltar un objeto sobre la papelera.
Vamos a explicar el código siguiente:
<TListView(source).Items.Delete(TListView(source).Selected.Index);>
Moldeamos la variable source, que como sabemos nos recoge el objeto origen del arrastre. Dicho moldeo nos permite acceder a la propiedad items, y sobre esta ejecutamos el método Delete. Dicho método espera el índice del objeto a borrar en esa lista y para proporcionarlo volvemos a moldear dicho objeto pero esta vez aplicando el método Selected.Index, que nos devolverá el índice de dicho icono.}
procedure TfrmRelaciones.Image1DragDrop(Sender, Source: TObject; X,
Y: Integer);
begin
if source <> nil then
if source is TListView then
// solo aceptamos el objeto si es perteneciente al ListView que contiene los objetos asignados al producto
if ((source as TListView).tag = 3) then
begin
if messagedlg(‘¿Quieres borrar el registro ‘ + TListView(source).Selected.Caption, mtWarning, [mbOk, mbCancel], 0) = mrOk then
begin
// Procedemos al borrado de dicho item
TListView(source).Items.Delete(TListView(source).Selected.Index);
end;
end;
end;
{Procedimiento correspondiente al perder el foco la casilla de edición que recogerá la cantidades asignadas. Necesitamos implementar este procedimiento para que dicho panel sea ocultado una vez sea pulsado el enter o hecho click con el puntero del ratón en otro elemento de la ventana.}
procedure TfrmRelaciones.ediCantidadExit(Sender: TObject);
var
decimal: currency;
begin
// nos aseguramos que el numero es correcto. No podemos admitir números como ‘1,24,30’ puesto que no controlamos la cantidad de comas que hay incluidas en el numero
try
decimal:= StrToFloat(ediCantidad.text);
lvw_destino.items.Item[lvw_destino.Items.count – 1].SubItems.Add(FloatToStr(decimal))
except
on exception do
begin
// si se produce una excepción tomamos como predeterminado el valor 0
ediCantidad.text:= ‘0’;
end;
end;
// ocultamos el panel y todos los elementos que contiene
panCantidad.visible:= false;
ediCantidad.text:= ‘0’; // ponemos a cero la cantidad
end;
{Procedimiento que corresponde a la pulsación del teclado sobre el cuadro de edición que recogerá las cantidades asignadas. Este procedimiento es compañero del inmediato anterior y entre ambos controlan la visibilidad del panel y la inserción en el icono destino de un subitem con la nueva cantidad asignada}
procedure TfrmRelaciones.ediCantidadKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
decimal: currency;
begin
if key = vk_return then // si es pulsado el enter
begin
// hacemos las mismas comprobaciones que en el procedimiento anterior
try
decimal:= StrToFloat(ediCantidad.text);
// añadimos el nuevo subitem con la cantidad asignada
lvw_destino.items.Item[lvw_destino.Items.count – 1].SubItems.Add(FloatToStr(decimal))
except
on exception do
begin
ShowMessage(‘Introduce un numero correcto, por favor…’);
ediCantidad.text:= ‘0’;
Exit;
end;
end;
panCantidad.visible:= false;
ediCantidad.text:= ‘0’;
end;
end;
{Procedimiento que corresponde al pulsar el teclado sobre el cuadro de edición que recogerá las cantidades asignadas}
procedure TfrmRelaciones.ediCantidadKeyPress(Sender: TObject;
var Key: Char);
begin
// si es pulsada una tecla distinta de todas estas es ignorada
if key <> #13 then // distinta de enter
if key <> #8 then // distinta de retorceso
if key <> ‘,’ then // distinta de coma
if ((key > ‘9’) or (key < ‘0’)) then // o distinta de número
key := #0;
end;
{Al situar el cursor del ratón sobre un icono del listview de asignación al producto}
procedure TfrmRelaciones.lvw_destinoMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
begin
try
// asignamos a la propiedad hint del listview el valor de la cantidad introducida en el subitem del objeto
lvW_destino.hint:= lvw_destino.GetItemAt(x,y).SubItems.Strings[0];
except
lvW_destino.hint:= »;
end;
end;
{En este procedimiento debemos transferir a la tabla de productos las asignaciones efectuadas.}
procedure TfrmRelaciones.FormClose(Sender: TObject;
var Action: TCloseAction);
var
xIndice: Integer;
numero: integer;
codigoProducto: String;
begin
// esta variable nos recogerá el valor del código del producto
CodigoProducto:= ds_enlacept.DataSet.fields[0].asString;
//Rellenamos el listview de Productos Terminados
with consulta_Relaciones do
begin
Sql.clear;
Close;
Sql.Add(‘Select * from RELACION_PT_MP’);
Sql.Add(‘Where CODIGO_PROD_TER = ‘ + Chr(39)+ ds_enlacept.DataSet.fields[0].asString + Chr(39));
Sql.Add(‘order by CODIGO_MATEPRIM’);
Open;
First;
end;
// borramos todos los registros de materias primas asignados originalmente en la tabla de relación
while not consulta_Relaciones.eof do
begin
consulta_relaciones.Delete; // borramos todos los registros para ese producto
end;
// la variable numero nos devolvera la cantidad de items en el listview
numero:= lvw_destino.Items.Count;
for xIndice:= 0 to numero – 1 do // recorremos un bucle con ese valor
begin
// si el item pertenece a materias primas (su imageindex es 0)
if lvW_destino.items.item[xIndice].ImageIndex = 0 then
begin
consulta_Relaciones.insert; // insertamos un registro
// damos valor a todos sus campos según este item
consulta_relaciones.fields[1].asString:= CodigoProducto;
consulta_relaciones.Fields[2].asString:= lvW_destino.items.item[xIndice].Caption;
// si subitems no esta asignado (cantidad)
if lvW_destino.items.item[xIndice].SubItems = nil then
// asignamos al campo el valor 0 para que no genere una excepción
consulta_relaciones.Fields[3].asString:= ‘0’
else // en el caso de que sí esté asignada
// le damos el valor que ha proporcionado el usuario
consulta_relaciones.Fields[3].asString:= lvW_destino.items.item[xIndice].SubItems.Strings[0];
// validamos la tabla
consulta_relaciones.Post;
end;
end;
//Ahora procedemos con los procesos especiales
with consulta_Relaciones do
begin
Sql.clear;
Close;
Sql.Add(‘Select * from RELACION_PT_PE’);
Sql.Add(‘Where CODIGO_PROD_TER = ‘ + Chr(39)+ ds_enlacept.DataSet.fields[0].asString + Chr(39));
Sql.Add(‘order by CODIGO_PROCESOS_ESP’);
Open;
First;
end;
// borramos todos los registros de procesos especiales asignados originalmente en la tabla de relación
while not consulta_Relaciones.eof do
begin
consulta_relaciones.Delete; // borramos todos los registros para ese producto
end;
// la variable numero nos devolverá la cantidad de items en el listview
numero:= lvw_destino.Items.Count;
for xIndice:= 0 to numero – 1 do // recorremos un bucle con ese valor
begin
// si el item pertenece a procesos especiales (su imageindex es 1)
if lvW_destino.items.item[xIndice].ImageIndex = 1 then
begin
consulta_Relaciones.insert; // insertamos un registro
// damos valor a todos sus campos según este item
consulta_relaciones.fields[1].asString:= CodigoProducto;
consulta_relaciones.Fields[2].asString:= lvW_destino.items.item[xIndice].Caption;
// si subitems no esta asignado (cantidad)
if lvW_destino.items.item[xIndice].SubItems = nil then
// asignamos al campo el valor 0 para que no genere una excepción
consulta_relaciones.Fields[3].asString:= ‘0’
else // en el caso de que sí esté asignada
// le damos el valor que ha proporcionado el usuario
consulta_relaciones.Fields[3].asString:= lvW_destino.items.item[xIndice].SubItems.Strings[0];
// validamos la tabla
consulta_relaciones.Post;
end;
end;
end;
end. |
Deja una respuesta