Author: Tomas Rutkauskas
I have various TStringGrid objects within my application and I want to allow the
user to copy selected data to the clipboard for insertion into other programs such
as Excel.
Answer:
Solve 1:
1 var2 S: string;
3 i, k: Integer;
4 begin5 S := EmptyStr;
6 with StringGrid1 do7 begin8 for i := FixedRows to RowCount - 1 do9 begin10 for k := FixedCols to ColCount - 1 do11 begin12 if k > FixedCols then13 S := S + #9;
14 S := S + Cells[k, i];
15 end;
16 S := S + #13#10;
17 end;
18 end;
19 Clipboard.AsText := S;
This generates a string in which columns are separated by Tab characters and rows
by CR/LF linebreaks. Most spreadsheets are able to paste this into cells correctly.
Same for the selection in a grid:
20 S := '';
21 with grid do22 for i := Selection.Top to Selection.Bottom do23 begin24 for k := Selection.Left to Selection.Right do25 begin26 S := S + Cells[k, i];
27 if k <> Selection.Right then28 S := S + #9;
29 end;
30 S := S + #13#10;
31 end;
32 Clipboard.AsText := S;
Solve 2:
Here is how you can copy a selection.
33 uses34 ClipBrd;
35 36 procedure CopyGridSelectionToClipBoard(Grid: TStringGrid; Selection: TGridRect);
37 const38 TAB = Chr(VK_TAB);
39 CR = #13;
40 var41 r, c: integer;
42 S: string;
43 begin44 S := '';
45 for r := Selection.Top to Selection.Bottom do46 begin47 for c := Selection.Left to Selection.Right do48 begin49 S := S + Grid.Cells[c, r];
50 if c < Selection.Right then51 S := S + TAB;
52 end;
53 if r < Selection.Bottom then54 S := S + CR;
55 end;
56 ClipBoard.SetTextBuf(PChar(S));
57 end;
Pasting would be the reverse. An idea would be to get the text from the clipboard
and assign it to a TStringList. This way you'll know how many rows you have.
58 var59 F: TStringList;
60 begin61 F := TStringList.Create;
62 F.Text := Clipboard.AsText;
63 F.Free;
64 end;
You'll still need to parse each row to get the columns.
By the way, you can use the text you copied with the above procedure to paste into Excel. Excel knows how to parse it if you use the TAB to delimit columns.