PDA

Ver la Versión Completa : Recorrer una Dataset hacia atras


IVAND
14-05-2012, 21:52:55
Hola a todos

Estoy tratando de hacer algo q un cliente me pidio con un tema contable , les explico , tengo uno balance que obviamente tiene
codigo , nombre , debe ,haber y proviene este de un plan de cuentas , hasta aqui todo esta bien hay un SP que se encarga de sacar algo como esto


codigo nombre debe haber saldo
1 Activo 0 0 0
1.1 Activo corr 0 0 0
1.1.1 Caja 0 0 0
1.1.1.01 Caja General 120 30 90
2. Pasivo 0 0 0
2.1. Pasivo corriente 0 0 0
2.1.1 Lo que sea 80 120 - 40


Pues bien , la idea es barrer desde abajo hasta arriba la tabla o el datased , y usar un bucle para recorrer todo el dato completo

La idea se resume a

con dataset.last me pongo en el ultimo registro , pero que ciclo uso para que el registro vaya desde abajo hasta arriba , la idea es ir acumulando los valores ejemplo la 2.1.1 acumulara 2.1 y esta en la 2 , seguira con la 1.1.1.01 que acumula a la 1.1.1 y esta 1.1 y esta 1

adjunto el proyecto a ver si me pueden dar la mano un abrazo

Pues no me deja adjuntar archivo

colocare parte del codigo

procedure TForm1.Button1Click(Sender: TObject);
var
x,I, nume: Integer;
J: string;
Saldo: Real;
begin
//Recorremos de atras para adelante el bucle

rx.Last;

//for i := 0 to Rx.RecordCount - 1 do
while rx.Eof do
begin
nume := Length(Trim(rx.fieldByname('codigo').value));
saldo := Saldo + Rx.FieldByName('Saldo').Value;
for X := Nume - 1 downto 1 do
begin
//Enceramos cuando llegamos al principio
if x = 0 then
Saldo := 0;
J := Copy(Trim(rx.fieldByname('codigo').value), 1, X);
if rx.Locate('codigo', j, []) then
begin
saldo := Saldo + Rx.FieldByName('Saldo').Value;
Rx.Edit;
Rx.FieldByName('Saldo').Value := saldo;
rx.Post;
end;
end;
next;
end
end;

marcoszorrilla
14-05-2012, 22:05:22
Tienes que utilizar Bof en vez de Eof y además Prior.


While Not dmXXX.Bof do
begin
xxxxxx
Dmxx.Prior
end;

Un Saludo.

IVAND
15-05-2012, 05:55:35
Gracias Marcos por tu respuesta, funciona perfecto , pero cuando el locate salta y encuentra el registro se sale del bucle , se puede guardar una posicion dentro de la busqueda y luego volver a esa posicion despues del locate ?


rx.Last;
While Not rx.Bof do
begin
nume := Length(Trim(rx.fieldByname('codigo').value));
saldo := Saldo + Rx.FieldByName('Saldo').Value;
rx1.insert;
rx1.fieldbyname('codigo').value:=rx.fieldByname('codigo').value;
rx1.post;

for X := Nume - 1 downto 1 do //Paso 2
begin
//Enceramos cuando llegamos al principio
if x = 0 then
Saldo := 0;
J := Copy(Trim(rx.fieldByname('codigo').value), 1, X);
if rx.Locate('codigo', j, []) then
begin
saldo := Saldo + Rx.FieldByName('Saldo').Value;
Rx.Edit;
Rx.FieldByName('Saldo').Value := saldo;
rx.Post;
end;
end;
Rx.prior; //Tomaria un registro y subiria al proximo en el paso 2 y asi sucesivamente
end;




Gracias por sus comentarios

marcoszorrilla
15-05-2012, 07:41:48
Para volver a una posición dentro de un Dataset puedes utilizar un BookMark.

Ejemplo de uso.

procedure TfrPVP.spbCambiarClick(Sender: TObject);
var
s1,s2:String;
begin
Try
s1:=DmPrix.IBDtsProveeCODIGO.Value;
s2:=Copy(DmPrix.IBDtsPVPCODIGO.Value,4,7);
DmPrix.IbDtsPVP.Edit;
DmPrix.IBDtsPVPCODIGO.Value:=s1+s2;
EdProvee.Text:=DmPrix.IBDtsProveeNOMBRE.Value;

spbCambiar.Visible:=False;
Donde:=DmPrix.IBDtsPVP.GetBookmark;
Actualizar_Codigo_Proveedor();
ShowMessage('Atención:El código de Proveedor se cambio con éxito.');
Except
ShowMessage('Atención: Se produjo un error al intentar cambiar el Código del Proveedor del producto.');
end;
DmPrix.IBDtsPVP.Open;
DmPrix.IBDtsPVP.GotoBookmark(donde);
end;
Un Saludo.

IVAND
15-05-2012, 22:20:15
Gracias muy amable por tu tiempo

ya esta listo lo que queria gracias a todos