Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-07-2010
jusaso jusaso is offline
Registrado
 
Registrado: dic 2008
Posts: 5
Poder: 0
jusaso Va por buen camino
RichEdit para comentar las ventajas de un ‘producto’

Tengo un fichero RTF formateado con información de una serie de productos..
(Antes utilizaba un fichero TXT, pero pienso que con RTF puede quedar más 'bonito').
Y deseo algo muy sencillo….
Leer el fichero RTF, seleccionar la información referente a uno de los productos y mostrar esta información en el RichEdit.
Con ficheros de texto es muy fácil hacerlo....
Lo cargo en un array de texto. Localizo las líneas referentes a uno de los productos y las muestro en un MEMO o un LIST.
Pero si lo hago con RichEdit, pierde el formato y me muestra los caracteres ocultos del texto.
He consultado en Google… sin resultado.
Una ayuda…
Gracias.
Responder Con Cita
  #2  
Antiguo 19-07-2010
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola jusas

El problema de la pérdida del formato lo tenés cuando cargas en un arreglo de texto,
lo que luego se mostrará en el RichEdit.

Yo cargaría directamente el archivo .RTF al RichEdit y luego posisionaría en el texto buscado.

Carga:
Código:
procedure CargarRTF;
begin
  RichEdit1.Lines.LoadFromFile('Archivo.RTF');
end;
Busqueda:
Código:
procedure BuscarEnRTF(Producto: string);
  with RichEdit1 do
  begin
    SetFocus;
    SelStart:= Pos(Producto, RichEdit1.Text)-1;
    SelLength:= Length(Producto); 
  end;
end;
Este código sólo te situa en el nombre del producto y lo deja seleccionado. Ahora bién, si sólo
querés mostrar la parte correspondiente al producto y no todo, tendríamos que normalizar de algún
modo la ayuda.
Es decir, señalizar donde comienza y términa la información de cada producto para luego eliminar las
líneas anteriores y posteriores a la información que queres mostrar.


Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 19-07-2010
jusaso jusaso is offline
Registrado
 
Registrado: dic 2008
Posts: 5
Poder: 0
jusaso Va por buen camino
Gracias por la respuesta...

Estoy de acuerdo...
Primero el load para cargar el texto que contiene la descripción de todos los productos.
Un texto que préviamente ha sido escrito en Word para que quede 'bonito'.
Cada descripción del producto quedá separada por una línea en la que aparece el número que tiene asignado cada producto.
De esta manera para buscar el producto 1234...

Código Delphi [-]
nIni:=0;nFin:=0;    //numero lineas ini y fin
for i:=1 to totalLin do
   begin
   if ansipos('1234',textoArray[i])>0 then nini:=i;
   if ansipos('1235',textoArray[i])>0 then begin nFin:=i;break;end;
   end;

Continuamos...
Localizado el texto, se selecciona con...

SelStart:= Pos(Producto, RichEdit1.Text)-1;
SelLength:= Length(Producto);

Donde... selStart sería el inicio del texto pero ¿no falta indicar el final para calcular la longitud?

Y finalmente, una vez seleccionado, habría que borrar el richEdit (richEdit1.clear) y mostrar solo la parte del texto correspondiente.

Gracias anticipadas...

Última edición por jusaso fecha: 19-07-2010 a las 11:28:20.
Responder Con Cita
  #4  
Antiguo 19-07-2010
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 22
Caro Va por buen camino
Hola jusaso, como te dice ecfisa en su codigo de ejemplo solo esta seleccionando el producto por lo que el final es el Length del producto.

No deberías borrar el RichEdit sino trabajar sobre el contenido del mismo RichEdit, yo seleccionaría las líneas que estan antes y despues del texto que se quiere mostrar y eliminarlas.

Código Delphi [-]
procedure BorrarSeleccion;
var
 IniSelect, FinSelect : Integer;
begin
 //Inicio de la selección
 IniSelect := RichEdit1.Perform(EM_LINEFROMCHAR,RichEdit1.SelStart,0);
 //Fin de la selección
 FinSelect := RichEdit1.Perform(EM_LINEFROMCHAR,RichEdit1.SelStart + RichEdit1.SelLength,0);
 
 for i:=IniSelect to FinSelect do
  RichEdit1.Lines.Delete(IniSelect);
