Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Componente Stringgrild (https://www.clubdelphi.com/foros/showthread.php?t=72279)

JLMN22 08-02-2011 12:55:07

Componente Stringgrild
 
Buenas tardes, en un manual que me descargue de delphi, me pone ue haga un ejercicio con el coponente srtinggrild. Lo copio para que lo entendais:

2.- Construir un concentrado que contenga los ingresos por ventas mensuales de los 3 primeros meses del año de 4 sucursales de una cadena refaccionaría, agregar listas de ingresos totales por mes e ingresos promedios por sucursal.

Tengo el sigiente codigo:

Código Delphi [-]
procedure TForm1.CalcularClick(Sender: TObject);
var
totsuc: array [1..4] of real;
promsuc: array [1..4] of real;
totmes: array [1..3] of real;
prommes: array [1..3] of real;
columnas:integer;
renglones:integer;

begin


for renglones:=0 to 3 do begin
for columnas:=0 to 2 do begin
  totsuc[renglones]:=totsuc[renglones]+strtofloat(stringgrid1.Cells[renglones,columnas]);

end;
end;
for renglones:=0 to 3 do begin
promsuc[renglones]:=totsuc[renglones]/3;
end;


for renglones:=0 to 3 do begin
for columnas:=0 to 2 do begin
totmes[columnas]:=totmes[columnas]+strtofloat(stringgrid1.Cells[renglones,columnas]);
end;

end;
for columnas:=0 to 2 do begin

prommes[columnas]:=totmes[columnas]/4;
end;

for renglones := 0 to 3 do begin
listbox1.Items.Add(floattostr(totsuc[renglones]));
listbox1.Items.Add(floattostr(promsuc[renglones]));
end;
for columnas := 0 to 2 do begin
listbox3.Items.Add(floattostr(totmes[columnas]));
listbox4.Items.Add(floattostr(prommes[columnas]))


end;

end;

end.

Al ejecutarlo me va todo bien pero cuando le doy al boton calcular me da el siguente error:

raised excemtio class econverterror with message is not vaid floating point value.

He mirado y no he encontrado el fallo, aunque seguro que sera una tonteria como siempre me suele pasar.

Un saludo y gracias de antemano

duilioisola 08-02-2011 15:22:03

Cita:

is not vaid floating point value
Te está diciendo que el valor que utilizas no es un valor tipo Float válido.

Supongo que el problema está en la función StrToFloat.
Le pasas un string y te devuelve un Float.
Si el string es vacío o tiene letras o más de un punto, te dará un error de conversión
Cita:

raised exception class EConvertError
Puedes por ejemplo poner la parte que puede fallar en bloques try..except
Por ejemplo:
Código Delphi [-]
for renglones:=0 to 3 do 
begin
   for columnas:=0 to 2 do 
   begin
      try
         totmes[columnas] := totmes[columnas] + strtofloat(StringGrid1.Cells[renglones,columnas]);
      except
         on e:Exception do
         begin
            {Si falla te mostrara el valor del StringGrid y pondrá el valor a 0}
            ShowMessage('No puedo convertir ' + StringGrid1.Cells[renglones,columnas]);
            totmes[columnas] := 0;
         end;
      end;
   end;
end;

JLMN22 09-02-2011 11:49:41

Cita:

Empezado por duilioisola (Mensaje 390328)
Te está diciendo que el valor que utilizas no es un valor tipo Float válido.

Supongo que el problema está en la función StrToFloat.
Le pasas un string y te devuelve un Float.
Si el string es vacío o tiene letras o más de un punto, te dará un error de conversión

Puedes por ejemplo poner la parte que puede fallar en bloques try..except
Por ejemplo:

Código Delphi [-]for renglones:=0 to 3 do
begin
for columnas:=0 to 2 do
begin
try
totmes[columnas] := totmes[columnas] + strtofloat(StringGrid1.Cells[renglones,columnas]);
except
on e:Exception do
begin
{Si falla te mostrara el valor del StringGrid y pondrá el valor a 0}
ShowMessage('No puedo convertir ' + StringGrid1.Cells[renglones,columnas]);
totmes[columnas] := 0;
end;
end;
end;
end;


Ants no he dicho, que da fallo cuando pongo datos ya sea enteros o decimales.

duilioisola 09-02-2011 15:39:20

¿Has modificado tu procedimiento como te he comentado (try..except)?
¿Sigue fallando?
¿Con qué error?
¿En qué línea?

JLMN22 10-02-2011 12:45:22

Cita:

Empezado por duilioisola (Mensaje 390443)
¿Has modificado tu procedimiento como te he comentado (try..except)?
¿Sigue fallando?
¿Con qué error?
¿En qué línea?

Lo he puesto en la primera linea, y me da error, de mod que no he seguido con las demas. y me da el error que no puede convertir, y a la cuarta vez que me sale ese error me sale el error ya comentado.

Yo creo que el fallo esta en toda las lineas.

duilioisola 10-02-2011 13:23:55

Cita:

y me da el error que no puede convertir
Código Delphi [-]
ShowMessage('No puedo convertir ' + StringGrid1.Cells[renglones,columnas]);
totmes[columnas] := 0;
Si el error es exactamente "No puedo convertir " Quiere decir que la celda en ese renglón y esa columna está vacío.

Si el error es algo así como "No puedo convertir 123.456.678"; Quiere decir que la celda en ese renglón y esa columna tiene el valor "123.456.678" que no es un valor válido. (Tiene 2 puntos)

Por lo que comentas, creo que es el primer error y por lo tanto se puede tomar como un 0 y es lo que hace el trozo de código si hay una excepción.

Cita:

la cuarta vez que me sale ese error me sale el error ya comentado
Eso es porque ya ha terminado el primer bucle donde has puesto el control de errores (bloque try..except).
En el segundo bucle trata de convertir nuevamente los valores y vuelve a fallar.

Si nos dices EXACTAMENTE qué valores tiene las celdas (con sus puntos, comas y signos) te podrémos decir qué es lo que fallará.

Ten en cuenta que para convertir un número con la función StrToFloat el string que le pasas:
- solo debe tener números
- solo puede haber un punto que separe la parte entera de la decimal.
- si fuera negativo podría empezar con el signo "-"
- no debe contener espacios.

JLMN22 10-02-2011 13:27:08

Cita:

Empezado por duilioisola (Mensaje 390553)
Código Delphi [-]
ShowMessage('No puedo convertir ' + StringGrid1.Cells[renglones,columnas]);
totmes[columnas] := 0;
Si el error es exactamente "No puedo convertir " Quiere decir que la celda en ese renglón y esa columna está vacío.

Si el error es algo así como "No puedo convertir 123.456.678"; Quiere decir que la celda en ese renglón y esa columna tiene el valor "123.456.678" que no es un valor válido. (Tiene 2 puntos)

Por lo que comentas, creo que es el primer error y por lo tanto se puede tomar como un 0 y es lo que hace el trozo de código si hay una excepción.


Eso es porque ya ha terminado el primer bucle donde has puesto el control de errores (bloque try..except).
En el segundo bucle trata de convertir nuevamente los valores y vuelve a fallar.

Si nos dices EXACTAMENTE qué valores tiene las celdas (con sus puntos, comas y signos) te podrémos decir qué es lo que fallará.

Ten en cuenta que para convertir un número con la función StrToFloat el string que le pasas:
- solo debe tener números
- solo puede haber un punto que separe la parte entera de la decimal.
- si fuera negativo podría empezar con el signo "-"
- no debe contener espacios.

Los numeros que meto en las celdas es 1 2 3 4 asi hasta 12. No pongo ni untos ni espacios ni signos ni nada, solo 1,2,3,4 a si hata doce y cada numero en una celda.

duilioisola 10-02-2011 13:30:27

Si quieres más información sobre el error puedes agregarla al mensaje de la exceción
Código Delphi [-]
for renglones:=0 to 3 do 
begin
   for columnas:=0 to 2 do 
   begin
      try
         totmes[columnas] := totmes[columnas] + strtofloat(StringGrid1.Cells[renglones,columnas]);
      except
         on e:Exception do
         begin
            {Si falla te mostrara el valor del StringGrid y pondrá el valor a 0}
            if (Trim(StringGrid1.Cells[renglones,columnas]) = '') then
               ShowMessage('No puedo convertir el valor del renglon '+IntToStr(rengloses)+ 'y columna '+IntToStr(columnas)+' porque esta vacio');
            else
               ShowMessage('No puedo convertir el valor '+ StringGrid1.Cells[renglones,columnas] + ' del renglon '+IntToStr(rengloses)+ 'y columna '+IntToStr(columnas));
            totmes[columnas] := 0;
         end;
      end;
   end;
end;

ecfisa 13-02-2011 12:14:16

Hola JLMN22.

Estuve mirando tu código y dos motivos causan tus errores.

(Error de conversión)
Si lees la propiedad Cells de TStringGrid, verás que no es: [Fila, Columna], sino:[Columna, Fila].
Cuando haces:
Código Delphi [-]
  for renglones:=0 to 3 do 
    for columnas:=0 to 2 do 
      totsuc[renglones]:=totsuc[renglones]+
          strtofloat(stringgrid1.Cells[renglones,columnas]);
y la variable 'renglones' alcanza el valor 3, es lógico que allí haya un espacio vacío por que esa es la posición de los meses y estos sólo tendrían que alcanzar el valor 2. Ojalá hubiesen sido 4 meses... :)

