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 19-01-2005
Avatar de JuanBCT
JuanBCT JuanBCT is offline
Miembro
 
Registrado: ago 2004
Ubicación: Campana, Argentina
Posts: 57
Poder: 20
JuanBCT Va por buen camino
Acerca de CommaText

Hola, tengo una pequeña duda con la propiedad Commatext de los Stringlist... espero q me puedan ayudar. Estoy haciendo un procedimiento que toma los datos de una libreta de direcciones del Outlook (exportada a CSV). Primero cargo el archivo en un stringlist; y luego en otro separo por campos, con commatext. El problema que tengo es que los nombres que tienen un espacio en el medio, son separados por commatext igual q si hubiera una coma. Por ej, si yo tengo estas líneas:

Juan,juanbecette81@yahoo.com.ar
Juan José Becette,juanbecette81@yahoo.com.ar


En el primer caso, campos[0] contendría "Juan", y campos[1] contendría "juanbecette81@yahoo.com.ar"; q es precisamente lo que quiero. Pero en el segundo caso, me lo pasaría de la siguiente manera: campos[0]="Juan" y campos[1]="José". ¿Hay algo que esté haciendo mal? En algún mensaje del foro leí que los stringlist tienen una propiedad llamada Delimiter, donde uno especifica el caractér delimitador, pero no lo puedo encontrar (aunque en teoría Commatext separa donde encuentra una coma, no?). Quizás esa propiedad no la encuentre porque uso Delphi 3...

Bueno, voy a estar muy agradecido si alguien me puede ayudar. Les adjunto el código del procedimiento que hice, por si acaso:

Código Delphi [-]
procedure TImport_form.FlatSpeedButton1Click(Sender: TObject);
var
Archivocsv, Campos: Tstringlist;
I: Integer;
begin

//Creo las dos StringList: una contiene el archivo entero, otra los campos...
Archivocsv:=Tstringlist.create;
Campos:=Tstringlist.create;
  try
  //Cargo el archivo a la stringlist Archivocsv...
  Archivocsv.LoadFromFile(Filelistbox1.FileName);
  //Separo cada línea en campos con COMMATEXT y paso c/u al arreglo Campos
  for I:=0 to Archivocsv.Count -1 do
    begin
    Campos.clear;
    Campos.CommaText:=ArchivoCsv[i];

   //Paso c/campo a la tabla
   //Pone nro de cliente automáticamente...
   if Datamodule1.Client.RecordCount=0 then ncli:=0
      else ncli:=Datamodule1.Client['CLI_NUM'];
   Datamodule1.Client.Last;
   Datamodule1.Client.Insert;
   Datamodule1.Client['CLI_NUM']:=ncli + 1;
   //==============================================
    Datamodule1.Client['CLI_NOM']:=Campos[0];
    Datamodule1.Client['CLI_MAIL']:=Campos[1];
    Datamodule1.Client.Post;
    end;
    finally
    Archivocsv.Free;
    Campos.Free;
  end;
end;

Gracias, y saludos!

Última edición por JuanBCT fecha: 19-01-2005 a las 16:05:28.
Responder Con Cita
  #2  
Antiguo 19-01-2005
Avatar de Héctor Randolph
[Héctor Randolph] Héctor Randolph is offline
Miembro Premium
 
Registrado: dic 2004
Posts: 882
Poder: 20
Héctor Randolph Va por buen camino
Hola Juan!

Una posible solución es que generes o modifiques el archivo que contiene los correos de la siguiente manera:

"Juan","juanbecette81@yahoo.com.ar"
"Juan José Becette","juanbecette81@yahoo.com.ar"

Cuando asignas texto a la propiedad CommaText se trabaja con el formato SDF y la cadena es separada por comas o espacios, opcionalmente puedes asignar comillas dobles para separar por bloques como en el ejemplo anterior.

Cita:
Empezado por JuanBCT
En algún mensaje del foro leí que los stringlist tienen una propiedad llamada Delimiter, donde uno especifica el caractér delimitador, pero no lo puedo encontrar (aunque en teoría Commatext separa donde encuentra una coma, no?).
Efectivamente, el componente TStringList maneja dos propiedades para separar texto, CommaText y DelimitedText; son similares excepto que CommaText asume que siempre separas por comas y en DelimitedText opcionalmente puedes definir la propiedad Delimiter para cambiar el caracter que será utilizado para separar en lugar de la coma y también puedes definir QuotedChar para cambiar el caracter que encierra bloques entre comillas.

