PDA

Ver la Versión Completa : Sumar y multiplicar varios edit automaticamente


The Cid James
05-12-2017, 06:38:39
Buenas gente, tengo el siguiente problema tengo un form con varios edit estos representan un valor especifico, para ser mas claro el de una moneda por ejemplo billete 1 dolar, 5 dolares, 10 dolares, etc...

Quisiera hacer que al editar el valor de los edit vaya multiplicando y sumando el total

Ejemplo ingreso en el edit1 la cantidad de 10 (cada uno de un dolar) en el edit2 un ejemplo ingreso 5 (de 5 dolares) en estos datos ingresados multiplicar por su valor fijo automáticamente en código para un botón seria algo así como


procedure TForm1.Button1Click(Sender: TObject);
Var n1,n2,suma: Integer;
begin
n1:=strtoint(Edit1.text);
n2:=strtoint(Edit2.text);
suma:= (n1*1) +(n2*5);
tedit3:text = inttostr(suma);
end;

ElKurgan
05-12-2017, 07:25:00
Si lo he entendido bien, quieres que se sumen sin necesidad de pulsar un botón, ¿correcto?

En ese caso, podrías capturar el evento "OnExit" de cada campo de edición y poner el mismo código que para el botón. Incluso se podría capturar el evento OnChange.

Eso si, los dos botones tendrían que compartir el código, llamándolo (por ejemplo) "CambiarDatos"

Saludos

ecfisa
05-12-2017, 07:26:26
Hola.

¿ Te sirve algo así ?

procedure TForm1.Button1Click(Sender: TObject);
var
amount: Integer;
begin
amount := StrToIntDef(Edit1.Text, 0) + // 1 u$S
StrToIntDef(Edit2.Text, 0) * 5 + // 5 u$s
StrToIntDef(Edit3.Text, 0) * 10 + // 10 u$s
StrToIntDef(Edit4.Text, 0) * 20 + // 20 u$s
...
end;


Saludos :)

The Cid James
05-12-2017, 08:07:18
Si lo he entendido bien, quieres que se sumen sin necesidad de pulsar un botón, ¿correcto?

En ese caso, podrías capturar el evento "OnExit" de cada campo de edición y poner el mismo código que para el botón. Incluso se podría capturar el evento OnChange.

Eso si, los dos botones tendrían que compartir el código, llamándolo (por ejemplo) "CambiarDatos"

Saludos
Si estuve probando con el onchange pero siempre trabaje con botones en lo que llevo aprendido por lo que se me complica hacer algo que ejecute lo mismo en muchos edits al mismo tiempo. Un procedimiento tal vez?:confused:
Con los "dos botones" te referis a los edit? la idea es hacerlo sin botones

Hola.

¿ Te sirve algo así ?
Código Delphi [-] (https://www.clubdelphi.com/foros/#)procedure TForm1.Button1Click(Sender: TObject); var amount: Integer; begin amount := StrToIntDef(Edit1.Text, 0) + // 1 u$S StrToIntDef(Edit2.Text, 0) * 5 + // 5 u$s StrToIntDef(Edit3.Text, 0) * 10 + // 10 u$s StrToIntDef(Edit4.Text, 0) * 20 + // 20 u$s ... end;


Saludos :)

Claro algo asi pero que cambie cuando vaya editando el edit no en boton

ecfisa
05-12-2017, 13:51:47
Hola.

...
Claro algo asi pero que cambie cuando vaya editando el edit no en boton
Entonces sólo debes situar el mismo código en el evento OnChange de todos los Edits, por ejemplo:

...
(* Asigno los eventos en tiempo de ejecución para clarificar el ejemplo,
pero te resultará mas simple hacerlo en tiempo de diseño *)
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.OnChange := EditsChange;
Edit2.OnChange := EditsChange;
Edit3.OnChange := EditsChange;
Edit4.OnChange := EditsChange;
//...
end;