Entonces lo correcto sería:
Código Delphi [-]
 for renglones:=0 to 3 do 
    for columnas:=0 to 2 do 
      totsuc[renglones]:=totsuc[renglones]+
          strtofloat(stringgrid1.Cells[columnas, renglones]);

Ahora tenés otro error, que lógicamente aún no has podido descubrir...:)
Si miramos la declaración de los arreglos
Código Delphi [-]
var
 totsuc: array [1..4] of real;
 promsuc: array [1..4] of real;
 totmes: array [1..3] of real;
 prommes: array [1..3] of real;
y los valores en que inician y finalizan los for, no nos dan las cuentas...
Empiezan en una posición inexistente(0) y terminan una posición antes(3) como por ejemplo: totsuc. Cuando recorremos los arreglos tenemos que sumar 1 tanto a filas como a columnas.

Bueno, resumiendo:
Código Delphi [-]
procedure TForm1.CalcularClick(Sender: TObject);
var
  totsuc: array [1..4] of real;
  promsuc: array [1..4] of real;
  totmes: array [1..3] of real;
  prommes: array [1..3] of real;
  Suc, Mes:integer;
  Aux: Double;
begin
  for Suc:= 0 to 3 do
   for Mes:= 0 to 2 do
     if TryStrToFloat(StringGrid1.Cells[Mes,Suc],Aux) then
       totsuc[Suc+1]:= totsuc[Suc+1] + Aux
     else
     begin
       ShowMessage(Format('Error: Sucursal: %d, Mes: %d',[Suc+1,Mes+1]));
       StringGrid1.Col:= Mes;  // Posicionar en la celda,
       StringGrid1.Row:= Suc; // donde se produjo el error
       Exit; // Salir
     end;

  for Suc:= 0 to 3 do
    promsuc[Suc+1]:= totsuc[Suc+1]/3;

  for Suc:= 0 to 3 do
    for Mes:= 0 to 2 do // TryStrToFloat no es necesario, ya se controló arriba
       totmes[Mes+1]:= totmes[Mes+1]+StrToFloat(StringGrid1.Cells[Mes, Suc]);

  for Mes:= 0 to 2 do
   prommes[Mes+1]:=totmes[Mes+1]/4;

  for Suc := 0 to 3 do
  begin
    listbox1.Items.Add(floattostr(totsuc[Suc+1]));
    listbox1.Items.Add(floattostr(promsuc[Suc+1]));
  end;

  for Mes := 0 to 2 do
  begin
    listbox3.Items.Add(floattostr(totmes[Mes+1]));
    listbox4.Items.Add(floattostr(prommes[Mes+1]))
  end;