Cita:
Empezado por JuanBCT
Quizás esa propiedad no la encuentre porque uso Delphi 3...
Alguna vez utilicé Delphi 3, pero no recuerdo si TStringList tenía la propiedad DelimitedText.


Espero que te sea útil, un Saludo.

Última edición por Héctor Randolph fecha: 19-01-2005 a las 20:58:43.
Responder Con Cita
  #3  
Antiguo 19-01-2005
Avatar de JuanBCT
JuanBCT JuanBCT is offline
Miembro
 
Registrado: ago 2004
Ubicación: Campana, Argentina
Posts: 57
Poder: 20
JuanBCT Va por buen camino
Hola Héctor; gracias por tu respuesta!

Voy a probar hacer una rutina que recorra el archivo y que ponga las dobles comillas como me indicaste (ya que el Outlook los saca así, y sería muy engorroso ponerse a hacerlo manualmente)... aparte sigo sin encontrar la propiedad DelimitedText...

Saludos!
Responder Con Cita
  #4  
Antiguo 21-01-2005
Avatar de JuanBCT
JuanBCT JuanBCT is offline
Miembro
 
Registrado: ago 2004
Ubicación: Campana, Argentina
Posts: 57
Poder: 20
JuanBCT Va por buen camino
Saben que acabo de probar en Delphi 5 a ver si me aparecía la propiedad DelimitedText y Delimiter de los stringlist... y siguen sin aparecer! No tendré que declarar algo en el uses, por ejemplo?
Gracias...
Responder Con Cita
  #5  
Antiguo 22-01-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
En la ayuda de delphi viene

Cita:
In TStringList

Capacity
CaseSensitive
Count
Duplicates
Objects
Sorted
Strings

Derived from TStrings

CommaText
DelimitedText
Delimiter

Names
QuoteChar
StringsAdapter
Text
Values
Además son propiedades de un Tstrings, por tanto lo tienen los combobox, listbox. etc.

Saludos
Responder Con Cita
  #6  
Antiguo 26-01-2005
Avatar de JuanBCT
JuanBCT JuanBCT is offline
Miembro
 
Registrado: ago 2004
Ubicación: Campana, Argentina
Posts: 57
Poder: 20
JuanBCT Va por buen camino
Hola! Te muestro lo q aparece en mi Help

In TStringList

Capacity
Count
Duplicates
Objects
Sorted
Strings

Derived from TStrings

CommaText
Names
StringsAdapter
Text
Values



Gracias por tu respuesta, de todas formas...
Responder Con Cita
  #7  
Antiguo 27-01-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Eso me pasa por listillo jejeje, bueno , pues vamos a lo que vamos:

Código Delphi [-]
function DelimitedText(lista:TStringList;Delimiter:char):string;
var i:integer;
begin
  for i:= 0 to lista.count-2 do
     result := result+ lista[i]+ Delimiter;
  if lista.count > 1 then
     result:= result+lista[lista.count-1]
end;

Vas a tener que crear otra rutina para añadir las comillas dobles, pero eso te lo dejo a ti.

Espero que te sirva
Responder Con Cita
  #8  
Antiguo 27-01-2005
Avatar de JuanBCT
JuanBCT JuanBCT is offline
Miembro
 
Registrado: ago 2004
Ubicación: Campana, Argentina
Posts: 57
Poder: 20
JuanBCT Va por buen camino
Hola, Lepe; finalmente solucioné el tema haciendo dicha rutina... les muestro como me quedó el botón "Importar":

