Podłączenie się do Sfery Subiekta – błędy kompilacji i Access Violation

0

Witam wszystkich w ten Świąteczny dzień,

Próbuję podłączyć się do Sfery Subiekta. Poszukałem troszkę, poczytałem troszkę ale efekt jest wyjątkowo niezadowalający.
Co zrobiłem: oczywiście zaimportowałem bibliotekę i wygenerowałem plik InsERT_TLB. Zaimportowałem też kontrolki ActiveX.

Co potrafię: uruchomić Subiekta jako wybrany użytkownik używając albo pliku pas albo kontrolki ActiveX oraz go zakończyć. I to wszystko, nic innego mi nie wychodzi.

Powiedzmy że wybiorę metodę z użyciem InsERT_TLB.pas.

Tak wygląda mój przykład:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
  Vcl.Dialogs, Vcl.StdCtrls, Vcl.OleServer, System.Win.ComObj, InsERT_TLB;

type
  TForm1 = class(TForm)
    btnUruchomSubiekt: TButton;
    btnZakonczSubiekt: TButton;
    btnWczytajDokument: TButton;
    procedure btnUruchomSubiektClick(Sender: TObject);
    procedure btnZakonczSubiektClick(Sender: TObject);
    procedure btnWczytajDokumentClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  UruchomSubiekta: Aplikacja;
  oGT: GT;
  oSubGT: Subiekt;
  oDokum: SuDokument;
  oDodatki: Dodatki;

implementation

{$R *.dfm}

procedure TForm1.btnWczytajDokumentClick(Sender: TObject);
begin
//  oDokum := oSubGT.SuDokumentyManager.Wczytaj('FZ 1/MAG/2018');  // błąd w czasie kompilacji [dcc32 Error] Unit1.pas(37): E2010 Incompatible types: 'SuDokument' and 'IDispatch'
end;

procedure TForm1.btnUruchomSubiektClick(Sender: TObject);
begin
  oGT := CreateComObject(CLASS_GT) as GT;
  oDodatki := CreateCOMObject(CLASS_Dodatki) as Dodatki;

  oGT.Autentykacja := gtaAutentykacjaMieszana;
  oGT.Produkt := gtaProduktSubiekt;
  oGT.Serwer := 'komputer\instancja';
  oGT.Uzytkownik := 'sa';
  oGT.UzytkownikHaslo := 'HasloDoBazy';
  oGT.Baza := 'bazaSubiekta';
  oGT.Operator_ := 'Szef';
  oGT.OperatorHaslo := oDodatki.Szyfruj('HasloUzytkownika');

  UruchomSubiekta := oGT.Uruchom(gtaUruchomDopasujOperatora, gtaUruchom);
//  oSubGT.MagazynId := 1;  // błąd po uruchomieniu Access violation
end;

procedure TForm1.btnZakonczSubiektClick(Sender: TObject);
begin
  UruchomSubiekta.Zakoncz;
end;

end.

W przykładach pomocy dla Visual Basic (którego nie znam) dla tematu SuDokument, przykład 1 pokazuje jak pobrać jakiś dokument i zrobić na nim prostą operację, wygląda to tak:

Private Sub FS_ManipulowanieWartoscia()
    On Error GoTo ErrHandler
    
    Dim oGT As New InsERT.gt
    Dim oSubGT As InsERT.Subiekt
    Dim oDokum As InsERT.SuDokument
    
    'Połączenie z aplikacją Subiekt GT
    If oGT Is Nothing Then
        MsgBox "Nie udało się utworzyć obiektu GT."
        Exit Sub
    End If
    oGT.Produkt = gtaProduktSubiekt
    oGT.Autentykacja = gtaAutentykacjaMieszana
    oGT.Serwer = "JACEKP\InsERTGT"
    oGT.Uzytkownik = "sa"
    oGT.UzytkownikHaslo = "5DB15B5B29B1A23A"
    oGT.Baza = "BIBUS"
    oGT.Operator = "Szef"
    Set oSubGT = oGT.Uruchom(gtaUruchomDopasujOperatora, gtaUruchom)
    oSubGT.MagazynId = 1
    
    'Wczytanie faktury FS 28/MAG/2005 i pokazanie jej parametrów początkowych
    Set oDokum = oSubGT.Dokumenty.Wczytaj("FS 28/MAG/2005")
    
    Debug.Print oDokum.NumerPelny
    Debug.Print oDokum.DataWystawienia
    Debug.Print oDokum.WartoscBrutto
    
    Dim oPoz As InsERT.SuPozycja
    Dim i As Integer
    For i = 1 To oDokum.Pozycje.Liczba
        Set oPoz = oDokum.Pozycje.Element(i)
        Debug.Print oPoz.TowarNazwa
        Debug.Print "Ilość: " & oPoz.Ilosc & vbTab & "Rabat%: " & oPoz.RabatProcent
        Debug.Print "Cena przed rabatem: " & oPoz.CenaNettoPrzedRabatem & vbTab & "Cena po rabacie: " & oPoz.CenaNettoPoRabacie
    Next i
    
    Debug.Print "=========================="
    
    'Ustawienie automatycznego rabatu do wszystkich pozycji tak,
    'aby wartość dokumentu wyniosła 1000 zł
    oDokum.NadajRabatDoWartosci (CCur(1000))
    oDokum.Zapisz
    
    For Each oPoz In oDokum.Pozycje
        Debug.Print oPoz.TowarNazwa
        Debug.Print "Ilość: " & oPoz.Ilosc & vbTab & "Rabat%: " & oPoz.RabatProcent
        Debug.Print "Cena przed rabatem: " & oPoz.CenaNettoPrzedRabatem & vbTab & "Cena po rabacie: " & oPoz.CenaNettoPoRabacie
    Next
    
    Exit Sub
    
