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)
-   -   Consulta con ADOTABLE (https://www.clubdelphi.com/foros/showthread.php?t=83417)

nefore 15-06-2013 20:37:19

Consulta con ADOTABLE
 
Hola, estoy trabajando con una BD de Access 2007 en Delphi 7. Necesito una funcion busca, la cual me devuelva verdadero si encuentra un determinado valor. Los criterios de busqueda son por Codigo, DNI, y por Nombre.
El codigo es el siguiente:

Código:

type
    Tclasepropietario = class (Tclasepersona)
    codigo_titular: Integer;
    sexo: string;
    fecha_modificacion: TDate;
    fecha_desde: TDate;

    Procedure grabardatos;
    function busqueda (dato:string;opcion:Integer):Boolean;
end;

Implementation

function Tclasepropietario.busqueda(dato: string; opcion: Integer): Boolean;
begin
  ADOTable1.Filtered := True;
  case opcion of

  1: begin
      ADOTable1.Filter:= 'CODIGO_TITULAR LIKE '''+'%'+dato+'%''';
      if (ADOTable1.RecordCount > 0)
        then
          begin
            Result:=True;
          end
        else;
        begin
            Result:=False;
          end;
    end;
  2: begin
      ADOTable1.Filter:='DNI LIKE '+dato+'';
      if (ADOTable1.RecordCount > 0)
        then
          begin
            Result:=True;
          end
        else;
        begin
            Result:=False;
          end;
      end;
  3: begin
      ADOTable1.Filter:='APELLIDO_NOMBRES LIKE '''+dato+'*''';
      if (ADOTable1.RecordCount > 0)
        then
          begin
            busqueda:=True;
          end
        else;
        begin
            busqueda:=False;
          end;
      end;
  end;
end;

En donde dato seria por ejemplo un edit, el cual posee segun lo que vaya a buscar, y opcion seria un "case" que manejo internamente para seleccionar que tipo de busqueda quiero realizar. Pues bien, a todo esto mi problema es que, en el caso del DNI y del CODIGO, en la tabla estan cargados como numeros y aca el parametro dato es string, y cuando por ejemplo realizo un alta de Propietarios necesito saber si el DNI ingresado ya esta cargado o no, pero al momento de llamar a la funcion me salta un error de "No se pudo abrir el filtro" mi duda es ¿existe alguna forma de que la consulta sql me convierta a numero el string "dato" y como seria?

ecfisa 15-06-2013 23:39:21

Hola nefore, bienvenido a Club Delphi :)

Como a todos los recién llegados te invitamos a que leas nuestra guía de estilo.

Yo haría:
Código Delphi [-]
function Tclasepropietario.Busqueda(const aFieldName, aValue: string): Boolean;
begin
  with ADOTable1 do
  begin
    Filtered := False;
    Filter   := '(' + aFieldName + ' LIKE ' + QuotedStr('*' + aValue + '*') + ')';
    Filtered := True;
    Result   := RecordCount > 0;
  end;
end;

Ejemplo de llamada:
Código Delphi [-]
  if Busqueda('CODIGO_TITULAR', '0006') then
   ...

Saludos. :)

nefore 16-06-2013 02:32:13

Te agradezco la bienvenida, y por tu tiempo para responder. Antes de escribir este post he pegado un vistazo a la guia de estilos, si he rompido alguna norma hazmelo saber.
Te pido disculpas, pero recien estoy empezando en esto, asi que no entiendo muy bien. La constate aFieldName es necesaria que este asi? o sea yo estoy haciendo un alta de propietarios, y quiero usar este busca, para evitar un dni duplicado me explico? (los demas: codigo titular y nombre los usare para realizar una consulta). Segun lo que yo entiendo estas pasando una constante como parametro? y la propiedad(?) Filtered, primero tengo que desactivarla?

He intentando el codigo me pasaste pero, no me deja compilar, me dice incompatible types

ecfisa 16-06-2013 03:44:47

Hola nefore.
Cita:

Te agradezco la bienvenida, y por tu tiempo para responder. Antes de escribir este post he pegado un vistazo a la guia de estilos, si he rompido alguna norma hazmelo saber.
No, no has roto ninguna regla, es un recordatorio que siempre se les hace a los que publican su primer mensaje. :)

Cita:

La constate aFieldName es necesaria que este asi?
El que los parámetros estén declarados como constantes es a fines de optimización, funcionara del mismo modo quitando el calificador. Y el sentido de enviar como argumento el nombre del campo es para evitar la evaluación del índice (opción) dentro de la función.
Cita:

