PDA

Ver la Versión Completa : Se puede hacer un else en un While not query1.eof Do?


negrokau
17-10-2011, 15:27:20
hola a todos, tengo un inconveniete con un BUCLE, quiero ponerle un else a un While not query1.eof do pero me salta este error:

'END' expected but 'ELSE' found

Este es bucle que quiero utilizar:


query1.First;
While not query1.Eof Do
Begin

if cod_barra.text=query1.fieldvalues['cod_barra'] then
begin
showmessage('el codigo ingresado ya existe');
cod_barra.setfocus;
end;

query1.Next
end else

guardar.click;



la idea de este bucle es que busque si el codigo ingresado no se repite en la base de datos...
me darian alguna sugerencia? o alguna forma de modificarla para que me funcione, ya probe de muchas
maneras sin usar ELSE pero no pude resolverlo

Desde ya muchas gracias.....

Casimiro Notevi
17-10-2011, 15:28:47
Está mal anidado los if then begin end ;)
Fíjate bien...

negrokau
17-10-2011, 15:37:48
ya lo corregi.... pero igual da el mismo error.... :(

roman
17-10-2011, 15:54:30
Y ¿por qué no nos muestras como lo "corregiste"? :p

// Saludos

negrokau
17-10-2011, 16:02:44
if cod_barra.text<>null then
begin
query1.close;
query1.params[0].value:=dm.stock.fieldvalues['cod_barra'];
query1.open;
query1.First;
While not (query1.Eof) Do
Begin

if cod_barra.text=query1.fieldvalues['cod_barra'] then
begin
showmessage('el codigo ingresado ya existe');
cod_barra.setfocus;
end;

query1.Next
end else

guardar.click;
end;
Asi esta mi proceso..... ya lo mire muchas veces y creo que esta bien desde mi punto de vista... corrijanme nomas si deje pasar algo... gracias

oscarac
17-10-2011, 16:06:18
eres conciente de que el else despues del end del while... es del primer if verdad?
en todo caso para que hacer un do while si estas verificando si el codigo ingresado existe via un query

Casimiro Notevi
17-10-2011, 16:07:03
While not (query1.Eof) Do
Begin
if cod_barra.text=query1.fieldvalues['cod_barra'] then
begin
showmessage('el codigo ingresado ya existe');
cod_barra.setfocus;
end;

query1.Next
end else

guardar.click;
end;


¿y ese código de dónde viene?

roman
17-10-2011, 16:07:47
Si indentaras el código apropiadamente sería más fácil de ver. Te falta el end del if exterior. Lo tienes que poner justo despúés del end del while.

// Saludos

Delphius
17-10-2011, 16:23:46
Lo que sucede aquí es una incompresible falta de atención y lectura a la sintaxis y gramática de Pascal. Con todo respeto.

TODA instrucción debe finalizar con ;
TODO begin debe ir con su correspondiente end
El error se debe a un cierre prematuro debido a un punto y coma colocado después del end de la parte then.

Un IF se "cierra" colocando el ; al final.

Es decir:

IF (condicion)
then instruccion;

IF (condición)
then begin
instrucciones;
end;

IF (condición)
then instrucción // aqui no va ; porque tiene parte else
else instrucción; // aquí si va ;. finaliza el IF

Simple: Repasar gramática y sintaxis.

Saludos,

roman
17-10-2011, 16:27:36
TODA instrucción debe finalizar con ;


Bueno, esto, de hecho, no es cierto :p En pascal, el punto y coma es un separador de instrucciones, no un terminador.

// Saludos

Casimiro Notevi
17-10-2011, 16:37:15
Hay alguna excepción a la norma, ejemplo:

procedure TFregistroIVA.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DS1.DataSet.Close // <--- No hace falta el punto y coma
end;

roman
17-10-2011, 16:47:58
No es una excepción, es sólo que, al no haber sentencia posterior, no es necesario. Como dije, en pascal el punto y coma no termina, separa. Cosa, por ejemplo, que no ocurre en C, en donde el punto y coma sí es un terminador.

// Saludos

oscarac
17-10-2011, 16:49:51
sin temor a equivocarme... lo que negrokau quiere hacer es validar si un codigo ya existe
pero me parece que no lo esta haciendo correctamente

podrias usar el evento ONValidate en el campo y ahi mismo podrias verificar mediante un query si el codigo existe o no
a mi parecer el do while esta de mas (salvo que en el query te jale varios registros iguales :S)

negrokau
17-10-2011, 16:55:14
Código Delphi [-] (http://www.clubdelphi.com/foros/#)
While not (query1.Eof) Do
Begin
if cod_barra.text=query1.fieldvalues['cod_barra'] then
begin showmessage('el codigo ingresado ya existe');
cod_barra.setfocus;
end;
query1.Next
end else
guardar.click;
end;


¿y ese código de dónde viene?

el end else es del while... corre bien el bucle, encuentra si ya existe el codigo, pero si no existe tiene que
guardar, es por eso que quiero poner un else al while...

roman
17-10-2011, 16:58:58
A ver, un while no lleva un else. Punto.

Ahora, como ya te han observado, más allá del error propiamente sintáctico, tienes un error de concepto. No necesitas recorrer los resultados de una consulta para determinar que un código ya se ha introducido. Únicamente necesitarías saber si la consulta regresa por lo menos un registro, para lo cual cuentas con la propiedad IsEmpty del Query.

// Saludos

Delphius
17-10-2011, 17:12:47
Bueno, esto, de hecho, no es cierto :p En pascal, el punto y coma es un separador de instrucciones, no un terminador.

// Saludos
Bueno... es un decir :D . Por algo dije más adelante: Un IF se "cierra" :p

El "terminador" que se me ocurre es el punto:

end.

Jeje :D

Saludos,

negrokau
17-10-2011, 17:22:15
if cod_barra.text<>null then
begin
query1.close;
query1.params[0].value:=dm.stock.fieldvalues['cod_barra'];
query1.open;
query1.First;
While not (query1.Eof) Do
Begin

if cod_barra.text=query1.fieldvalues['cod_barra'] then

showmessage('el codigo ingresado ya existe');
cod_barra.setfocus;
query1.Next;

end;

guardar.click;
end;

Ya tengo claro que el while no lleva else.
Ahora el problema que tengo es que al encontrar un mismo codigo tendria que el focus posicionarse en cod_barra, pero igual recorre todo el algoritmo y guarda..., como le hago para que no guarde si encuentra un mismo codigo y que el focus se situe en cod_barra...

negrokau
17-10-2011, 17:23:50
sin temor a equivocarme... lo que negrokau quiere hacer es validar si un codigo ya existe
pero me parece que no lo esta haciendo correctamente

podrias usar el evento ONValidate en el campo y ahi mismo podrias verificar mediante un query si el codigo existe o no
a mi parecer el do while esta de mas (salvo que en el query te jale varios registros iguales :S)

y como uso el evento ONValidate? nunca le use, por eso no lo conozco...

oscarac
17-10-2011, 17:31:39
yo lo tengo mas o menos asi


procedure TfrmCatalogoArticulo.qryArticuloKODValidate(
Sender: TField);
dmComedor.qryVerificaKodArticulo.Parameters.ParamByName('KOD').Value := Sender.Value;
dmComedor.qryVerificaKodArticulo.Open;
if not dmComedor.qryVerificaKodArticulo.IsEmpty then
begin
MessageDlg('Código ya creado', mtError, [mbAbort], 0);
dmComedor.qryVerificaKodArticulo.Close;
Abort;
end;
dmComedor.qryVerificaKodArticulo.Close;



como ubicas el ONvalidate?
en el query o tabla donde estas grabando la informacion le das doble click al componente y te salen los campos persistentes.. en el campos en el cual pretendes grabar el "codigo", busca en el object inspector.. el evento Onvalidate... ahi colocas el codigo para verificar si existe o no

Casimiro Notevi
17-10-2011, 17:35:33
Debes explicar primero EXACTAMENTE qué quiéres hacer, porque ese while, aparentemente, no sirve para nada, como ya han comentado.

negrokau
17-10-2011, 17:54:47
Debes explicar primero EXACTAMENTE qué quiéres hacer, porque ese while, aparentemente, no sirve para nada, como ya han comentado.

Lo que quiero que haga exactamente es que busque si el codigo ingresado ya existe, si ya existe me salte el mensage y que el focus se posiciones en cod_barra para cambiar el codigo:


if cod_barra.text=query1.fieldvalues['cod_barra'] then
showmessage('el codigo ingresado ya existe');
cod_barra.setfocus;

si no existe el codigo que guarde:


guardar.click;


se entiende ahora lo que quiero hacer?

oscarac
17-10-2011, 17:57:16
entonces guiate del ejemplo que te di usando Onvalidate

la diferencia es que el mensaje te lo manda cuando sale del campo

Loviedo
17-10-2011, 18:02:40
Imagino que está comprobando un Edit.text con el valor de un Campo.
Creamos una variable booleana (existe). Si lo encuentra sal del bucle.



existe := false;

query1.First;
While not query1.Eof Do
Begin
if cod_barra.text=query1.fieldvalues['cod_barra'] then
begin
showmessage('el codigo ingresado ya existe');
existe := true;
cod_barra.setfocus;
break;
end;
query1.Next;
end;

if not existe then
guardar.click;



Otra opción es comprobar previamente con un select si existe el cod_barra.

oscarac
17-10-2011, 18:24:40
Imagino que está comprobando un Edit.text con el valor de un Campo.
Creamos una variable booleana (existe). Si lo encuentra sal del bucle.


Loviedo si bien es cierto el codigo de Negrokau podria funcionar... lo que pretendo (al menos yo) es mostrarle la mejor opcion para que pueda validar si un campo esta repetido o no... hay muchas formas (si alguien con mas capacidad que yo pudiera mostrarnos otra bienvenida)
por eso menciono que el While esta demas

negrokau
20-10-2011, 17:46:04
yo lo tengo mas o menos asi

Código Delphi [-] (http://www.clubdelphi.com/foros/#)
procedure TfrmCatalogoArticulo.qryArticuloKODValidate( Sender: TField);
dmComedor.qryVerificaKodArticulo.Parameters.ParamByName('KOD').Value := Sender.Value;
dmComedor.qryVerificaKodArticulo.Open;
if not dmComedor.qryVerificaKodArticulo.IsEmpty then
begin
MessageDlg('Código ya creado', mtError, [mbAbort], 0);
dmComedor.qryVerificaKodArticulo.Close;
Abort;
end;
dmComedor.qryVerificaKodArticulo.Close;


como ubicas el ONvalidate?
en el query o tabla donde estas grabando la informacion le das doble click al componente y te salen los campos persistentes.. en el campos en el cual pretendes grabar el "codigo", busca en el object inspector.. el evento Onvalidate... ahi colocas el codigo para verificar si existe o no

hola oscarac, me podrias explicar un poco mejor como configurar? te lo agradeceria...

ecfisa
20-10-2011, 23:01:56
Hola negrokau.

Una opción de búsqueda es mediante un while como intentaste en tu mensaje inicial:

var
Found: Boolean;
begin
query1.First;
Found:= False;
while not query1.Eof and not Found do
begin
Found:= cod_barra.Text = query1.FieldValues['cod_barra'];
query1.Next;
end;
if not Found then
guardar.Click;
...

Creo que el error en tu primer código, parte de la confusión que tenés con las estructuras de control.
Como yá te han dicho más arriba, una cosa es una estructura decisión (if/then/else) y otra una de iteracion (for, while, repeat) aunque las dos últimas puedan evaluar alguna condición.

La otra opción, más eficiente, es mediante una consulta SQL:

function ExisteCodigo(const Value: string): Boolean;
begin
with TQuery.Create(nil) do
try
DatabaseName:= 'NOMBRE_DE_TU_BD'; // Alias (o Ruta a donde esta la tabla)
SQL.Text:= 'SELECT * FROM TU_TABLA WHERE COD_BARRA = :DATO'; // Cambia 'TU_TABLA' por tu nombre de tabla
ParamByName('DATO').AsString:= Value;
Open;
Result:= not IsEmpty;
Close;
finally
Free;
end;
end;

De esta manera tu código inicial queda reducido a:

if not ExisteCodigo(cod_barra.Text) then
guardar.Click;


Un saludo.

negrokau
22-10-2011, 01:29:22
disculpame la ignorancia amigo... pero como nunca hice como esta en el ejemplo que me diste... en donde lo coloco la consulta?

function ExisteCodigo(const Value: string): Boolean;
begin
with TQuery.Create(nil) do
try
DatabaseName:= 'C:\SGC v1.0\Database\SGC_v1.GDB'; // Alias (o Ruta a donde esta la tabla)
SQL.Text:= 'SELECT * FROM FACTURAS WHERE COD_BARRA = :DATO'; // Cambia 'TU_TABLA' por tu nombre de tabla
ParamByName('DATO').AsString:= Value;
Open;
Result:= not IsEmpty;
Close;
finally
Free;
end;
end;

Casimiro Notevi
22-10-2011, 10:16:52
Donde quieras, da igual.
Tan sólo recuerda que además deberás declarar la function en la sección private (arriba, al principio del código).

private
function ExisteCodigo(const Value: string): Boolean;

Y ese código, esa function, la pones por ejemplo, al final del todo.

negrokau
22-10-2011, 14:53:42
lo estoy probando pero me salta este error:
Declaration expected but identifier 'private' found
algo no estoy haciendo bien creo....

Casimiro Notevi
22-10-2011, 15:13:54
¿Dónde lo has puesto?.

El código, pega tu código, que no somos adivinos ;)
_______________________________||
_______________________________\/

ecfisa
23-10-2011, 00:29:16
Hola negrokau.

Declararlo como un método como te indica Casimiro es la mejor opción ya que no importa la posición donde ubiques el código de la función:

unit Unit1;

interface

uses
Windows, Messages,...;

type
TForm1 = class(TForm)
...
private
function ExisteCodigo(const Value: string): Boolean;
public
end;

var
Form1: TForm1;

implementation {$R *.dfm}

// aca el resto de tu codigo

function TForm1.ExisteCodigo(const Value: string): Boolean;
begin
with TQuery.Create(nil) do
try
DatabaseName:= 'C:\SGC v1.0\Database\SGC_v1.GDB';
SQL.Text:= 'SELECT * FROM FACTURAS WHERE COD_BARRA =:DATO';
ParamByName('DATO').AsString:= Value;
Open;
Result:= not IsEmpty;
Close;
finally
Free;
end;
end;

// o, si preferís aca el resto de tu codigo

end.


Otra opción es declararlo como función, pero para ello, la cabecera debe estar declarada antes del método o función que la invoque. Para asegurar el tiro, inmediatamente después a la declaración Implementation, de ese modo la función, tendrá alcance a todo código subyacente a ella:

...
Implementation

function ExisteCodigo(const Value: string): Boolean;
begin
...


Saludos.