Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Ayuda con un buscador en un StringGrid (https://www.clubdelphi.com/foros/showthread.php?t=79456)

Henoc 06-07-2012 05:40:08

Ayuda con un buscador en un StringGrid
 
Buenas noches, mi nombre es Johnatan y tengo una duda amigos

desarrolle un buscador de texto para un stringgrid pero tengo un problema, yo ingreso lo que yo quiera, despues lo busco por su cedula, y al buscar otro item me dice que no existe... ¿me podrian hechar una mano?( El fin de esto es que yo ingreso personas, y las tengo que buscar por su cedula)

este es el codigo de mi busqueda
Código:

void __fastcall TForm10::Button1Click(TObject *Sender)
{
int p;
for (p=1;p<=Form5->StringGrid1->RowCount;p++){
if (Edit1->Text == Form5->StringGrid1->Cells[3][p]){
Form9->Nombre->Text = Form5->StringGrid1->Cells[1][p];
Form9->Apellido->Text = Form5->StringGrid1->Cells[2][p];
Form9->CI->Text = Form5->StringGrid1->Cells[3][p];
ShowMessage("Se ha encontrado al Paciente");
p=0;
Form9->ShowModal();
Close();}
if (Edit1->Text != Form5->StringGrid1->Cells[3][p]){ShowMessage("El Paciente no existe"); Edit1->Text=""; p=0;}
break;
}
}

soy bastante nuevo referente a trabajar con c++ builder y orita es que me estan enseñando en mi universidad, gracias de antemano

ecfisa 06-07-2012 07:14:11

Hola Henoc y bienvenido a Club Delphi :)

Como a todos los que se inician te invitamos a que leas nuestra guía de estilo.

Yo haría:
Código:

#define COL_CEDULA 3 

bool ExistePaciente(TStringGrid *SG, AnsiString Nombre)
{
bool Existe = false;
  for(int i = SG->FixedRows; i < SG->RowCount && !Existe; i++)
    if(SG->Cells[COL_CEDULA][i] == Nombre) Existe = true;
  return Existe;
}

/* Llamada de ejemplo: */
void __fastcall TForm1::btnBuscarClick(TObject *Sender)
{
 if(ExistePaciente(StringGrid1, Edit1->Text))
  ShowMessage("Existe");
 else
  ShowMessage("No existe");
}

Saludos.

Henoc 06-07-2012 16:01:46

Antes de todo, muchas gracias por tu ayuda ecfisa, veo que eres bastante profesional con este programa :)

referente a tu codigo, se lo que quieres hacer, como y con que xD, entendi todo tu codigo pero mi problema es ahora adaptarlo al mio, es decir, no se donde colocar las cosas(como dije soy bastante nuevo en el tema de c++ build referente a puntadores y demas), yo casi que el mes pasado estoy saliendo de pascal xD
mas o menos asi esta arreglado mi codigo:
Cita:

Form5->StringGrid1->Cells[3][x](esta es la columna donde se ubican todas las cedulas)
Form4->Edit1->Text( aqui es donde se compararia el valor ingresado en el stringgrid)
otra cosa, ademas de que tu codigo me da error, me apunta a
Cita:

bool ExistePaciente(TStringGrid *SG, AnsiString Nombre)
y que hace falta o que esperaba un ")"

tambien, y disculpa la molestia, sabrias decirme donde esta el error en mi codigo? (el del post), por que busca una vez perfectamente y a la segunda me dice que no existe?

ecfisa 07-07-2012 09:03:11

1 Archivos Adjunto(s)
Cita:

referente a tu codigo, se lo que quieres hacer, como y con que xD, entendi todo tu codigo pero mi problema es ahora adaptarlo al mio, es decir, no se donde colocar las cosas(como dije soy bastante nuevo en el tema de c++ build referente a puntadores y demas), yo casi que el mes pasado estoy saliendo de pascal xD
...
otra cosa, ademas de que tu codigo me da error, me apunta a
...
y que hace falta o que esperaba un ")"
Hola Henoc.

Te adjunto un ejemplo funcionando para que puedas revisar con tranquilidad como es la estructura y ubicación de funciones y demás.

El ejemplo realiza la búsqueda sobre la columna 3 en cuyas celdas pongo los nombres de meses del año a fin de simplificar ya que el tipo de dato no altera en absoluto el procedimiento de búsqueda. Está realizado en Builder C++ 6.

Saludos. :)

Henoc 07-07-2012 16:51:08