o sea yo estoy haciendo un alta de propietarios, y quiero usar este busca, para evitar un dni duplicado me explico?
Para ese caso es mas simple usar el método Locate:
Código Delphi [-]
begin
  if ADOTable1.Locate('DNI', Edit1.Text,[]) then
  begin
    MessageBox(Handle,'Ya existe un propietario con ese DNI', '', MB_ICONERROR + MB_OK);
    Exit;
  end;
  //... Continuar con el ingreso

Cita:

He intentando el codigo me pasaste pero, no me deja compilar, me dice incompatible types
Ignoro que tipos estás enviando como argumentos a la función, sería bueno si pusieras la declaración de las variables y la parte del código en que realizas la llamada.
Fijate que los parámetros los declaré de tipo string, partiendo del supuesto que campos tales como APELLIDO_NOMBRES no seran de tipo Integer.

Saludos. :)

nefore 16-06-2013 07:23:49

Cita:

Empezado por ecfisa (Mensaje 462311)
Hola nefore.

No, no has roto ninguna regla, es un recordatorio que siempre se les hace a los que publican su primer mensaje. :)


El que los parámetros estén declarados como constantes es a fines de optimización, funcionara del mismo modo quitando el calificador. Y el sentido de enviar como argumento el nombre del campo es para evitar la evaluación del índice (opción) dentro de la función.

Para ese caso es mas simple usar el método Locate:
Código Delphi [-]
begin
  if ADOTable1.Locate('DNI', Edit1.Text,[]) then
  begin
    MessageBox(Handle,'Ya existe un propietario con ese DNI', '', MB_ICONERROR + MB_OK);
    Exit;
  end;
  //... Continuar con el ingreso


Ignoro que tipos estás enviando como argumentos a la función, sería bueno si pusieras la declaración de las variables y la parte del código en que realizas la llamada.
Fijate que los parámetros los declaré de tipo string, partiendo del supuesto que campos tales como APELLIDO_NOMBRES no seran de tipo Integer.

Saludos. :)

Oh, vaya! muchas gracias el ADOTable.Locate ha funcionado! Lo malo es que he tenido que pasar el dni como string para que lo tome, dado que lo tenia como campo numerico en la BD, y aca paso un string del edit (segun tengo entendio).
Pues bien, me ha servido de mucho para la validacion, pero el problema es que aun asi necesito un metodo para buscar con ADOTable con un filtro o algo asi, porque por ejemplo cuando realize la consulta y pedir buscar por nombre y apellido (o por parte de este), utilizaria el Filtro y mostraria los resultados en un db grid.
Igualmente desde ya muchas gracias, te agradezco por la ayuda (ya me estaba volviendo loco). Un paso menos. :)

ecfisa 16-06-2013 10:09:55

1 Archivos Adjunto(s)
Hola.

Cita:

Pues bien, me ha servido de mucho para la validacion, pero el problema es que aun asi necesito un metodo para buscar con ADOTable con un filtro o algo asi, porque por ejemplo cuando realize la consulta y pedir buscar por nombre y apellido (o por parte de este), utilizaria el Filtro y mostraria los resultados en un db grid.
Si se trata de campos alfanuméricos la función que te puse en el mensaje anterior funciona perfectamente. De tratarse de campos numéricos, tendrás que filtrar por >, <, = ,>=, <=.

Pero creo entender de tu comentario que no has podido implementar la función del mensaje #2 en tu código, por lo cuál te adjunto un demo funcionando para que puedas revisar con tranquilidad el por qué.

Crea una carpeta, descomprimí los fuentes allí y compila. (incluye dbdemos.mdb que trae Delphi)

Saludos. :)

nefore 17-06-2013 20:55:28

Cita:

Empezado por ecfisa (Mensaje 462317)
Hola.


Si se trata de campos alfanuméricos la función que te puse en el mensaje anterior funciona perfectamente. De tratarse de campos numéricos, tendrás que filtrar por >, <, = ,>=, <=.

Pero creo entender de tu comentario que no has podido implementar la función del mensaje #2 en tu código, por lo cuál te adjunto un demo funcionando para que puedas revisar con tranquilidad el por qué.

Crea una carpeta, descomprimí los fuentes allí y compila. (incluye dbdemos.mdb que trae Delphi)

Saludos. :)

Hola muchas gracias por tomarte el tiempo para buscar el arhivo que me pasaste, lo he visto y De verdad agradezco tu paciencia y ayuda. Antes que nada, te pido disculpas me he expresado mal, tu codigo, como dices, no tiene ningun problema cuando es string (como nombre y apellido, y dni lo son), el problema es el campo codigo que es integer, probe colocar el AdoTable1 (que es que esta asociado con la tabla propietarios).Filter: 'DNI ='dato; pero me salta un error de "Parametros Incorrectos, fuera del intervalo permitido o en conflicto con otros'.
Me he fijado el archivo que me pasaste, pero justamente realiza la busqueda por name, capital o continent (campos string) y no por los otros campos numericos:

este es el codigo de la busqueda en el cual esta (entre comentarios) el codigo que me pasaste

Código:

function Tclasepropietario.busqueda(dato: string; opcion: Integer): Boolean;
var
  ban: Boolean;

begin
  ban:= False;
  ADOTable1.Filtered := True;
  case opcion of

  1: begin
      //ADOTable1.Filter:= Format(' = ',[CODIGO_TITULAR,dato]);
      //if (ADOTable1.RecordCount > 0)
      //then
      //begin
      //  ban:= True;
      //end
      //else
      //begin
      //  ban:= False;
      //end;
      if (ADOTable1.Locate('CODIGO_TITULAR',dato,[])=True)then
      ban:=True;
    end;
  2: begin
      if (ADOTable1.Locate('DNI',dato,[])=True)then
      ban:=True;
      end;
  3: begin
      ADOTable1.Filter:='APELLIDO_NOMBRES LIKE '''+dato+'*''';
      if (ADOTable1.RecordCount > 0)
        then
          begin
            ban:=True;
          end
        else;
        begin
            ban:=False;
          end;
      end;
  end;
  busqueda:= ban;
end;

He intentado implementar el codigo #2 pero como te mencione, me sigue saltando el error de "Parametros Incorrectos, Fuera del Intervalo permitido o en conflicto con otros". Lo probe con el ADOTABLE.locate (que me mencionaste despues y ha funcionado), pero cuando muestro el ADO en un DB Grid, no me filtra y me muestra solamente esa persona con el dni o con el codigo que haya escrito; solamente apunta a donde se encuentra ese registro (supongo que es por la misma funcion locate, que no es un filtro en realidad, solo busca el valor y se para alli), no es asi con el nombre el cual efectivamente me filtra los resultados.

En el siguiente codigo, ocurre el mismo error:

Código:

procedure TForm7.FormActivate(Sender: TObject);
begin
propietario:= Tclasepropietario.Create;
propietario.conectaBD;
propietario.ConectaTabla(1);
ADOTable1.Filtered:= True;
ADOTable1.Filter:='BORRADO LIKE FALSO';
DataSource1.DataSet := ADOTable1;
end;

En donde Form7 es el formulario donde realizo la modificacion de propietarios, lo que intento hacer es: en un DB Grid que esta en dicho formulario, mostrar solo aquellos cuyo campo BORRADO sea FALSO (es decir mostrar aquellos propietarios que estan activos), y a partir de ahi buscar por codigo, dni o "apellido y nombre".
Pero como te digo me salta el error mencionado.

ecfisa 17-06-2013 22:29:18

Hola.
Cita:

el problema es el campo codigo que es integer, probe colocar el AdoTable1 (que es que esta asociado con la tabla propietarios).Filter: 'DNI ='dato; pero me salta un error de "Parametros Incorrectos, fuera del intervalo permitido o en conflicto con otros'.
Como te comenté en el mensaje #6:
Cita:

Si se trata de campos alfanuméricos la función que te puse en el mensaje anterior funciona perfectamente. De tratarse de campos numéricos, tendrás que filtrar por >, <, = ,>=, <=.
Cita:

En el siguiente codigo, ocurre el mismo error:

Código Delphi [-]
procedure TForm7.FormActivate(Sender: TObject);
begin
  propietario:= Tclasepropietario.Create;
  propietario.conectaBD;
  propietario.ConectaTabla(1);
  ADOTable1.Filtered:= True;
  ADOTable1.Filter:='BORRADO LIKE FALSO';
  DataSource1.DataSet := ADOTable1;
end;

En el caso de ser un campo lógico también se tiene que accionar de forma diferente:
Código Delphi [-]
procedure TForm1.FilterLogical(const FName: string; const Value: Boolean);
const
  COND : array[Boolean] of string =('''False''','''True''');
begin
  with ADOTable1 do
  begin
    Filtered := False;
    Filter   := Format('%s= %s',[FName, COND[Value]]);
    Filtered := True;
  end;
end;

// LLamada:
...
begin
  FilterLogical('Borrado', True);
  ...
Creo que debes profundizar un poco mas sobre el tema de los filtros.

En el FTP de Club Delphi se encuentra un libro de descarga gratuita en el que se explica cláramente: La cara oculta de Delphi 4 (Capítulo 20).

Saludos. :)


La franja horaria es GMT +2. Ahora son las 15:01:19.

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