Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - stringgrid - Spalten vertauschen?


D. Annies - Do 08.05.08 10:50
Titel: stringgrid - Spalten vertauschen?
Hi, Delpher,

wie kann ich in einem Stringgrid einzelne Spalten vertauschen?
Einfache Frage, aber die Antwort? - Ich finde nichts darüber. :?

Danke für Hilfe,
Detlef


Delete - Do 08.05.08 11:17

so viel ich weiss, geht das mit handarbeit ... :-)


D. Annies - Do 08.05.08 11:38

Hi, Grenggaenger & aliter,

meinst du so etwas?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Spaltenvertauschen1Click(Sender: TObject);
var row, col1, col2         : integer;
     hilf                   : string;
     clickedok1, clickedok2 : boolean;
begin
  col1 := 0; col2 := 0;
  showmessage('Benötigte Spaltennummern eingeben');
  ClickedOK1 := InputQuery('von Spalte''Spaltennummer 1:', Inputstring);
  If ClickedOK1 then col1 := strtoint(inputstring);
  ClickedOK2 := InputQuery('nach Spalte''Spaltennummer 2:', Inputstring);
  If ClickedOK2 then col2 := strtoint(inputstring);
  for row := 0 to TntStringGrid1.RowCount-1 do
  begin
    hilf := TntStringGrid1.Cells[col2, row];
    TntStringGrid1.Cells[col2, row] := TntStringGrid1.Cells[col1, row];
    TntStringGrid1.Cells[col1, row] := hilf;
  end;
  gridbreite(tntstringgrid1);
end;


Das muss doch eleganter gehen ...

Detlef


Delete - Do 08.05.08 12:18

ja, meinte so etwas. wobei du hier nicht den Obj. pointer vergessen solltest. für das verschieben, kannst 'ne verschiebung mit der maus implementieren. :-)

alternativ, kannst auch 'ne andere componente verwenden :-) , welche noch zusätliche möglichkeiten zur verfügung stellt, z.b. sortieren, filtern, etc. aber das tStringGrid/tDrawGrid sind halt quasi urväter, und dennen musste noch alles beibringen.

aber vielleicht kennt ja 'n anderer noch 'n trick ...

seh grad, du verwendest 'ne andere komponente. tausch mal den titel aus, was das TNT kann, davon hab ich keine ahnung.


D. Annies - Do 08.05.08 13:30

Hi,

das TntStringgrid kann bloß mehr Schriftarten, also z.B. Unicode darstellen.
Kann der Titel wohl bleiben, oder?

Gruß, Detlef


hansa - Do 08.05.08 14:07

Was heißt eleganter ? Kürzer geht es so :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls;

type
  TForm1 = class(TForm)
    sg1: TStringGrid;
    btn1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  HilfStr : TStrings;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var i,j : Integer;
begin   //Spalten jeweils mit Reihenfolge füllen
  for i := 1 to sg1.ColCount do
    for j := 1 to sg1.RowCount do
      sg1.Cells [i,j] := IntToStr(i);
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
  HilfStr := sg1.Cols[1];
  sg1.Cols[1] := sg1.Cols[2];
  sg1.Cols[2] := HilfStr;
end;

end.


Jetzt kommt der Witz. :lol: Es geht nicht. :mrgreen: Bitte das mal so ausprobieren. Wieso wird die in HilfStr gespeicherte Spalte 1 nicht in Spalte 2 angezeigt. :shock:


Martok - Do 08.05.08 14:11

Versuch mal, HilfStr zu erzeugen und statt Zuweisungen Assign zu nehmen. Durch die Setter von Cols wird das eh gemacht, und da du nur die Referenz übergibst, zerschießt du dir den HilfStr in Zeile 40..


hansa - Do 08.05.08 14:38

Detlef hat jedenfalls seine (nicht) funktionierende Alternative. :motz: Es gibt noch eine.

Das create hat tatsächlich schon mal gefehlt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.btn1Click(Sender: TObject);
begin
  HilfStr := TStrings.Create;
  HilfStr := sg1.Cols[1];
  sg1.Cols[1] := sg1.Cols[2];
  sg1.Cols[2] := HilfStr;
end;


Was soll jetzt da das Assign ?


D. Annies - Do 08.05.08 14:52

Hi, Hansa,

meine Alternative funktioniert! Bestens! Aber eben "zu Fuß".

Bis auf Weiteres, Detlef :lupe:


Martok - Do 08.05.08 14:57

Schonmal von dem Unterschied zwischen Pointern und Properties gehört?

Die Setter für die Cols-Property kopieren per Assign die Daten in ihre eigenen Objekte.
HilfStr ist nur ein Pointer, der wird einfach überschrieben. Dein Code eben ist also nichts weiter als ein Speicherleck. Und dazu noch eins, was mit einem EAbstract crasht. TStrings kann man nicht instanzieren.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.btn1Click(Sender: TObject);
var HilfStr:TStringList;
begin
  HilfStr := TStringList.Create;
  try
    HilfStr.Assign(sg1.Cols[1]);  //kopieren
    sg1.Cols[1] := sg1.Cols[2];  //implizites Assign
    sg1.Cols[2] := HilfStr;  //implizites Assign
  finally
    HilfStr.Free;
  end;
end;


Ich hab grad mal ein wenig grids.pas gelesen, da schauerts einem ja. Also das hätte man bestimmt auch irgendwie einfacher hingekriegt... ändert aber nichts daran, dass dieser Code jetzt geht.


D. Annies - Fr 09.05.08 12:42

Hi, Sebastian,

danke auch für deine Ideen zur Lösung! Ist denn wohl beantwortet.
Detlef


Delete - Mo 12.05.08 11:37

Mal 'ne neue Lösung :-)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
 i, j: integer;
begin
 for i := 0 to StringGrid1.ColCount do
  for j := 0 to StringGrid1.RowCount do
   StringGrid1.Cells[i, j] := inttostr(i);
end;

end.


das geheimnis liegt in der DFM ;-)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 223
  ClientWidth = 426
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object StringGrid1: TStringGrid
    Left = 8
    Top = 8
    Width = 401
    Height = 187
    DefaultRowHeight = 18
    Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goRowMoving, goColMoving, goEditing]
    TabOrder = 0
  end
end


die spalte verschieben, kann das StrinGrid schon von haus aus ... ;-)


D. Annies - Mo 12.05.08 11:59

Hi, GG,

mysteriös, mysteriös ...

Äh, und wie geht dann das Vertauschen? Da brauch ich einen Tritt von dir!

Gruß, Detlef


jaenicke - Mo 12.05.08 12:57

Klicken und ziehen in der Überschrift (fixed row).


Lannes - Mo 12.05.08 12:58

Hallo,
user profile iconD. Annies hat folgendes geschrieben:

Das muss doch eleganter gehen ...
Detlef

StringGrid.Rows sind vom Typ TStrings, und TStrings kennt die Methode Exchange.
Spalte 1 mit Spalte 2 tauschen:

Delphi-Quelltext
1:
2:
for z := 0 to StringGrid.RowCount -1 do
  StringGrid.Rows[z].Exchange(1,2);


D. Annies - Mo 12.05.08 16:43

An alle!

@lannes: Setze im Stringgrid goColmoving auf True;

@jaenicke: Alles klar! (Bei den DBTabellen geht das ja auch schon von Hause aus)

Vielen, vielen Dank - da werden andere auch von lernen!

Gruß, Detlef