Autor Beitrag
Xearox
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 260
Erhaltene Danke: 3



BeitragVerfasst: Mo 09.05.11 20:55 
Ich weiß nicht ob ich im richtigen Forumsteil bin aber das hat ja was mit Dateizugriff zu tun.
Vorweg, das hier ist absolutes neu land für mich und habe mir so einiges schon im Internet angeschaut, was ich bei google so finde, nur weiß ich mir leider keinen Rat mehr.
Ich möchte gerne in meiner Anwendung per Drücken auf einen Button zunächst einmal eine ListBox mit Daten aus einer Excel Tabelle einfügen.
Diese Tabelle beinhaltet Kontakt Daten mit Adresse etc..
Ich möchte jedoch nur immer eine Spalte einfügen.
Sprich immer nur den Namen bzw. die Firma in der ListBox als auswählbares Objekt, damit ich diesen Namen per Doppel klick in einem Weiterem Feld, in diesem Fall ein Memo, einfügen kann.

Was ich nun genau wissen will, wie bekomme ich aus der Tabelle im Bereich A1 bis A97 alle Daten untereinander in die ListBox übertragen?

Was ich bisher programmiert habe, sind Quellen aus dem World Wide Web.
ausblenden volle Höhe 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:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    LB_Kunde: TListBox;
    Label1: TLabel;
    LB_Artikel: TListBox;
    Label2: TLabel;
    M_Artikel: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }
    procedure ListenFuellen;
  end;

var
  Form2: TForm2;

implementation

var
  Excel:variant;

{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
  ListenFuellen;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm2.ListenFuellen;
var
  DestSheet:variant;
  DestRange:Olevariant;

begin
  try
    try
      Excel:= CreateOleObject('Excel.Application');
    except
      Excel := GetActiveOleObject('Excel.Application');
    end;
  begin
      Excel.Workbooks.Open(ExtractFilePath(Paramstr(0))+('rechi.xls'));
      Excel.ActiveWorkBook.Saved := false;


      DestSheet:=Excel.WorkBooks['rechi.xls'].Worksheets['Kontakte'];

      //Excel.Range['A1', 'A97'].Copy(EmptyParam);

      LB_Kunde.Items.Append(DestSheet.Range['A1''A97']);
      Excel.Quit; //Beendet Excel
      Excel := Unassigned;
  end;
  except
    Showmessage('Fehler, Exceldaten konnten nicht eingelesen werden');
  end;

end;

end.


kann mir irgendjemand bei meinem Problem weiter helfen?

Bitte wenn jemand helfen kann, dann mit Kommentar, damit ich weiß, was genau jeweils eine Zeile/Befehl macht.

Danke :-)

Gruß Xearox
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 10.05.11 06:13 
user profile iconXearox hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
      Excel.ActiveWorkBook.Saved := false;					
Wozu? Wenn du dem Excelobjekt sagst, dass da noch ungespeicherte Daten sind, kommt logischerweise beim Beenden die Frage, ob diese gespeichert werden sollen. Wozu brauchst du das, ich dachte du willst die Daten nur lesen? :gruebel:

user profile iconXearox hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
      LB_Kunde.Items.Append(DestSheet.Range['A1''A97']);					
Woher sollte denn Excel wissen, dass du dort gerne einen String mit Zeilenumbrüchen hättest? Du bekommst ein Objekt zurück.

Davon abgesehen geht es aber ohnehin einfacher indem du einfach die Zellen direkt ansprichst. Grad keine Zeit zu testen, aber sollte so gehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
var
  Excel, ContactsSheet: OleVariant;
  i: Integer;
begin
  try
    try
      Excel := CreateOleObject('Excel.Application');
    except
      Excel := GetActiveOleObject('Excel.Application');
    end;
    Excel.Workbooks.Open(ExtractFilePath(Paramstr(0))+('rechi.xls'));

    ContactsSheet := Excel.Workbooks['rechi.xls'].Worksheets['Kontakte'];

    for i := 1 to 97 do
      ListBox1.Items.Append(ContactsSheet.Cells[i, 1]);

    Excel.Quit; // Beendet Excel
    Excel := Unassigned;
  except
    Showmessage('Fehler, Exceldaten konnten nicht eingelesen werden');
  end;
Xearox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 260
Erhaltene Danke: 3



BeitragVerfasst: Di 10.05.11 10:38 
soweit verstanden.
Aber wie schaut es aus, wenn man eine Tabelle hat, wo immer wieder neue Daten hinzukommen?
Mit was muss ich da genau arbeiten?

Sprich eine Liste von X Daten.
Im Obrigen Fall sind es 97 Zeilen.
Aber es kann ja sein, das morgen 99 Zeilen drin stehen.
Wie bekomme ich nun das ins Programm integriert?

Soviel ich weiß, kann man Zeilen zählen.
Diese in einer Variable ablegen, in dem fall "I"
und dann wird kopiert.



[Edit:]
Hab hier was im Forum gefunden, will aber nicht als Totengräber enden, wenn ich da einfach eine Frage nach mehr als 12 Monaten stelle.
www.delphi-forum.de/...Zaehlen_96462,0.html

was ist das für ein befehl, xlLastCells und SpecialCells...
Der Compiler gibt aus: [DCC Fehler] Unit2.pas(61): E2003 Undeklarierter Bezeichner: 'xlLastCell'

[Edit2:]
ausblenden Delphi-Quelltext
1:
2:
3:
iMaxZeilen := ContactsSheet.UsedRange.Rows.Count;
    for i := 1 to iMaxZeilen do
      LB_Kunde.Items.Append(ContactsSheet.Cells[i, 1]);
Chemiker
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 194
Erhaltene Danke: 14

XP, Vista 32 Bit, Vista 64 Bit, Win 7 64 Bit
D7, BDS 2006, RAD Studio 2009+C++, Delphi XE2, XE3, VS 2010 Prof.
BeitragVerfasst: Di 10.05.11 14:57 
Hallo Xearox,

xlLastCells ist eine Konstante aus Excel. SpecialCells ist eine Methode von Range in Excel.

Bis blad Chemiker
Xearox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 260
Erhaltene Danke: 3



BeitragVerfasst: Do 12.05.11 20:07 
Die Frage hab ich zwar schon beantwortet bekommen, aber eine ganz wichtige Sache hab ich vergessen.
Und zwar, beim einfügen der Daten, werde ich immer wieder gefragt beim Schließen von excel, ob die datei gespeichert wurde, obwohl nichts geändert wurde.
Wie bekomme ich nun das hin, das diese Frage nicht immer vor kommt?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 12.05.11 20:28 
Ich wiederhole mich ja nur ungern, aber ich habe dich schon gefragt warum du das eingebaut hast... :roll:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconXearox hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
      Excel.ActiveWorkBook.Saved := false;					
Wozu? Wenn du dem Excelobjekt sagst, dass da noch ungespeicherte Daten sind, kommt logischerweise beim Beenden die Frage, ob diese gespeichert werden sollen. Wozu brauchst du das, ich dachte du willst die Daten nur lesen? :gruebel:
Xearox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 260
Erhaltene Danke: 3



BeitragVerfasst: Do 12.05.11 20:57 
Das hab ich ja rausgenommen komplett.
Dennoch frag er mich immer noch.

Soll ich mal den Kompletten Quelltext einfügen?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 12.05.11 21:12 
Ja, kannst du machen.

Ich habe den von mir geposteten Quelltext aber gerade ausprobiert:
Da kommt die Nachfrage nicht. :nixweiss:
Xearox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 260
Erhaltene Danke: 3



BeitragVerfasst: Do 12.05.11 21:27 
Genau 2 Mal kommt die Frage.

ausblenden volle Höhe 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:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    LB_Kunde: TListBox;
    Label1: TLabel;
    LB_Artikel: TListBox;
    Label2: TLabel;
    Button2: TButton;
    E_Kunde: TEdit;
    L_Kunde: TLabel;
    LB_Aus_Artikel: TListBox;
    Label3: TLabel;
    Button3: TButton;
    CheckBox1: TCheckBox;
    E_Lieferdatum: TEdit;
    L_DatumLayout: TLabel;
    B_Vorschau: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure LB_KundeClick(Sender: TObject);
    procedure LB_ArtikelDblClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure B_VorschauClick(Sender: TObject);
  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }
    procedure KontakteFuellen;
    procedure ArtikelFuellen;
  end;

var
  Form2: TForm2;

implementation

uses Unit3;

var
  Excel:variant;
  Kundenauswahl,Artikelauswahl:string;
  ArtikelAnz:integer;

{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
  KontakteFuellen;
  ArtikelFuellen;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm2.B_VorschauClick(Sender: TObject);
begin
  form3.showmodal;
end;

procedure TForm2.CheckBox1Click(Sender: TObject);
begin
  E_Lieferdatum.Visible:=True;
  L_DatumLayout.Visible:=True;
end;

procedure TForm2.FormShow(Sender: TObject);
begin
  ArtikelAnz:=1;
end;

procedure TForm2.KontakteFuellen;
var
  Excel, ContactsSheet: OleVariant;
  i,iMaxZeilen: Integer;
begin
  try
    try
      Excel := CreateOleObject('Excel.Application');
    except
      Excel := GetActiveOleObject('Excel.Application');
    end;
    Excel.Workbooks.Open(ExtractFilePath(Paramstr(0))+('rechi.xls'));
    ContactsSheet := Excel.Workbooks['rechi.xls'].Worksheets['Kontakte'];
    iMaxZeilen := ContactsSheet.UsedRange.Rows.Count;
    for i := 1 to iMaxZeilen do
      LB_Kunde.Items.Append(ContactsSheet.Cells[i, 1]);

    Excel.Quit; // Beendet Excel
    Excel := Unassigned;
  except
    Showmessage('Fehler, Exceldaten konnten nicht eingelesen werden');
  end;
end;

procedure TForm2.LB_ArtikelDblClick(Sender: TObject);
var
  ArtikelNr,i:integer;
begin
  if ArtikelAnz<= 13 then
  begin
    ArtikelAnz:=ArtikelAnz+1;
    ArtikelNr:=LB_Artikel.ItemIndex;
    ArtikelAuswahl:=LB_Artikel.Items.Strings[ArtikelNR];
    LB_Aus_Artikel.Items.Append(ArtikelAuswahl);
  end;
end;

procedure TForm2.LB_KundeClick(Sender: TObject);
var
  KundenNr:integer;

begin
  KundenNr:=LB_Kunde.ItemIndex;
  Kundenauswahl:=LB_Kunde.Items.Strings[KundenNr];
  E_Kunde.Text:=Kundenauswahl;
end;

procedure TForm2.ArtikelFuellen;
var
  Excel, ArtikelSheet: OleVariant;
  i,iMaxZeilen: Integer;
begin
  try
    try
      Excel := CreateOleObject('Excel.Application');
    except
      Excel := GetActiveOleObject('Excel.Application');
    end;
    Excel.Workbooks.Open(ExtractFilePath(Paramstr(0))+('rechi.xls'));
    ArtikelSheet := Excel.Workbooks['rechi.xls'].Worksheets['Artikel'];
    iMaxZeilen := ArtikelSheet.UsedRange.Rows.Count;
    for i := 1 to iMaxZeilen do
      LB_Artikel.Items.Append(ArtikelSheet.Cells[i, 1]);

    Excel.Quit; // Beendet Excel
    Excel := Unassigned;
  except
    Showmessage('Fehler, Exceldaten konnten nicht eingelesen werden');
  end;
end;

end.


Jetzt mal eine ganz wichtige Frage.
Kann ich die Variablen, wie KundenAuswahl etc. in eine weitere Form, wo eine Vorschau statt finden soll, in ein Memo schreiben, ohne den ganzen Quelltext hier umzuschreiben?
Also ich beziehe mich auf GlobaleVariablen, hier im Forum habe ich zu der Frage, Variablen in andere Unit übergeben, was mit property gefunden und das man GlobaleVariablen nicht nutzen sollte.
Chemiker
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 194
Erhaltene Danke: 14

XP, Vista 32 Bit, Vista 64 Bit, Win 7 64 Bit
D7, BDS 2006, RAD Studio 2009+C++, Delphi XE2, XE3, VS 2010 Prof.
BeitragVerfasst: Sa 14.05.11 22:23 
Hallo Xearox,

Zitat:
Genau 2 Mal kommt die Frage.


Das liegt daran, dass für Artikel und Kontakte jeweils Excel aufgerufen wird. Normalerweise sollte es eigentlich ohne Nachfrage funktionieren.

Sonst setze einfach:
ausblenden Delphi-Quelltext
1:
Excel.ActiveWorkBook.Saved := TRUE;					

Dann kommt selbst keine Nachfrage, wenn das Workbook aus welchem Grund auch immer verändert worden ist.
Da OLE relativ langsam ist sollte man, wenn es möglich die Daten in einem Rutsch einlesen.
Da in Deinem Fall das gleiche Workbook mit verschieden Sheets ausgelesen wird, würde sich anbieten Excel einmal zu starten das Workbook zu laden, anschließend beide Sheets auszulesen und dann Excel wieder zu schließen.
Außerdem sind diese Zeilen nicht in Ordnung:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
try
  Excel := CreateOleObject('Excel.Application');
except
  Excel := GetActiveOleObject('Excel.Application'); 
end;

Sie müssten eigentlich umgekehrt sein, wenn sie einen Sinn machen sollen.
ausblenden Delphi-Quelltext
1:
2:
3:
 except
    Showmessage('Fehler, Exceldaten konnten nicht eingelesen werden');
 end;

An dieser Stelle muss Du überlegen, ob das weiterarbeitet mit Deinem Programm ohne Excel überhaupt Sinn macht, weil die Fehlerabfrage eigentlich dazu dient festzustellen, ob eine Excel-Instanz gestartet werden kann. Ist das nicht der Fall würde ich an dieser Stelle das Programm mit Exit; abbrechen.

Es gibt einige Möglichkeiten die Daten auszutauschen. Als ein Beispiel könnte dir dieser Quelltext dienen:

ausblenden volle Höhe 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:
45:
46:
47:
48:
unit frmHauptForm;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    bt2FormAnzeigen: TButton;
    procedure bt2FormAnzeigenClick(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private-Deklarationen }
    FTestString: String;
  public
    { Public-Deklarationen }
    property TestString: String read FTestString write FTestString;
  end;

var
  Form1: TForm1;

implementation

uses frm2Form;

{$R *.dfm}

procedure TForm1.bt2FormAnzeigenClick(Sender: TObject);
begin
  Form2.Show;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  TestString:= Edit1.Text;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  Edit1.Text:= TestString;
end;

end.


ausblenden volle Höhe 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:
unit frm2Form;

interface

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

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    procedure Edit1Change(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

 uses frmHauptForm;

{$R *.dfm}

procedure TForm2.Edit1Change(Sender: TObject);
begin
  Form1.TestString:= Edit1.Text;
end;

procedure TForm2.FormActivate(Sender: TObject);
begin
  Edit1.Text:= Form1.TestString;
end;

end.

Bis bald Chemiker