end;
...............................................................
...............................................................
...............................................................
 nIni := AnsiPos('1234', Richedit1.Text);
 nFin := AnsiPos('1235', Richedit1.Text);
 
 Richedit1.SelStart := nFin;
 Richedit1.SelLength := Length(Richedit1.Text);
 BorrarSeleccion;
 
 Richedit1.SelStart := 0;
 Richedit1.SelLength := nIni;
 BorrarSeleccion;

el código quedaría mas o menos así, talvez tengas que ajustar algo.

Saluditos
__________________
Disfruten cada minuto de su vida a lado de sus seres queridos como si fuese el ultimo, uno nunca sabe lo que puede pasar.
Responder Con Cita
  #5  
Antiguo 19-07-2010
jusaso jusaso is offline
Registrado
 
Registrado: dic 2008
Posts: 5
Poder: 0
jusaso Va por buen camino
Gracias por sus respuestas.

El código quedaría pues...

Código Delphi [-]
procedure TForm1.Button6Click(Sender: TObject);
var
  nfin,nIni:integer;
begin
 richedit1.Lines.LoadFromFile('GradosBIEN.rtf');
 nIni:=0;
 nFin:=0;
 nIni := AnsiPos('12345', Richedit1.Text);
 nFin := AnsiPos('12346', Richedit1.Text);

 RichEdit1.SetFocus;
 Richedit1.SelStart := nFin;
 Richedit1.SelLength := Length(Richedit1.Text);
 BorrarSeleccion;

 Richedit1.SelStart := 0;
 Richedit1.SelLength := nIni;
 BorrarSeleccion;
end;

procedure TForm1.BorrarSeleccion;
var
 IniSelect, FinSelect,i : Integer;
begin
 //Inicio de la selección
 IniSelect := RichEdit1.Perform(EM_LINEFROMCHAR,RichEdit1.SelStart,0);
 //Fin de la selección
 FinSelect := RichEdit1.Perform(EM_LINEFROMCHAR,RichEdit1.SelStart + RichEdit1.SelLength,0);

 for i:=IniSelect to FinSelect do
  RichEdit1.Lines.Delete(IniSelect);
end;
Y ciertamente funciona.
Pero tiene un problema importante que habría que solucionar.
El documento Word, en su versión RTF, tiene unas cien páginas.
Y tarda varios segundos, bastantes, en cargarse sobre el RichEdit.

El problema se complica cuando esta operación debe repetirse para cada 'producto'.

Por ello, habría que guardar en memoria la totalidad del texto y mostrar en el RichEdit sólo las líneas referentes al artículo seleccionado.

He visto algunos ejemplos que utilizan TMemoryStream o TStringStream pero nunca he tenido que utilizarlos....

Si se os ocurre algo... os lo agradecería.

Un cordial saludo
Responder Con Cita
  #6  
Antiguo 19-07-2010
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola jusaso.

El uso de TMemoryStream no va a acelerar significativamente la carga desde el disco,
que es, a mi criterio el punto álgido del problema.

Tal vez la solución pase por dividir el archivo de ayuda. Podés utilizar el criterio que prefieras;
código, nombre,... buscando una distribución lo más simétrica posible.

En mis pruebas con un Core2Duo y 4 Gb de Ram, con las 100 páginas, obtuve 8 s con la carga directa
del RichEdit, 7s y monedas con MemoryStream. Sin embargo dividiendo el archivo en cinco partes de 20
páginas cada uno la carga no llegó a 1s y la demóra fué casi imperceptible.

Lo que sí, te puede adicionar algunas dificultades al momento de ingresar un nuevo producto y en la
preselección de la ayuda, pero creo que es una solución viable.

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 19-07-2010 a las 20:47:34.
Responder Con Cita
  #7  
Antiguo 19-07-2010
rrf rrf is offline
Miembro
 
Registrado: ago 2003
Ubicación: S/C Tenerife, España
Posts: 454
Poder: 21
rrf Va por buen camino
Wink

Aunque no era para lo mismo exactamente, ante una situación similar, lo que hice fue utilizar 2 richedit.

El primer RichEdit cargaba y mantenía en memoria el contenido del archivo (siendo invisible para el usuario) y el 2º richedit era el que utilizaba para presentar la información seleccionada.

Así se reducía el tiempo de carga de la información porque, después de leer por primera vez el archivo RTF, ya se podía acceder a él directamente, al tenerlo en memoria.

Salu2.

Ramón.
Responder Con Cita
  #8  
Antiguo 20-07-2010
jusaso jusaso is offline
Registrado
 
Registrado: dic 2008
Posts: 5
Poder: 0
jusaso Va por buen camino
Hola ecfisa

Estaba equivocado...
El tiempo de espera no se produce al cargar el texto en RichEdit.
La carga la hace muy rápida.
El problema es debido al tener que borrar una a una todas las líneas sobrantes del RichEdit.....
Tarda mucho en hacerlo.


Código Delphi [-]
for i:=IniSelect to FinSelect do
RichEdit1.Lines.Delete(IniSelect);





Las he anulado y es muy rápido.

La solución cosistiría en borrar todo un bloque de líneas, pero no he visto la forma....

Por otro lado, utilizar dos RichEdit...
Todos los ejemplos que he visto en Google se limitan a copiar el TEXT completo del uno al del otro, sin realizar una selección de líneas, que es lo que buscamos.

Gracias por vuestras ideas....
Responder Con Cita
  #9  
Antiguo 20-07-2010
rrf rrf is offline
Miembro
 
Registrado: ago 2003
Ubicación: S/C Tenerife, España
Posts: 454
Poder: 21
rrf Va por buen camino
Smile

Hola.

Bueno, he revisado el código que hice hace meses y, finalmente, lo hice todo con 1 solo RichEdit, aunque me quedó la idea de que había usado 2.

Bueno, te incluyo el código de la función que escribí. Puede tener algún pequeño error puesto que lo he adaptado para ponerlo aquí, pues el código original no se ajusta del todo a lo que se comenta en este hilo.

Código Delphi [-]
procedure TForm1.Selecciona_seccion_texto ( pp: integer );
var
  num_lin, cc : integer ;
  borra_lin : boolean ;
begin
      // Selecciona_seccion_texto
      //---------------------------

    // Eliminar el texto que no esté entre 2 marcas   (EJ: ENTRE  ,,,---2  y  ,,,---3 )
  outRichEdit1.Visible := false ;
  outRichEdit1.Lines.LoadFromFile( 'Archivo_Ayuda.rtf' );  // adaptarlo al nombre de tu archivo RTF

       // Borra hasta que aparece la marca de inicio del apartado de texto que interesa
  while trim ( outRichEdit1.Lines [ 0 ] ) <> ',,,---' + IntToStr ( pp )
    do outRichEdit1.Lines.Delete( 0 );

  outRichEdit1.Lines.Delete( 0 );   // Elimina la línea del separador

       // Borra desde la marca de inicio del siguiente apartado del texto hasta el final del texto
  borra_lin := false ;
  for cc := 0 to outRichEdit1.Lines.Count -1
   do
    begin

      if trim ( outRichEdit1.Lines [ cc ] ) = ',,,---' + IntToStr ( pp +1 )
        then
          begin
            borra_lin := true ;
            num_lin := cc ;
          end ;

      if borra_lin
        then outRichEdit1.Lines.Delete( num_lin ) ;

    end ;

  outRichEdit1.Visible := true ;
  outRichEdit1.Lines.Insert( 0, '' );  // Esto hace que el cursor
  outRichEdit1.Lines.Delete( 0 );      // quede al inicio del texto
  outRichEdit1.SetFocus ;

end ;

El texto está dividido en partes. Los separadores son ",,,---1", ",,,---2", ",,,---3", ..., ",,,---10", ",,,---11", etc.

El contenido del RichEdit sería algo así:
-----------------------------------------------------
,,,---1
Este es el texto del apartado 1 del texto.
Este es el texto del apartado 1 del texto.
Este es el texto del apartado 1 del texto.
,,,---2
Este es el texto del apartado 2 del texto.
Este es el texto del apartado 2 del texto.
Este es el texto del apartado 2 del texto.
,,,---3
Este es el texto del apartado 3 del texto.
Este es el texto del apartado 3 del texto.
Este es el texto del apartado 3 del texto.
Este es el texto del apartado 3 del texto.
,,,---4
-----------------------------------------------------

El nombre del RichEdit es outRichEdit1.

El parámetro "pp" indica el número del apartado del texto que queremos ver.

A mí me funcionó bastante bien y espero que te sirva.

Saludos.

Ramón.

PD.: Creo que el richedit tiene que tener la propiedad WordWrap a false para que funcione bien. Puede que no sea así (lo digo sin haberlo probado).

Última edición por rrf fecha: 20-07-2010 a las 17:02:44. Razón: añadir un detalle
Responder Con Cita
  #10  
Antiguo 20-07-2010
jusaso jusaso is offline
Registrado
 
Registrado: dic 2008
Posts: 5
Poder: 0
jusaso Va por buen camino
Saludos compañeros

He vuelto a mi planteamiento inicial y parece que ya funciona. Esperemos...

La idea era la siguiente:
Leer el fichero RTF, seleccionar la información referente a uno de los productos y mostrar esta información en el RichEdit.

Pero se perdía el formato del texto.
¿Porqué?
Porque las líneas extraidas necesitan de la información del encabezado del fichero RTF. Lo puedes comprobar cargando el fichero en el IDE de Delphi.

Por lo tanto la tarea consiste en localizar estas líneas y pasarlas al RicheEdit junto con las seleccionadas.

¿Cuales son estas líneas?
Me ha parecido comprobar que el tamaño de las mismaas varía de un RTF a otro.
Así que he utilizado el siguiente truco...
Al principio del fichero RTF pongo una señal: INIFILE.
Las líneas que estén por encima (unas 40) serán la cabecera.

Y las líneas comprendidas entre cada número de producto serán la descripción del mismo.

¡IMPORTANTE!
Conviene dejar una línea en blanco por encima y debajo de cada señal, al redactar el texto en Word. Simplemente por precaución....

Bueno os pongo el código...

Código Delphi [-]
 
procedure TForm1.Button1Click(Sender: TObject);
var
  nfin,nIni: integer;
  nIniFile,i : integer;
  FichRTF,mislineas : TStringList;
begin
  FichRTF:=TStringList.Create;
  mislineas:=TStringList.Create;
  FichRTF.LoadFromFile('TEXT.RTF');
 
  nIniFile:=0;  //fin de la cabecera
  nIni:=0;       //línea comienzo selección
  nFin:=0;      // fin selección
      //localiza las 3 líneas
  for i:=0 to FichRTF.Count-1-1 do
    begin
    if AnsiPos('INIFILE', FichRTF[i])>0 then nIniFile := i;
    if AnsiPos('12345', FichRTF[i])>0 then nIni := i;
    if AnsiPos('12346', FichRTF[i])>0 then begin nFin := i;break;end;
    end;
 
  if (nIniFile=0)or(nIni=0)or(nFin=0) then showmessage ('Problema');
 
       //seleccionamos las líneas de la cabecera
  for i:=0 to nIniFile-1 do
       mislineas.add(FichRTF.Strings[i]);

       //Y la parte del texto comprendido entre 12345 y 12346
  for i:=nIni+1 to nFin-1 do
       mislineas.add(FichRTF.Strings[i]);
 
       //Finalmente pasamos las líneas de texto al RichEdit
  RichEdit1.Text:=mislineas.Text;

end;


Esto es todo.
Seguramente se me escapa algo...

En respuesta al compañero rrf... Pienso que el delete, una a una, de las líneas tiene que ser algo lento si el texto es abundante...

Gracias...
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
synedit como comentar codigo con Ctrl + } JXJ Varios 3 08-03-2010 02:35:38
Hacer Scrol en un RichEdit para abajo fide_uci Varios 2 18-11-2009 17:00:45
Mirar por favor este query y comentar... El_Raso Firebird e Interbase 33 18-11-2008 12:53:44
Jefe de producto de servidores!!!! (para Madrid) jcuesta Varios 1 17-12-2006 18:31:06
Parte de un RichEdit a otro RichEdit (donde esté el cursor) Tomy Varios 3 21-12-2005 21:08:15


La franja horaria es GMT +2. Ahora son las 03:05:20.


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
Copyright 1996-2007 Club Delphi