Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Modificacion de Dataset en ejecucion (https://www.clubdelphi.com/foros/showthread.php?t=75450)

joelphi 24-08-2011 17:10:53

Modificacion de Dataset en ejecucion
 
Hola buen dia..

Primero debo de agradecer a los participantes de este club por ayudarme mas de una vez en mis problemas..
Bueno paso al grano armo una consulta SQL y abro el dataset (Open) posteriormente necesito que un campo que viene en la consulta sea modificable es decir que su valor salga de de otros campos de la misma consulta y una condicion, investigando en la red encontre que podia ponerlo en Edit; y luego guardarlo con el Post; Pero me lanza un error al ponerlo en edicion..

Por favor requiero de ayuda o alguna informacion.
El codigo es el siguiente:
Código Delphi [-]
 Consulta.Close;
    Consulta.SQLs.SelectSQL.Clear;
    Consulta.SQLs.SelectSQL.Add(' Select Prod.nombre_producto,Sus.nombre as sustancia,Prov.nombre_proveedor,Cat.Id_categoria,Cat.nombre as categoria,Prod.aplicar_descuento,'
                               +' Prod.costo_referencia,Prod.iva,Prod.ganancia,Prod.precio_farmacia,Prod.precio_maximo,Prod.Precio_Max  imo As Precio_Con_Descuento'
                               +' From categorias Cat, medidas Me,sustancias_activas Sus,proveedores Prov,productos Prod'
                               +' where cat.id_categoria = Prod.id_categoria And Me.id_medida = Prod.id_medida And Sus.id_sustancia_activa = Prod.id_sustancia_activa'
                               +' And Prov.id_proveedor = Prod.id_proveedor');
    try
        Consulta.Open;
    except on E: Exception do
    begin
        Raise;
        Exit;
    end;
    end;

     Consulta.First;
     Consulta.Edit;
    while not consulta.Eof do
    begin
        with Consulta do
        begin
        //Si aplica descuento a este producto.. 
            if(FieldByName('Aplicar_Descuento').AsString = 'SI') then
              begin
                for I := 0 to ListaDescuentos.Count do //entonces buscar su categoria y si es igual aplicar el descuento
                 begin
                     if FieldByName('id_Categoria').AsInteger = TDescuentos_Clientes(ListaDescuentos[i]).Id_Categoria then
                     begin    //Aplicar el descuento
                        //ProductoDescuento.PrecioConDescuento := ProductoDescuento.PrecioMaximo - (ProductoDescuento.PrecioMaximo*descuento);
                        FieldByName('Precio_Con_Descuento').AsCurrency :=FieldByName('Precio_Maximo').AsCurrency - (FieldByname('Precio_Maximo').AsCurrency * TDescuentos_Clientes(ListaDescuentos[i]).Descuento);
                     end;
                 end;
              end;

        consulta.next;
        end;
    end;
    Consulta.Post;

Deberas que se lo agradecere muchisimo...

oscarac 24-08-2011 17:40:17

seria mucho mas facil de entender si es que nos proporcionas el error que aparece

una forma de hacerlo podria ser utilizando campos calculados

joelphi 24-08-2011 17:48:05

Se me paso el error..
 
Menciona esto:

Cannot modify a read-only dataset

haciendo el Debuger me di cuenta que aparece en la linea donde esta la sentencia
Código Delphi [-]
      Consulta.Edit;

a que te refieres con campos calculados??? ..
te refieres a agregarle una nueva columna al dataset con un atributo Calculado?

oscarac 24-08-2011 18:01:46

asi es..

otra sugerencia... es que trates de utilizar Joins... ya sea Left o Inner en tu consulta dependiendo de lo que necesites

segun veo estas sacando datos de 5 tablas
Categorias
Medidas
Sustenacias Activas
Proveedores
Productos
la consulta podria tornarse lentas si es que no utilizas racionalmente la sintaxis

podrias hacer algo como esto

Código Delphi [-]
Select P.nombre_producto,S.nombre as sustancia, Pv.nombre_proveedor, C.Id_categoria,C.nombre as categoria, P.aplicar_descuento,
       P.costo_referencia,P.iva, P.ganancia, P.precio_farmacia, P.precio_maximo, P.Precio_Maximo As Precio_Con_Descuento
From productos Prod
Left Join categorias C on c.id_categoria = P.id_categoria
Left Join sustancias_activas S on S.id_sustancia_activa = P.id_sustancia_activa
Left Join proveedores P on Pv.id_proveedor = P.id_proveedor

otro detalle es que estas jalando datos de la tabla Medida y no lo estas usando en la consulta


como dato adicional...

has depurado el programa y verificado que la consulta se abra? porque si no se abre o hay un error no puedes hacerle el edit



saludos

joelphi 24-08-2011 18:45:54

probe
 
Tu consulta esta muy bien..se ve que ya tienes tu experiencia yo todavia soy estudiante..

Ya depure el programa y si se abre la consulta,ahora estoy probando los campos calculados quedo de esta forma solo que ahora no lo calcula
Código Delphi [-]
  Consulta.Close;
    Consulta.SQLs.SelectSQL.Clear;
    Consulta.SQLs.SelectSQL.Add(' Select P.nombre_producto,S.nombre as sustancia, Prov.nombre_proveedor, C.Id_categoria,C.nombre as categoria, P.aplicar_descuento,'+
                                  ' P.costo_referencia,P.iva, P.ganancia, P.precio_farmacia, P.precio_maximo'+
                                  '  From productos P'+
                                  '  Left Join categorias C on c.id_categoria = P.id_categoria'+
                                  '  Left Join sustancias_activas S on S.id_sustancia_activa = P.id_sustancia_activa'+
                                  '  Left Join proveedores Prov on Prov.id_proveedor = P.id_proveedor');
    try

        Consulta.Open;
    except on E: Exception do
    begin
        Raise;
        Exit;
    end;
    end;
   Consulta.Close;

    for I := 0 to Consulta.FieldDefs.Count - 1 do
     Consulta.FieldDefs[i].CreateField(Consulta, nil, Consulta.FieldDefs[i].Name);

  NuevoCampoCalculado := TStringField.Create(Consulta);
  NuevoCampoCalculado.FieldName := 'Precio_Con_Descuento';
//  NuevoCampoCalculado.AsCurrency;
  NuevoCampoCalculado.FieldKind := fkCalculated;
  NuevoCampoCalculado.DataSet := Consulta;
    Consulta.Open;
    Consulta.First;
    while not consulta.Eof do
    begin
        with Consulta do
        begin
        //Si aplica descuento a este producto..
            if(FieldByName('Aplicar_Descuento').AsString = 'SI') then
              begin
                for I := 0 to ListaDescuentos.Count -1  do //entonces buscar su categoria y si es igual aplicar el descuento
                 begin
                     if FieldByName('id_Categoria').AsInteger = TDescuentos_Clientes(ListaDescuentos[i]).Id_Categoria then
                     begin    //Si pasa por aqui pero no realiza la operacion-..
                        //ProductoDescuento.PrecioConDescuento := ProductoDescuento.PrecioMaximo - (ProductoDescuento.PrecioMaximo*descuento);
                        FieldByName('Precio_Con_Descuento').AsCurrency :=FieldByName('Precio_Maximo').AsCurrency - (FieldByname('Precio_Maximo').AsCurrency * TDescuentos_Clientes(ListaDescuentos[i]).Descuento);
                     end;
                 end;
              end;

        consulta.next;
        end;
    end;
    ListaDescuentos.Destroy;
    Result:= TDataSource.Create(Nil);
    Result.DataSet:=Consulta;

funciono bien pero no realiza la operacion..
Saludos..

oscarac 24-08-2011 18:52:25

te cuento que muuuuucha experiencia no tengo tampoco....

seria mejor que en el mismo componente ADOQUERY (si en caso usas ADO para la conexion) agregues el campo calculado

luego en el evento OnCalcFields ejecutes lo que quieres que calcule

esto lo hara despues del open

en resumen

agrega un campo calculado en el "componente adoquery" y tu rutina de calculo colocala en el evento Oncalcfield a ver que sale

saludos

joelphi 24-08-2011 19:02:55

ok
 
Lo probare trabajo con componentes TpFibPlus con firebird..no hay mucha diferencia tiene el mismo evento..

Gracias y Saludos..


La franja horaria es GMT +2. Ahora son las 07:01:44.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi