User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Pascal and Delphi section within the Software Development category of DaniWeb, a massive community of 456,611 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,430 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Pascal and Delphi advertiser: Programming Forums
Views: 5527 | Replies: 46 | Solved
Reply
Join Date: Nov 2007
Posts: 87
Reputation: squidd is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 1
squidd squidd is offline Offline
Junior Poster in Training

Question How to split a large list

  #1  
Nov 5th, 2007
ok so basically I am writing a small program that does a few different things in Delphi 2007. I am very new to coding and so I hope that my terminology will be up to par. If not, please forgive me.

I am loading text files into a ListView... I know arrays can do this much faster, but I am trying to do this in a more visual way. When I load a list of oh, say 15,000 lines... I would like to be able to split the list and then save them into smaller lists. I have an editbox to display how many lines to use for splitting..

For example: I want to split the 15,000 line text file into 250 lines.. or maybe 3,000 lines. I cant for the life of me figure out how to do this.

Once the files are split, then naturally they need to be saved as well.. and that is the other problem.

ANY help on this would be a huge relief!

My code is as follows and is horribly wrong i am WELL aware:

procedure TForm1.Button12Click(Sender: TObject);
var
txt : textfile;
x,y : integer;
begin
savedialog1.Execute();
AssignFile(txt, saveDialog1.FileName + '.txt');
ReWrite(txt);
for x := 0 to ListView1.Items.Count - 1 do
begin
Writeln(txt, ListView1.Items[x].Caption, edit6.text);
end;
end;


As you can see, this is extremely fouled up and I have been trying for hours to figure this out. Thanks for any help in advance.
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,878
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 13
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: How to split a large list

  #2  
Nov 5th, 2007
The choice of TListView is a bit odd to me. You could have just as easily used a TListBox or TRichEdit component, which will give you an items: TStrings or lines: TStrings property, as well as LoadFromFile and SaveToFile methods.

You also need to check to make sure the user did actually choose a filename. The filename returned will always be the full path of the filename --there is no need to add '.txt' to it:
  1. procedure TForm1.Button12Click(Sender: TObject);
  2. begin
  3. if savedialog1.Execute() then
  4. ListBox.items.saveToFile(saveDialog1.fileName)
  5. end;
If you only want to save, say, 250 lines at a time, you can do something like:
  1. procedure save250( filename: string; var strs: tStrings; startAt: integer );
  2. var
  3. sl: tStringList;
  4. b, e: integer;
  5. begin
  6. // Our temporary string list
  7. sl := tStringList.create;
  8. // indices of lines to copy, inclusive
  9. b := startAt;
  10. e := startAt + 249;
  11. if e >= strs.count then e := strs.count -1;
  12. // copy the indexed lines into our temporary string list
  13. for b := b to e do
  14. sl.append( strs[ b ] );
  15. // save the lines to file
  16. sl.saveToFile( filename );
  17. // cleanup
  18. sl.free
  19. end;
Did you really want the caption saved at the beginning of each line?

Hope this helps.
Reply With Quote  
Join Date: Nov 2007
Posts: 87
Reputation: squidd is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 1
squidd squidd is offline Offline
Junior Poster in Training

Re: How to split a large list

  #3  
Nov 5th, 2007
thank you very much for your quick reply....

I am wanting to be able to say in an editbox the number of lines to save.. not just one number or the other. When I click the button that says to perform the procedure, I want the action to be:

1. count from the beginning of the original large list (aka text file) to whatever number is typed in the editbox.

2. save the files that are split into whatever name is chosen by the user named one after the other incrementally. ex: mytextfile1.txt, mytextfile2.txt, etc... until the entire list is split and saved in the desired directory. (mytextfile would be what the user specified in another editbox to give the file a base name)

so, enter how many lines you want to save to each text file in the edit6.text box. use that number to then save that amount of lines to each text file until the list that WAS one huge list, will now be smaller lists incrementally adding until is is complete.

Again, thank you very much for your help I hope that I have made this a bit clearer. if not, I apologize.
Reply With Quote  
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,878
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 13
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: How to split a large list

  #4  
Nov 5th, 2007
Ah, that helps. You need to be more careful about reading the documentation when using various procedures (line writeln).

For what you want to do, the save250 procedure can almost do it. Just add another parameter for the number of lines to save and adjust line 10 to use the correct value.

Then you can save each n lines in a loop.
  1. procedure TForm1.Button12Click( Sender: TObject );
  2. var
  3. lines_per_block: integer;
  4. line_index: integer;
  5. file_number: integer;
  6. file_extension: string;
  7. base_filename: string;
  8. begin
  9. lines_per_block := strToInt( edit6.text ); // number of lines to save per file
  10. if saveDialog1.execute then
  11. begin
  12. // get the file extension and everything except the extension in
  13. // separate strings so we can inject the 1, 2, 3, ... file number.
  14. file_extension := extractFileExt( saveDialog1.filename );
  15. base_filename := copy(
  16. saveDialog1.filename,
  17. 1,
  18. length( saveDialog1.filename ) -length( file_extension )
  19. );
  20. // save each block of lines
  21. line_index := 0;
  22. file_number := 1;
  23. while line_index < ListBox.items.count do
  24. begin
  25. save250(
  26. base_filename + intToStr( file_number ) + file_extension,
  27. ListBox.items,
  28. line_index,
  29. lines_per_block
  30. );
  31. inc( file_number );
  32. inc( line_index, lines_per_block )
  33. end
  34. end
  35. end;
