Solved

Convert object properties to delimited string and save results to file

Posted on 2011-03-24
10
688 Views
Last Modified: 2012-05-11
Suppose we have a Customer obj with the following properties:
- Id
- Name
- Address

I would like to Convert object properties to delimited string with a object method like:

function Customer.ToString(const aDelimiter: Char): string;
begin
  //SAmple code for csv, need change to use aDelimiter parameter
  Result := Format("%s,%s,%s",Id, Name, Description);
end;

where aDelimiter can be ",", ";", tab(\t), etc.

Notice that the result string will be stored in a stringlist later on to be output to a file. For example the Pseudo code:
csvList := TStringList.Create;
foreach customer in CustomerList
  csvList.Add(customer.ToString(',');
csvList.SaveToFile("CustomerExport.csv");

There are thousands of lines to store from CustomerList, any ideas on how to make it this export more efficient will be greatly appreciated.
Note: Compiler is still Delphi 7.
0
Comment
Question by:Miguel Oz
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 32

Expert Comment

by:ewangoya
ID: 35212097

I dont think you can get alot more efficiency out of a sequential list. You have to iterate all the objects in any case.
However you can eliminate the saving to stringlist, save it straight to a file, this will be much faster

You could make the object much better by adding the save method to the CustomerList object and let the methods of the List handle the iteration and also set the delimiter once in the CustomerList Object

private
   FDelimiter: Char;
   function GetText: string;
public
    procedure SaveToFile(const AFileName: string);
    .....
    property Delimiter: char read FDelimiter write FDelimiter;
end;





function TCustomerList.GetText;
var
  L, Size, Count: Integer;
  P: PChar;
  S, LB: string;
begin
  Count := GetCount;
  Size := 0;
  LB := #13#10;
  foreach customer in CustomerList
    Inc(Size, Length(Customer.ToString(FDelimiter) + Length(LB));

  SetString(Result, nil, Size);
  P := Pointer(Result);
  foreach customer in CustomerList
  begin
    S := Customer.ToString(FDelimiter;
    L := Length(S);
    if L <> 0 then
    begin
      System.Move(Pointer(S)^, P^, L);
      Inc(P, L);
    end;
    L := Length(LB);
    if L <> 0 then
    begin
      System.Move(Pointer(LB)^, P^, L);
      Inc(P, L);
    end;
  end;
end;


procedure TCustomerList.SaveToFile(const AFileName: string);
var
  Stream: TFileStream;
  S: string;
begin
  Stream := TFileStream.Create;
  try
    S := GetText;
    Stream.WriteBuffer(Pointer(S)^, Length(S));
  finally
    FreeAndNil(Stream);
  end; 
end;

Open in new window

0
 
LVL 35

Author Comment

by:Miguel Oz
ID: 35212119
Your code does not implement Customer.ToString method using the delimiter parameter.
If you can add thta to your answer will be great
Thanks.
0
 
LVL 32

Expert Comment

by:ewangoya
ID: 35212141

Since Delimiter is already a property of the CustomerList and is accessed within the method GetText, you just set and call SaveToFile


  CustomerList.Delimiter := ',';
  CustomerList.SaveToFile('c:\CusomerExport.csv');
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 35

Author Comment

by:Miguel Oz
ID: 35212188
The delimiter is only for the customer properties.
Your posted code use this construct:
Customer.ToString(FDelimiter)
but the implementation (ToString method at Customer object) is not posted. The main objective of this question is how to convert the object to string taking in consideration that this string will be later used in a big list to save it to a file.
0
 
LVL 32

Assisted Solution

by:ewangoya
ewangoya earned 250 total points
ID: 35212238



function Cusomer.ToString(const ADelimiter: string): string;
begin
  Result := Format('%d%s%s%s%s',
      [Id, FDelimiter, Name, FDelimiter, Description]);
end;
0
 
LVL 11

Expert Comment

by:SAMIR BHOGAYTA
ID: 35212301
Hi, this is very useful to you the code is very large so i will give you a link for that

http://www.dotnetperls.com/convert-dictionary-string

http://www.switchonthecode.com/tutorials/csharp-tutorial-serialize-objects-to-a-file
0
 
LVL 25

Expert Comment

by:epasquier
ID: 35213234
You can use a TStringList to build your delimited string. It requires a delimiter, and also a quote in case there can be occurences of the delimiter in the values (the address might contain coma, for example)
the resulting string could then be :

1;John Smith;"123, main street road"
function TCustomer.ToString(Delim:Char=',';Quote:Char='"'):String;
Var
 L:TStringList;
begin
 L:=TStringList.Create;
 L.Delimiter:=Delim;
 L.QuoteChar:=Quote;
 L.Add(IntToStr(ID));
 L.Add(Name);
 L.Add(Address);
 Result:=L.DelimitedText;
 L.Free;
end;

Open in new window

0
 
LVL 35

Author Comment

by:Miguel Oz
ID: 35245682
I use this method:
function Customer.ToString(const AFormat: string): string;
begin
  Result := Format(AFormat,  [Id, Name, Description]);
end;
where  AFormat = '%s,%s,%s'; or any other delimiter I need.Thus the formatiing string is build once and use multiple times

Thank you all for your comments. I will keep the question open a bit longer to see if there is any faster way to do this.
0
 
LVL 25

Accepted Solution

by:
epasquier earned 250 total points
ID: 35260990
You can't get it faster.
Not that it matters anyway, you won't see much difference, even if you use the stringlist Delimited text functionality.
You probably should choose the method to use by considering the ease of coding and maintaining more the speed of execution, as your probable bottleneck is the writing of the file, not the generation of each line. For example, saving each line in a text file line by line instead of all in one SaveToFile will be quicker and consume less memory in the process.
0
 
LVL 35

Author Closing Comment

by:Miguel Oz
ID: 35311226
Guideline without profile backing
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi Form ownership 4 110
delphi parse string to params 3 136
creating threads in delphi 1 130
How to build JSON File in Delphi 6 3 44
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

789 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question