Vielleicht interessiert das auch andere. Darum mache ich mal ein neues Thema auf.Hallo willi4willi,
könntest Du mal ein lauffähiges Mini Demo Programm hochladen, das zeigt, wie sich ein Lazarus Programm am SAP anmeldet (wahrscheinlich mit einem SAP-Logon Control) und dann mit RFC_Read_Table den Inhalt einer Tabelle mit Showmessage ausgibt.
Die SAPFunctionOCX_5_0_TLB.pas habe ich schon aus der Type Library erstellt, aber jetzt weiß ich damit nicht weiter umzugehen.
Viele Grüße
Fritz
Als Erstes benötigst du das "SAP Logon Control".
Ich gehe mal davon aus, dass du das SAP-GUI und das LazActiveX- Package im Lazarus installiert hast. Dann kannst du das Control über "Werkzeuge" --> "Import Type Libary" importieren.
Das daraus entstandene "SAPLogonCtrl_1_1_TLBP" muss dem Projekt hinzugefügt werden.
Für die An- und Abmedung an das SAP-System (hell) habe ich einmal ein Formular mit zwei Buttons erstellt:
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
variants, SAPLogonCtrl_1_1_TLB;
type
{ TForm1 }
TForm1 = class(TForm)
AxcSAPLogonControl1: TAxcSAPLogonControl;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
end;
var
Form1: TForm1;
Connection:variant;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
(*LogOn durchführen *)
if Connection.LogOn(0,false) = true then
begin
showmessage('Anmeldung wurde erfolgreich durchgeführt.');
Button1.Enabled:=FALSE;
Button2.Enabled:=TRUE;
end
else
begin
ShowMessage('Anmeldung wurde nicht durchgeführt :-(((');
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
(* Verbindung trennen *)
Connection.LogOff;
ShowMessage('System LogOff...');
Button1.Enabled:=TRUE;
Button2.Enabled:=FALSE;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
(* Verbindung definieren *)
Connection:=AxcSAPLogonControl1.OleServer.NewConnection;
Button1.Enabled:=TRUE;
Button2.Enabled:=FALSE;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Connection:=NIL;
end;
end.
Code: Alles auswählen
. . .
procedure TForm1.Button1Click(Sender: TObject);
begin
(* Bei einigen GUI-Versionen muß der UserName in *)
(* Großbuchstaben übergeben werden!!!! *)
Connection.User := 'RFC_USER';
Connection.System := 'P1';
Connection.Client := '010';
Connection.ApplicationServer := '10.10.10.10';
Connection.SystemNumber := '00';
Connection.Password := 'password';
Connection.Language := 'DE' ;
(*LogOn durchführen *)
if Connection.LogOn(0,true) = true then // Parameter "true" : SilentLogOn
begin
Button1.Enabled:=FALSE;
Button2.Enabled:=TRUE;
showmessage('Anmeldung wurde erfolgreich durchgeführt.');
end
else
begin
ShowMessage('Anmeldung wurde nicht durchgeführt :-(((');
end;
end;
. . .
Als Beispiel möchte ich einmal mit "RFC_Read_Table" die Kostenstellen aus dem SAP auslesen. Sie sind in der SAP-Tabelle "CSKT ".
Dazu erweitere ich das Programm um einen Button3 und ein StringGrid.
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Grids, Variants,
StdCtrls, SAPFunctionsOCX_5_0_TLB;
type
{ TForm1 }
TForm1 = class(TForm)
AxcSAPFunctions1: TAxcSAPFunctions;
Button3: TButton;
StringGrid1: TStringGrid;
procedure Button3Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button3Click(Sender: TObject);
var txt : string ;
r : integer ;
Table, Funct : variant;
begin
{ Funktion definieren }
Funct:=Ifunction(AxcSAPFunctions1.OleServer.add('RFC_READ_TABLE'));
{ Der Funktion übergeben, welche Tabelle gelesen werden soll }
Funct.&Exports('QUERY_TABLE').value := 'CSKT';
{ Funktion ausführen }
if not Funct.call then
{ Bei Fehler Meldung anzeigen }
showMessage(Funct.exception)
else begin
{ Tabelle mit den Daten selektieren }
Table := Funct.tables.item('DATA');
{ Anzeige im StringGrid anpassen }
StringGrid1.rowCount := Table.rowcount + 1;
StringGrid1.cells[0,0] := 'Client';
StringGrid1.cells[1,0] := 'Kostenstelle';
StringGrid1.cells[2,0] := 'Bezeichnung';
for r := 1 to StringGrid1.rowCount -1 do begin
(* Aktuellen Datensatz selektieren *)
txt := Table.value(r,1);
(* Da die Function nur einen String übergibt *)
(* der alle Daten beinhaltet, muß dieser in *)
(* die einzelnen Abschnitte unterteilt werden *)
StringGrid1.cells[0,r] := IntToStr(r);
StringGrid1.cells[1,r] := copy(txt,0,3); (* Client *)
StringGrid1.cells[2,r] := copy(txt,9,10); (* KoSt-Nr. *)
StringGrid1.cells[3,r] := copy(txt,27,20); (* KoSt-Bez.*)
end;
StringGrid1.visible := True;
end;
end;
end.