procedure TForm1.EditsChange(Sender: TObject);
var
amount: Integer;
begin
amount := StrToIntDef(Edit1.Text, 0) + // 1 u$S
StrToIntDef(Edit2.Text, 0) * 5 + // 5 u$s
StrToIntDef(Edit3.Text, 0) * 10 + // 10 u$s
StrToIntDef(Edit4.Text, 0) * 20; // + // 20 u$s
//...
Self.Caption := IntToStr(amount);
end;


Saludos :)

The Cid James
06-12-2017, 03:25:21
Si entiendo bien creo en procedimiento edits onechanges, por ejemplo, y en el formcreate y lo asigno al onchange de cada edit para que se ejecuten?
No comprendo del todo a que te referís con asignarlos a tiempo de ejecución para el ejemplo (se lo que significa esto ultimo)

Gracias y saludos

ecfisa
06-12-2017, 18:03:36
Si entiendo bien creo en procedimiento edits onechanges, por ejemplo, y en el formcreate y lo asigno al onchange de cada edit para que se ejecuten?
No comprendo del todo a que te referís con asignarlos a tiempo de ejecución para el ejemplo (se lo que significa esto ultimo)
En tiempo de ejecución significa que los eventos se asignan cuando se ejecuta el programa, es mas simple hacerlo en tiempo de diseño, pero me resulta mas confuso de explicar en un mensaje.

En tiempo de diseño, seleccionas todos los Edits (Ctrl+Left_Click) y luego generas el evento OnChange desde el Object Inspector para todos ellos.

Saludos :)

ecfisa
06-12-2017, 18:08:36
Hola de nuevo.

Confeccione el ejemplo y te adjunto el código fuente para que lo evalues. (evento asignado en diseño)


Saludos :)

Milworm99
06-12-2017, 20:04:58
Hola de nuevo.

Confeccione el ejemplo y te adjunto el código fuente para que lo evalues. (evento asignado en diseño)


Saludos :)

Y si quiere sumar o multiplicar en números decimales, como seria el código ?

ecfisa
06-12-2017, 22:51:48
Hola.
Y si quiere sumar o multiplicar en números decimales, como seria el código ?
Puede usar la función StrToFloatDef (http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/SysUtils_StrToFloatDef@string@Extended.html) y cambiar la operación aritmética por la que desee.

Saludos :)

The Cid James
07-12-2017, 00:11:21
seria algo asi?

StrTofloatDef(Edit4.Text, 0) * 20

Ahora me quedo una duda... se puede trabajar con decimales en el tipo integer?

ecfisa
07-12-2017, 00:21:02
seria algo asi?

StrTofloatDef(Edit4.Text, 0) * 20

Ahora me quedo una duda... se puede trabajar con decimales en el tipo integer?
No, el compilador daría error de compatibilidad de tipos.

Por el contrario, no hay inconveniente en asignar un valor entero a una variable de tipo flotante.

Saludos :)

The Cid James
07-12-2017, 00:30:14
uff a cambiar los tipos de la tabla para poder cambiar eso ya que puse el ejemplo solo enteros, pero tambien estoy usando monedas, ahora entiendo porque no me deja copilarlo, entonces la variable amount en el ejemplo que me pasaste tambien tendria que ser flotante?

Saludos

Edit :

Asi funciona bien con decimales :D

procedure TFcaja.EditsChange(Sender: TObject);
var
amount: Currency;
begin
amount := StrToFloatDef (E1.Text, 0) * 0.1 + // 1 u$S
StrToFloatDef(E5.Text, 0) * 5 + // 5 u$s
StrToFloatDef(E10.Text, 0) * 10+ // 10 u$s
StrToFloatDef(E2 .Text, 0) * 20 ;// + // 20 u$s
//...
EACtotal.Text:= FloatToStr (amount);
end;

ecfisa
07-12-2017, 00:46:52
Hola.

Si vas a trabajar con monedas el tipo Currency es el indicado.

Saludos :)

Milworm99
07-12-2017, 16:37:17
Hola.

Si vas a trabajar con monedas el tipo Currency es el indicado.

Saludos :)

Y como se hace para el redondeo del resultado en decimales ?

Milworm99
07-12-2017, 17:04:00
Se trabajaría con este codigo ?

FormatFloat('0.0',amount);

The Cid James
07-12-2017, 17:32:32
Aca encontre lo que necesitas

https://www.clubdelphi.com/foros/showthread.php?t=40785

Saludos

Milworm99
18-12-2017, 01:06:26
Aca encontre lo que necesitas

https://www.clubdelphi.com/foros/showthread.php?t=40785

Saludos

function Redondearagag(Valor:Real; Decimal:Integer):Real;
begin
result := StrToFloat(FloatToStrF(StrToFloat(FloatToStr(Valor)), ffFixed, 18, Decimal));
end;

Como puedo utilizar esa funcion para redondear ?
Lo que yo quiero es que si el resultado es
7.55 lo redondee a 7.60

ecfisa
18-12-2017, 12:24:48
Hola.
...
Lo que yo quiero es que si el resultado es
7.55 lo redondee a 7.60
La función anterior lo hace, solo debes llamarla pasándo el valor 1 al parámetro Decimal.

Te agrego dos opciones diferentes:

uses Math;

function Redondear(const Value: Double; const Digit: Integer): Double;
begin
SetRoundMode(rmUp);
Result := RoundTo(Value, - Digit);
end;




function Redondear(const Numero: Double; const Digitos: Integer): Double;
var
m: Double;
begin
m:= Exp(Ln(10) * Digitos);
Result:= Round(Numero * m + 5 / m) / m;
end;


Un ejemplo de uso para ambos casos:

...
begin
ShowMessageFmt('%8.2f', [ Redondear(7.55, 1) ]);


Saludos :)

Milworm99
18-12-2017, 16:10:06
Hola.

La función anterior lo hace, solo debes llamarla pasándo el valor 1 al parámetro Decimal.


Funciona perfectamente, pero en este caso como lo haría para que el resultado me lo muestre en un edit automáticamente sin ningún botón ?

ecfisa
18-12-2017, 17:23:46
Hola.

Un modo es que crees código para el evento OnExit de un TEdit y luego se lo asignes a todos los Edits que esperen números decimales para redondear.

Ejemplo:

...

procedure TForm1.EditsExit(Sender: TObject);
var
d : Double;
begin
d := StrToFloatDef(TEdit(Sender).Text, 0);
TEdit(Sender).Text := FormatFloat('0.00', Redondear(d, 1));
end;

De este modo, cuando el Edit activo pierda el foco, mostrará el redondeo que deseas. ( StrToFloatDef (http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.SysUtils.StrToFloatDef) )

Saludos :)

Milworm99
18-12-2017, 17:28:58
Hola.

Un modo es que crees código para el evento OnExit de un TEdit y luego se lo asignes a todos los Edits que esperen números decimales para redondear.


El problema es que cuando se multiplica 1 x 0.80 me arroja el valor 0.90

Milworm99
18-12-2017, 17:40:53
Hola.

Un modo es que crees código para el evento OnExit de un TEdit y luego se lo asignes a todos los Edits que esperen números decimales para redondear.


Ya encontre el problema, para los que quieren que les multiplique un numero por un decimal ( ejemplo: 0.75 ) y el resultado les muestre redondeado utilizan esa función

function Redondear(const Numero: Double; const Digitos: Integer): Double;
var
m: Double;
begin
m:= Exp(Ln(10) * Digitos);
Result:= Round(Numero * m + 5 / m) / m;
end;

Metodo de uso:

multiplicacion:Currency;

multiplicacion := StrToFloatDef (edt1.Text, 0) * 0.75;
Edt2.Text:= FormatFloat('0.00', Redondear(multiplicacion , 1));

Con esto logramos que al multiplicar 1 x 0.75 el valor nos muestre redondeado: 0.80

Y si quieren que multiplique un numero por un decimal ( ejemplo: 0.80) y el resultado les muestre redondeado, utilizamos:

Edt2.Text:= FormatFloat('0.00',multiplicacion);

Con esto logramos que al multiplicar 1 x 0.80 nos muestre el valor de : 0.80