end;

Para evitar posibles errores de conversión en el ingreso de los valores, use la función TryStrToFloat, informando sucursal y mes en que se produjo en tal caso.

Otra cosa, el begin / end es innecesario cuando hay una sola instrucción, lo único que logra es oscurecer el código.

No comprobé si el resultado concuerda con la lógica del algorítmo, eso lo dejo a tu buen criterio... :)


Un saludo.

JLMN22 14-02-2011 11:44:50

Cita:

Empezado por duilioisola (Mensaje 390555)
Si quieres más información sobre el error puedes agregarla al mensaje de la exceción

Código Delphi [-]
for renglones:=0 to 3 do
begin
for columnas:=0 to 2 do
begin
try
totmes[columnas] := totmes[columnas] + strtofloat(StringGrid1.Cells[renglones,columnas]);
except
on e:Exception do
begin
{Si falla te mostrara el valor del StringGrid y pondrá el valor a 0}
if (Trim(StringGrid1.Cells[renglones,columnas]) = '') then
ShowMessage('No puedo convertir el valor del renglon '+IntToStr(rengloses)+ 'y columna '+IntToStr(columnas)+' porque esta vacio');
else
ShowMessage('No puedo convertir el valor '+ StringGrid1.Cells[renglones,columnas] + ' del renglon '+IntToStr(rengloses)+ 'y columna '+IntToStr(columnas));
totmes[columnas] := 0;
end;
end;
end;
end;



