Autor |
Beitrag |
Xearox
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: 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.
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
public 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'];
LB_Kunde.Items.Append(DestSheet.Range['A1', 'A97']); Excel.Quit; 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
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 10.05.11 06:13
Xearox hat folgendes geschrieben : | 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?
Xearox hat folgendes geschrieben : | 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: 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; Excel := Unassigned; except Showmessage('Fehler, Exceldaten konnten nicht eingelesen werden'); end; |
|
|
Xearox 
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: 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:]
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
      
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.
|
Verfasst: 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 
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: 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
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 12.05.11 20:28
|
|
Xearox 
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: 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
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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. 
|
|
Xearox 
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: Do 12.05.11 21:27
Genau 2 Mal kommt die Frage.
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
public 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; 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; 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
      
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.
|
Verfasst: 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:
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:
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.
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:
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 FTestString: String; public 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. |
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 public 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
|
|
|