Código Delphi [-]
procedure TImport_form.FlatSpeedButton1Click(Sender: TObject);
var
Archivocsv, Campos: Tstringlist;
I: Integer;
S:string;
begin
Datamodule1.Client.Last;
//StringLists para el archivo y para los campos
Archivocsv:=Tstringlist.create;
Campos:=Tstringlist.create;
  try
  //Cargo el archivo a la stringlist Archivocsv...
  Archivocsv.LoadFromFile(Filelistbox1.FileName);
  //Rutina para agregar las doble comillas...
  for I:=1 to Archivocsv.Count -1 do
      begin
      //Paso c/línea a un string para modificarla a mi gusto con insert
      S:=Archivocsv.Strings[i];
       //Modifico...
       Insert('"', S, 1);
       Insert('"', S, (Length(S))+1);
       Insert('"',S,Pos(',',S));
       Insert('"',S,Pos(',',S)+1);
      Archivocsv.Strings[i]:=S;
      end;
  Archivocsv.SaveToFile(Filelistbox1.FileName);
  //---------------------------------------------
  Archivocsv.LoadFromFile(Filelistbox1.FileName);
  //Separo en Campos con COMMATEXT
  for I:=0 to Archivocsv.Count -1 do
      begin
       CoolGauge1.Progress:=I*100 div Archivocsv.Count;
       Campos.clear;
       Campos.CommaText:=ArchivoCsv[i];
       //Paso c/campo a la tabla
       //Pone nro de cliente automáticamente...
       if Datamodule1.Client.RecordCount=0 then ncli:=0
          else ncli:=Datamodule1.Client['CLI_NUM'];
       Datamodule1.Client.Insert;
       Datamodule1.Client['CLI_NUM']:=ncli + 1;
       //==============================================
       Datamodule1.Client['CLI_NOM']:=Campos[0];
       Datamodule1.Client['CLI_MAIL']:=Campos[1];
       Datamodule1.Client.Post;
      end;
     finally
  Archivocsv.Free;
  Campos.Free;
end;
end;

Me queda una inquietud... en el caso que yo quiera incluir la función que me pasaste en el mensaje anterior; como o en q parte lo hago?
Gracias por tu tiempo...
Responder Con Cita
  #9  
Antiguo 27-01-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
En realidad mi funcion ahora no te hace falta, ya que recorres las lineas para poner las comillas dobles,así que aprovecha ese mismo ciclo para poner el separador coma.


Mi funcion simula el DelimitedText y Delimiter que existe en los TStringlist de delphi 6 o superior.

Despues de Releer todo el hilo, no creo que lo necesites; de todas formas te explico como va:

MIStringlist:
Código:
Pepe
Manuel
Jose Manuel
Antonio
y quieres que salga esto:
Código:
Pepe;Manuel;Jose Manuel;Antonio
Esto se consigue con una llamada del tipo:
Código Delphi [-]
var s:string;
s:= DelimitedText(MiStringList,';');

Saludos
Responder Con Cita
  #10  
Antiguo 27-01-2005
Avatar de JuanBCT
JuanBCT JuanBCT is offline
Miembro
 
Registrado: ago 2004
Ubicación: Campana, Argentina
Posts: 57
Poder: 20
JuanBCT Va por buen camino
Estaba interesado en tu función porque ahora me pidieron pasar 3 campos más; me dí cuenta que no lo iba a poder seguir haciendo así porque yo buscaba la coma con la función POS de los string. El inconveniente era q esta devuelve la posición del 1er caracter q uno busca en la línea; ahora q tenía varias comas no iba a poder seguir insertandole comillas!
Pero bueno, lo acabo de solucionar copiando cada "campo" en strings temporales para así ponerles las comillas a c/u y luego concatenar todo; haciendo la línea. Gracias por todo! Les dejo el código final de la procedure q hice, por si a alguno le interesa...