Muchas gracias por tu ayuda eficsa, sinceramente has sido de gran ayuda:), pero si no es molestia se me presento un problema con las fechas..

veras el profesor me mando un buscador "Paciente con fecha de nacimiento iguales a:" y "Pacientes con fecha de nacimiento menores a:"
sinceramente se me ha complicado como no tienes idea, ya eh buscado en google y hasta aqui en el foro xD, asi es como lo eh hecho:

en clases.h tengo esto puesto
Cita:

class Todo{
private:
public:
TDateTime fecha;
int x;
void FNI_Busq(TDateTime fecha ,int x); - Fecha de Nacimiento iguales, asi lo llame
despues en clases .cpp tengo puesto:
Cita:

void Todo::FNI_Busq(TDateTime fecha, int x){
for (x=1;x<=Form5->StringGrid1->RowCount;x++){
if (fecha == StrToDateTime(Form5->StringGrid1->Cells[6][x])){
Form15->StringGrid1->Cells[4][fch] = Form5->StringGrid1->Cells[4][fch];
}
}
};
/// Form5->StringGrid1->Cells[6][x] es donde estan las fechas de nacimiento
///Form15->StringGrid1->Cells[1][x] = Form5->StringGrid1->Cells[1][x]; es donde quiero almacenar la busqueda (col 1 es Nombre del Paciente)

y al final de todo en la forma 15, donde quiero realizar la busqueda con el boton
Cita:

void __fastcall TForm14::Button1Click(TObject *Sender)
{
int x;
fechalol->FNI_Busq(fecha1,x);
Form15->Show();
}
y me sale este error
Cita:

Project Project1.exe raised exception class EAccessViolation with message 'Access Violation at address 004032EE in module 'Project1.exe'. Read of Address 00000030'. Process Stoped
Disculpa la molestia en serio, pero eres el profesional mas cercano que tengo por ahora y sinceramente soy novato xD, el profesor creo que nisiquiera dio eso en clase y lo quiere para el lunes:(

ecfisa 07-07-2012 19:39:32

Hola Henoc.

Segun entiendo el problema se resume a pasar columnas de un TStringGrid (origen) a un TStringGrid (destino), para lo cuál debes basarte en la elección previa de un criterio que puede ser:
  • Nacidos en la misma fecha.
  • Nacidos en fecha previa.

Creo que lo más sencillo es usar un TEdit para ingresar la fecha y un TComboBox para seleccionar el criterio y cuyos Items sean:
  • Igual (0)
  • Menor (1)

Entonces podrías hacer:
Código:

#define COL_FENAC 6

void PacientesXFecha(TStringGrid *Orig, TStringGrid *Dest, TDate aDate, char TC)
{
int n = Dest->FixedRows, r;

  /* Limpiar destino */
  for(r = n; r < Dest->RowCount; r ++) Dest->Rows[r]->Clear();
  /* Copiar datos */
  for( r = Orig->FixedRows; r < Orig->RowCount; r++) {
    // Igual a
    if(TC == 0 && StrToDate(Orig->Cells[COL_FENAC][r]) == aDate) {
      for(int c= Dest->FixedCols; c < Dest->ColCount; c++)
        Dest->Cells[c][n] = Orig->Cells[c][r];
      n++;
    }
    // Menor a
    if(TC == 1 && StrToDate(Orig->Cells[COL_FENAC][r]) < aDate) {
      for(int c= Dest->FixedCols; c < Dest->ColCount; c++)
        Dest->Cells[c][n] = Orig->Cells[c][r];
      n++;
    }
  }
}

Ejemplo de llamada:
Código:

void __fastcall TForm1::btnBuscarClick(TObject *Sender)
{
  PacientesXFecha(Form5->StringGrid1,
                  Form15->StringGrid1,
                  StrToDate(Edit1->Text),
                  ComboBox1->ItemIndex);
}

Saludos.

Josephjht 08-07-2012 18:31:40

y ordeenar los datos por cedula?
 
Cita:

Empezado por ecfisa (Mensaje 436952)
Hola Henoc.

Segun entiendo el problema se resume a pasar columnas de un TStringGrid (origen) a un TStringGrid (destino), para lo cuál debes basarte en la elección previa de un criterio que puede ser:
  • Nacidos en la misma fecha.
  • Nacidos en fecha previa.

Creo que lo más sencillo es usar un TEdit para ingresar la fecha y un TComboBox para seleccionar el criterio y cuyos Items sean:
  • Igual (0)
  • Menor (1)

Entonces podrías hacer:
Código:

#define COL_FENAC 6

void PacientesXFecha(TStringGrid *Orig, TStringGrid *Dest, TDate aDate, char TC)
{
int n = Dest->FixedRows, r;

  /* Limpiar destino */
  for(r = n; r < Dest->RowCount; r ++) Dest->Rows[r]->Clear();
  /* Copiar datos */
  for( r = Orig->FixedRows; r < Orig->RowCount; r++) {
    // Igual a
    if(TC == 0 && StrToDate(Orig->Cells[COL_FENAC][r]) == aDate) {
      for(int c= Dest->FixedCols; c < Dest->ColCount; c++)
        Dest->Cells[c][n] = Orig->Cells[c][r];
      n++;
    }
    // Menor a
    if(TC == 1 && StrToDate(Orig->Cells[COL_FENAC][r]) < aDate) {
      for(int c= Dest->FixedCols; c < Dest->ColCount; c++)
        Dest->Cells[c][n] = Orig->Cells[c][r];
      n++;
    }
  }
}

Ejemplo de llamada:
Código:

void __fastcall TForm1::btnBuscarClick(TObject *Sender)
{
  PacientesXFecha(Form5->StringGrid1,
                  Form15->StringGrid1,
                  StrToDate(Edit1->Text),
                  ComboBox1->ItemIndex);
}

Saludos.



brother y para ordenar estos datos del stringgrid original a uno nuveo ordenandolos por cedula de menor a mayor?


sabes que se tiene varios datos por cada ingreso.

nombre apellido cedula ..... ...... .....

henoc Duran 22222 --- ---- ----

Hector Rodrig 333333 .... .... ...

Juan Campos 12 ---- --- ---


lo que sw quiere es que esto pase a una nueva stringggrid de la siguiente manera.


nombre apellido cedula ..... ...... .....

Juan Campos 12 ---- --- ---

Hector Rodrig 1111 .... .... ...

Hector Rodrig 333333 .... .... ...

Casimiro Notevi 08-07-2012 19:11:58

Cita:

Empezado por Josephjht (Mensaje 436966)
brother y para ordenar estos datos del stringgrid original a uno nuveo ordenandolos por cedula de menor a mayor?

Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración :)

Henoc 03-08-2012 05:41:11

Buenas presento una duda respecto al buscador:

para esta parte del codigo
Cita:

for(int i = SG->FixedRows; i < SG->RowCount && !Existe; i++)
if(SG->Cells[COL_CEDULA][i] == Nombre) Existe = true;
return Existe;
mi duda es: ( i < SG->RowCount) por que ajuro tiene que ser menor? simplemente no puede ser igual? asi de igual si hay 10 registros correria los 10 (1 a 10), pienso que podria ser asi ( i == SG->RowCount) , creo que hay lo estaria igualando ya que si pongo un solo = me dice que posible error, yo entiendo en tu codigo que por ejemplo: son 10 items en el stringgrid, y pongo(i < SG->RowCount) nada mas correria hasta 9 ya que i tiene que ser menor a rowcount.

yo lo entiendo asi:

Cita:

"Para i= a la cantidad de filas arregladas (las que se tildan de una caja gris) ; i sea menor a la cantidad de de filas que haya y que sea diferente( lo del booleano, creo que a eso te refieres con el signo de exclamación); que se sumen i+1"
muchas gracias de antemano y disculpen el testamento

ecfisa 03-08-2012 06:22:21

Hola amigo Henoc.

Cita:

mi duda es: ( i < SG->RowCount) por que ajuro tiene que ser menor? simplemente no puede ser igual?
La razón es que la propiedad Cells, comienza en las posiciones [0][0] y finaliza en las posiciones [ColCount - 1] [RowCount-1].

Cita:

yo entiendo en tu codigo que por ejemplo: son 10 items en el stringgrid, y pongo(i < SG->RowCount) nada mas correria hasta 9 ya que i tiene que ser menor a rowcount.
0 1 2 3 4 5 6 7 8 9 = 10 items.


La mejor forma de respetar las celdas fijas(en gris) para trabajar con un TStringGrid es usar las propiedades FixedCols, FixedRows por ejemplo:
Código:

for(int c = StringGrid1->FixedCols; c < StringGrid1->ColCount; c++ )
    for(int r = StringGrid1->FixedRows; r < StringGrid1->RowCount; r++)
    ...

FixedCols nos devuelve el número de columnas que no son desplazables (celdas en gris). FixedRow hace lo propio para las filas.

Saludos. :)


La franja horaria es GMT +2. Ahora son las 06:27:07.

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