Re: processing email-address list with Delphi


Posted by webmaster Guido on November 25, 2002 at 14:35:49:

In Reply to: Re: Flat Files posted by JB ID p12258 on November 24, 2002 at 04:19:26:

Our Org has to be able to have separate lists: students, instructors, announcements, etc.. These lists are simple .txt files but one of the things that happens is that they need to sorted into a single email address per line. And, they may need to be separated, sorted or merged at times as All Students and Instructors on the Announcement lists whereas Students and Instructors are on separate lists.
-----------------

The easiest would be to work with listbox components that contain the addresses, so that you can follow visually what is going on, and check that the program behaves correctly. Below are some tested code examples for working with the "items" (lines) of a listbox.

1. Load the items for the listbox from a textfile, your address list:

procedure TForm1.btnLoadClick(Sender: TObject);
var
  FileName: string;
begin
  FileName := 'C:\Addresses\List1.txt'; // or get filename with TOpenDialog
  ListBox1.Items.LoadFromFile(FileName);
end;

2. Clean up the addresses. The example code below is for only one kind of separators, for example a comma between every address that is on the same line, such as:
ann@abc.com,bill@cde.net,chris@ghi.org
Our example also allows additional blank spaces between the addresses, such as:
ann@abc.com,  bill@cde.net , chris@ghi.org

procedure TForm1.btnCleanClick(Sender: TObject);
const
  Sep = ','; // address separator
var
  NrOfLines, LineNr, SepPos, RestLength: integer;
  AdrLine, Adr: string;
begin
  NrOfLines := ListBox1.Items.Count - 1; // initial number of lines
  for LineNr := 0 to NrOfLines - 1 do begin
    AdrLine := ListBox1.Items[LineNr];
    SepPos := Pos(Sep, AdrLine); // position of first separator
    while SepPos > 0 do begin // as long as separator is found
      // Extract first address from line
      Adr := Copy(AdrLine, 1, SepPos - 1);
      // Remove leading and trailing blanks
      Adr := Trim(Adr);
      if Length(Adr) > 0 then   // don't add empty ones
        ListBox1.Items.Add(Adr);
      // Remove first part from line
      RestLength := Length(AdrLine) - SepPos;
      AdrLine := Copy(AdrLine, SepPos + 1, RestLength);
      // Find position of next separator
      SepPos := Pos(Sep, AdrLine);
    end;
    // Replace listbox item with what is left of addressline
    ListBox1.Items[LineNr] := AdrLine;
  end;
end;

This code does not maintain the original order of the addresses: from each line, we extract the additional addresses if it contains more than one address, and add them to the *end* of the list. Only the *last* address of every line stays at its original position.

If keeping the exact order of the addresses is important, you have to work with two listboxes: extract addresses from the first line of ListBox1 and add them to ListBox2, process the next line, and so on. The code would be very similar, but you would also add the lines with only one address to ListBox2.

3. Sorting a listbox alphabetically:

  ListBox1.Sorted := True;
  ListBox1.Sorted := False;

"Unsorting" is not possible, the original order is not remembered in the listbox. So the second line of code appearently does nothing... but it's very useful nevertheless! Because as long as Sorted is TRUE, items that are added or changed will be positioned automatically. And that's not what you would want while *processing* the list :)

4. Copying addresses from one list to another one, is easy if we use two listboxes: one as the source, one as the destination. Here's how to copy *all* the items from ListBox1 to ListBox2:

  ListBox2.Items.AddStrings(ListBox1.Items);

5. If you just want to copy one item, for example the currently selected item (the item that is highlighted):

var
  LineNr: integer;
begin
  ...
  LineNr := ListBox1.ItemIndex;
  if LineNr >= 0 then  // something must be selected
    ListBox2.Items.Add(ListBox1.Items[LineNr]);

6. Deleting an item from a listbox, for example the currently selected item:

  LineNr := ListBox1.ItemIndex;
  if LineNr >= 0 then  // something must be selected
    ListBox1.Items.Delete(LineNr);

7. Finally, saving the listbox to a file:

  FileName := 'C:\Addresses\NewList.txt'; // or get filename with TSaveDialog
  ListBox1.Items.SaveToFile(FileName);

[ DelphiLand Discussion Forum ]