I used the name save250 just because that is what I gave you before, but I imagine you will want to rename it. Also, you can make it a private member of the TForm if you like...

Hope this helps.
Reply With Quote  
Join Date: Nov 2007
Posts: 87
Reputation: squidd is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 1
squidd squidd is offline Offline
Junior Poster in Training

Re: How to split a large list

  #5  
Nov 5th, 2007
Thanks you very much.. it is late here and I will certainly pour over this to see if I can make it work for my purposes.

I will indeed reply and let you know either way.

Thank you for your prompt and friendly advice in my problem.
Reply With Quote  
Join Date: Nov 2007
Posts: 87
Reputation: squidd is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 1
squidd squidd is offline Offline
Junior Poster in Training

Re: How to split a large list

  #6  
Nov 6th, 2007
For whatever reason I cant get that procedure to properly compile to test it.. It keeps stopping on the save250 part with a complaint of undeclared indentifier.

I have tried a few things but none will compile for me either.
Reply With Quote  
Join Date: Nov 2007
Posts: 87
Reputation: squidd is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 1
squidd squidd is offline Offline
Junior Poster in Training

Re: How to split a large list

  #7  
Nov 7th, 2007
I added the code exactly as you put it in there...

I made some changes from listbox to listview, and defined the procedure up top.

procedure save250(sender: TObject);


procedure TForm1.Button12Click( Sender: TObject );
var
lines_per_block: integer;
line_index: integer;
file_number: integer;
file_extension: string;
base_filename: string;
begin

lines_per_block := strToInt( edit6.text ); // number of lines to save per file
if saveDialog1.execute then
begin
// get the file extension and everything except the extension in
// separate strings so we can inject the 1, 2, 3, ... file number.
file_extension := extractFileExt( saveDialog1.filename );
base_filename := copy( saveDialog1.filename,1,length( saveDialog1.filename ) -length( file_extension ));
// save each block of lines
line_index := 0;
file_number := 1;
while line_index < ListView1.items.count do
begin
save250(base_filename + intToStr( file_number ) + file_extension,
ListView1.items, line_index, lines_per_block);
inc( file_number );
inc( line_index, lines_per_block );
end;
end;
end;

/And here are the errors I am receiving when I try to compile.

[DCC Error] : E2065 Unsatisfied forward or external declaration: 'TForm1.save250'
[DCC Error] : E2034 Too many actual parameters
[DCC Error] : E2010 Incompatible types: 'TObject' and 'string'

thanks again
Last edited by squidd : Nov 7th, 2007 at 4:27 pm.
Reply With Quote  
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,878
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 13
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: How to split a large list

  #8  
Nov 7th, 2007
You didn't define save250 the way I gave it to you. The one you defined takes a single argument: a TObject. The one I gave you takes entirely different arguments.

The procedure header should look like this:
procedure SaveNLines( filename: string; var strs: tStrings; startAt, numLines: integer );
Please notice how I renamed the procedure from save250 to saveNLines.

Hope this helps.
Last edited by Duoas : Nov 7th, 2007 at 4:38 pm.
Reply With Quote  
Join Date: Nov 2007
Posts: 87
Reputation: squidd is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 1
squidd squidd is offline Offline
Junior Poster in Training

Re: How to split a large list

  #9  
Nov 7th, 2007
sigh... i cant get this to compile... *bangs head against the wall*

I copy your exact line changed it to SaveNLines where needed, and back to save250, then to AGGHH... no avail...
Last edited by squidd : Nov 7th, 2007 at 5:16 pm.
Reply With Quote  
Join Date: Nov 2007
Posts: 87
Reputation: squidd is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 1
squidd squidd is offline Offline
Junior Poster in Training

Re: How to split a large list

  #10  
Nov 7th, 2007
Here is what I have now....

Procedure Header:
procedure SaveNLines( filename: string; var strs: tStrings; startAt, numLines: integer );

Code For Button12:
procedure TForm1.Button12Click(Sender: TObject);
var
lines_per_block: integer;
line_index: integer;
file_number: integer;
file_extension: string;
base_filename: string;
begin
lines_per_block := StrToInt( edit6.text ); // number of lines to save per file
if saveDialog1.execute then
begin
// get the file extension and everything except the extension in
// separate strings so we can inject the 1, 2, 3, ... file number.
file_extension := extractFileExt( saveDialog1.filename );
base_filename := copy( saveDialog1.filename,1,length( saveDialog1.filename ) -length( file_extension ));
// save each block of lines
line_index := 0;
file_number := 1;
while line_index < ListView1.items.count do
begin
SaveNLines(base_filename + intToStr( file_number ) + file_extension,
ListView1.items, line_index, lines_per_block);
inc( file_number );
inc( line_index, lines_per_block );
end;
end;
end;

And the errors that inevitably ensue when I attempt to compile:
[DCC Error] : E2065 Unsatisfied forward or external declaration: 'TForm1.SaveNLines'
[DCC Error] : E2033 Types of actual and formal var parameters must be identical

I simply have no idea why this is happening... I really appreciate your patience and help on this matter regardless of whether or not I can get this work for me.
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

DaniWeb Pascal and Delphi Marketplace
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes

Similar Threads
Other Threads in the Pascal and Delphi Forum

All times are GMT -4. The time now is 7:19 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC