Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Acerca de CommaText (https://www.clubdelphi.com/foros/showthread.php?t=17725)

JuanBCT 19-01-2005 16:02:34

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!

Héctor Randolph 19-01-2005 20:51:20

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. :confused:


Espero que te sea útil, un Saludo.

JuanBCT 19-01-2005 21:20:50

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!

JuanBCT 21-01-2005 16:22:42

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...

Lepe 22-01-2005 14:20:50

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

JuanBCT 26-01-2005 20:28:55

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...

Lepe 27-01-2005 11:49:17

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

JuanBCT 27-01-2005 15:35:41

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...

Lepe 27-01-2005 16:42:51

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

JuanBCT 27-01-2005 19:19:34

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!!!

Lepe 28-01-2005 13:16:28

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

Chogo 16-07-2013 18:49:52

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;


La franja horaria es GMT +2. Ahora son las 10:56:00.

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