cuando hago eso me sale que no se puedo convertir el valor del renglon 3 y columna 0 por que esta vacio.

duilioisola 14-02-2011 12:55:02

Cita:

cuando hago eso me sale que no se puedo convertir el valor del renglon 3 y columna 0 por que esta vacio.
Por lo visto en el renglon 3 columna 0 está vacío. Revisa que es lo que tienes en esa posicion

Mira lo que te comenta ecfisa en el post anterior.
Cita:

Si lees la propiedad Cells de TStringGrid, verás que no es: [Fila, Columna], sino:[Columna, Fila].

JLMN22 15-02-2011 11:16:29

Ahora me da fallo la suma por sucursal y promedio por sucursal
 
El resto de cosas concuerdan pero ahora el fallo es la suma por sucursal y promedio opr sucursal que dan mal el calculo. Dejo mi codigo:
procedure TForm1.CalcularClick(Sender: TObject);
var
totsuc: array [1..4] of real;
promsuc: array [1..4] of real;
totmes: array [1..3] of real;
prommes: array [1..3] of real;
columnas:integer;
renglones:integer;
begin

for renglones:=0 to 3 do begin
for columnas:=0 to 2 do begin
totsuc[renglones+1]:=totsuc[renglones+1]+strtofloat(stringgrid1.Cells[columnas,renglones]);
end;
end;
for renglones:=0 to 3 do begin
promsuc[renglones+1]:=totsuc[renglones+1]/3;
end;

for renglones:=0 to 3 do begin
for columnas:=0 to 2 do begin
totmes[columnas+1]:=totmes[columnas+1]+strtofloat(stringgrid1.Cells[columnas,renglones]);
end;
end;
for columnas:=0 to 2 do begin
prommes[columnas+1]:=totmes[columnas+1]/4;
end;
for renglones := 0 to 3 do begin
listbox1.Items.Add(floattostr(totsuc[renglones+1]));
listbox2.Items.Add(floattostr(promsuc[renglones+1]));
end;
for columnas := 0 to 2 do begin
listbox3.Items.Add(floattostr(totmes[columnas+1]));
listbox4.Items.Add(floattostr(prommes[columnas+1]))

end;
end;
end.

ecfisa 15-02-2011 12:41:19

Hola JLMN22.

Por favor, tratá de usar las etiquetas [delphi] y [/delphi] para encerrar el código Delphi que pongas en los mensajes,
de ese modo se hace mucho más legible. [ Uso de Etiquetas vB ]

Un saludo.

JLMN22 15-02-2011 12:49:52

Ya he puiesto con etiquetas, espero que este bien
 
Código Delphi [-]
 
procedure TForm1.CalcularClick(Sender: TObject);
var
totsuc: array [1..4] of real;
promsuc: array [1..4] of real;
totmes: array [1..3] of real;
prommes: array [1..3] of real;
columnas:integer;
renglones:integer;
begin

for renglones:=0 to 3 do begin
for columnas:=0 to 2 do begin
  totsuc[renglones+1]:=totsuc[renglones+1]+strtofloat(stringgrid1.Cells[columnas,renglones]);
end;
end;
for renglones:=0 to 3 do begin
promsuc[renglones+1]:=totsuc[renglones+1]/3;
end;

for renglones:=0 to 3 do begin
for columnas:=0 to 2 do begin
totmes[columnas+1]:=totmes[columnas+1]+strtofloat(stringgrid1.Cells[columnas,renglones]);
end;
end;
for columnas:=0 to 2 do begin
prommes[columnas+1]:=totmes[columnas+1]/4;
end;
for renglones := 0 to 3 do begin
listbox1.Items.Add(floattostr(totsuc[renglones+1]));
listbox2.Items.Add(floattostr(promsuc[renglones+1]));
end;
for columnas := 0 to 2 do begin
listbox3.Items.Add(floattostr(totmes[columnas+1]));
listbox4.Items.Add(floattostr(prommes[columnas+1]))

end;
end;
end.

ecfisa 15-02-2011 16:30:16

Hola JLMN22.

Esta muy bién. Muchas gracias por tu colaboración.

Un saludo.

JLMN22 16-02-2011 11:51:07

Cita:

Empezado por ecfisa (Mensaje 391005)
Hola JLMN22.

Esta muy bién. Muchas gracias por tu colaboración.

Un saludo.

Menos masl que por fi he acertado, pero tengo el problema que he comentado anteriormente, el fallo es la suma por sucursal y promedio opr sucursal que dan mal el calculo


La franja horaria es GMT +2. Ahora son las 05:27:28.

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