ErrHandler:
    MsgBox "Wystąpił błąd" & vbCrLf & "Numer: " & Err.Number & vbCrLf & "Opis: " & Err.Description
    
End Sub

niestety, już pierwsza pozycja po uruchomieniu Subiekta

oSubGT.MagazynId := 1;

wywołuje błąd Access violation w moim programiku.

Dodatkowo, gdy chcę użyć procedurki:

oDokum := oSubGT.SuDokumentyManager.Wczytaj('FZ 1/MAG/2018'); // taki dokument istnieje

dostaję już w trakcie kompilacji informację:

[dcc32 Error] Unit1.pas(37): E2010 Incompatible types: 'SuDokument' and 'IDispatch'

Ktoś pomoże?

Pozdrawiam i życzę Wesołych Świąt
Robert

0

Nie znam Subiekta ale porównując Twój kod i ten z VS to pomyliłeś obiekty. Chyba powinno być (pisze z komórki więc sorry za błędy)

UruchomSubiekta := oGT.Uruchom(gtaUruchomDopasujOperatora, gtaUruchom);
UruchomSubiekta.MagazynId := 1;

Późniejsze podłączenie do dokumentu też powinno wtedy działać.
Edit
Dokument powinien być wczytywany:

oDokum := UruchomSubiekta.SuDokumentyManager.Wczytaj('FZ 1/MAG/2018');
0

O widzisz, najpewniej dokładnie trafiłeś w sedno sprawy.

W przykładzie z VB przyporządkowany jest start aplikacji (obiekt oGT) do oSubGT (który jest typu Subiekt).
Następnie wszystko działa już na oSubGT.
W Delphi nie mogę tego tak zrobić bo jest niezgodność typów. Mogę przyporządkować obiekt oGT tylko do UruchomSubiekta (typu Aplikacja).

Oczywiście że od razu wpadłem na pomysł żeby po tej operacji zrobić coś w stylu:

oSubGT:=UruchomSubiekta;

lub

oSubGT.Aplikacja:=UruchomSubiekta.Aplikacja;

ale niestety dostaję informację

[dcc32 Error] Unit1.pas(56): E2129 Cannot assign to a read-only property

Niestety nie mam pojęcia co z tym zrobić?

0
function TService.SubiektRun(const ADatabaseSettings: TDatabaseSettings; AVisible: Boolean = False): Boolean;
begin
  Result := False;

  if Assigned(ADatabaseSettings) then
  begin
    try
      GT := CreateOleObject('InsERT.GT');
      Add := CreateOleObject('InsERT.Dodatki');

      GT.Autentykacja := 0; // Autentykacja mieszana
      GT.Produkt := 1; // Subiekt
      GT.Serwer := ADatabaseSettings.Server;
      GT.Uzytkownik := ADatabaseSettings.User;
      GT.UzytkownikHaslo := ADatabaseSettings.Password; // jeśli jest hasło patrz GT.OperatorHaslo
      GT.Baza := ADatabaseSettings.DatabaseName;
      GT.Operator := ADatabaseSettings.Operator_;
      GT.OperatorHaslo := Add.Szyfruj(ADatabaseSettings.OperatorPassword);
      SubGT := GT.Uruchom(gtaUruchomDopasujOperatora, gtaUruchomWTle);
      SubGT.Okno.Widoczne := AVisible;

      Result := True;
    except
      on E: Exception do
      begin
        Log.Error(Format('Wystąpił błąd podczas uruchamiania Subiekta.' + sLineBreak + 'Komunikat: %s', [E.Message]), 'ERROR');
      end;
    end;
  end;

end;
0

dzięki za kawałek kodu ale mam pytanie, jakiego typu masz SubGT?

0

nieśmiało się przypomnę że cały czas czekam na jakąś dobrą duszę.
Przyznam że troszkę posiedziałam nad Visual Basic i coś tam skleiłem z przykładów i to działa ale i tak wolałbym to zrobić w Delphi.

Podrzucam kod InsERT_TLB.pas może to coś pomoże.

1 użytkowników online, w tym zalogowanych: 0, gości: 1