Código Delphi [-]
procedure TImport_form.FlatSpeedButton1Click(Sender: TObject);
var
Archivocsv, Campos: Tstringlist;
I: Integer;
S,A,B,C,D,E,F,G,H,Y:string;
begin
Datamodule1.Client.Last;
//StringLists para el archivo y para los campos
Archivocsv:=Tstringlist.create;
Campos:=Tstringlist.create;
  try
  //Cargo el archivo a la stringlist Archivocsv...
  Archivocsv.LoadFromFile(Filelistbox1.FileName);
  //Rutina para agregar las doble comillas...
  for I:=1 to Archivocsv.Count -1 do
      begin
      //Paso c/línea a un string para modificarla a mi gusto con insert
      S:=Archivocsv.Strings[i];
       //Modifico...
       Insert('"', S, 1);
       Insert('"', S, (Length(S))+1);
       //Pone " antes y después de la 1er coma (ahora tengo q hacer q recorra
        Insert('"',S,Pos(',',S));
        Insert('"',S,Pos(',',S)+1);
        //Voy separando cada campo, y les pongo comillas para luego
        //concatenarlos...
        E:=Copy(S,0,Pos(',',S));

        A:=Copy(S,Pos(',',S)+1,((Length(S))-Pos(',',S)));
        Insert('"',A,Pos(',',A));
        Insert('"',A,Pos(',',A)+1);
        F:=Copy(A,0,Pos(',',A));

        B:=Copy(A,Pos(',',A)+1,((Length(A))-Pos(',',A)));
        Insert('"',B,Pos(',',B));
        Insert('"',B,Pos(',',B)+1);
        G:=Copy(B,0,Pos(',',B));

        C:=Copy(B,Pos(',',B)+1,((Length(B))-Pos(',',B)));
        Insert('"',C,Pos(',',C));
        Insert('"',C,Pos(',',C)+1);
        H:=Copy(C,0,Pos(',',C));
        //D queda como está....
        D:=Copy(C,Pos(',',C)+1,((Length(C))-Pos(',',C)));
        //Ahora, concateno todo en Y
        Y:=concat(E,F,G,H,D);

       Archivocsv.Strings[i]:=Y;
      end;
  Archivocsv.SaveToFile(Filelistbox1.FileName);
  //---------------------------------------------
  Archivocsv.LoadFromFile(Filelistbox1.FileName);
  //Separo en Campos con COMMATEXT
  for I:=0 to Archivocsv.Count -1 do
      begin
       CoolGauge1.Progress:=I*100 div Archivocsv.Count;
       Campos.clear;
       Campos.CommaText:=ArchivoCsv[i];
       //Paso c/campo a la tabla
       //Pone nro de cliente automáticamente...
       if Datamodule1.Client.RecordCount=0 then ncli:=0
          else ncli:=Datamodule1.Client['CLI_NUM'];
       Datamodule1.Client.Insert;
       Datamodule1.Client['CLI_NUM']:=ncli + 1;
       //==============================================
       Datamodule1.Client['CLI_NOM']:=Campos[0];
       Datamodule1.Client['CLI_MAIL']:=Campos[1];
       Datamodule1.Client['CLI_TEL']:=Campos[2];
       Datamodule1.Client['CLI_CALIDAD']:=Campos[3];
       Datamodule1.Client['CLI_TELLAB']:=Campos[4];
       Datamodule1.Client.Post;
      end;
     finally
  Archivocsv.Free;
  Campos.Free;
end;
end;

Saludos!!!

Última edición por JuanBCT fecha: 27-01-2005 a las 19:23:08. Razón: Correción
Responder Con Cita
  #11  
Antiguo 28-01-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
La libreria NKlibs, tiene rutinas para buscar la ocurrencia de un caracter varias veces, además de otras muchas rutinas casi necesarias en el tratamiento de nombres de archivos, busqueda de archivos, strings y algunas cosas más.

Buscala en google.

Código Delphi [-]
// Dada una subcadena y una cadena, hace una búsqueda ultrarápida de la
// subcadena dentro de la cadena, devuelve la posición de la subcadena
// dentro de la cadena, o 0 si no se encontró la subcadena.
// Es igual que Pos, salvo que en vez de una búsqueda secuencial, usa una
// variante de Boyer-Moore (Horspool).
function BMPos(const cPttrn, cTarget: String): Integer;
function BMFirst(const cPttrn, cTarget: String): Integer;
function BMNext(iPos: Integer): Integer;
function BMLast: Integer;

// Dada una cadena devuelve un TStringList con todas las ocurrencias
/// de la subsadena.
function BMAll(const cPttrn, cTarget: String): TStringList;

Saludos
Responder Con Cita
  #12  
Antiguo 16-07-2013
Avatar de Chogo
Chogo Chogo is offline
Miembro
 
Registrado: may 2005
Ubicación: Pto Cortes,Honduras,C.A.
Posts: 148
Poder: 19
Chogo Va por buen camino
Desarrolle este procedimiento, le pasas un String y un TStringList, porque me encontré con el mismo problema de los espacios que se menciona al inicio.
La idea que el StringList nos lo devuelva con varios item.

Código Delphi [-]
procedure TForm2.ComasTexto(str: String; Lista: Tstringlist);
var
  I: Integer;
  cadena:String;
begin
    Lista.Clear;
    cadena:='';
    for I := 1 to Length(str)+1  do
    begin
          if str[i] = ',' then
          begin
               lista.Add(cadena);
               cadena:='';
          end
          else
          begin
               if str[i] =#0 then
               lista.Add(cadena)
               else
               cadena:=cadena + str[i];
          end;
    end;
end;
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


La franja horaria es GMT +2. Ahora son las 18:36:49.


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