Forum Użytkownikow Subiekt GT
InsERT GT => Dodatki - zestawienia - sfera => Wątek zaczęty przez: ural w Lipiec 20, 2010, 20:48:33
-
czy mógłby mi ktoś dać linki albo jakieś pliczki z tutorialami dotyczącymi zestawień COM ;D
-
czy mógłby mi ktoś dać linki albo jakieś pliczki z tutorialami dotyczącymi zestawień COM ;D
w jakim jezyku chcesz pisać ???
-
a w jakim można pisać? c++, java? Pytam o te zestawienia COM, bo zestawienia SQL mają jeden mankament - nie można wyszukiwać rekordów po frazach. :-X
p.s. myślałem że zestawienia COM to coś takiego jak zestawienia SQL, tylko że inna składnia :D
-
co masz na myśli pisząc "nie można wyszukiwać rekordów po frazach" ?
-
Gdy wynik zapytania SQL jest dość obszerny to aby przyśpieszyć wyszukanie chciałbym skorzystać z czegoś takiego jak F7 albo F8, a tego nie da się zrobić. :'( zapytania COM to umożliwiają?
-
Zestawienia COM - nazwa jest trochę nieszczęsna bo bardziej adekwatna powinna być dodatki/moduły/rozszerzenia COM.
Najczęściej używamy do jakiś większych operacji na bazie których nie da się wykonać z poziomu zestawień SQL a nie chcemy zmuszać kogoś do instalacji management studio. Do wyświetlania wyników raczej się to nie nadaje bo musiałbyś zbudować swój interfejs.
Jedyną różnicą między zewnętrznym programem a rozszerzeniem COM jest to że w zewnętrznym programie musisz spytać użytkownika o logowanie do bazy, magazyn itd.. a w rozszerzeniu COM masz udostępniony kontekst który dostarcza Ci informacji o dostępie do bazy, aktualnym magazynie, użytkowniku, wybranym okresie itd..
Wracając do Twojego problemu to można go rozwiązać na 2 sposoby :
1. w zestawieniach SQL działa CTRL + F czyli masz F7
2. możesz dodać parametr w zestawieniu który będzie działał jak F8
-
dzięki:) ale ja chciałbym się troszkę nauczyć tych zestawień COM ;D jak możesz to zamieść kilka przykładów :P
-
dzięki:) ale ja chciałbym się troszkę nauczyć tych zestawień COM ;D jak możesz to zamieść kilka przykładów :P
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZestManLib;
using System.Windows.Forms;
namespace test_com1
{
public class TestCOM1 : IZestawienieWlasne
{
public string Nazwa
{
get { return "Nazwa mojego zestawienia"; }
}
public string Opis
{
get { return "Opis mojego pierwszego zestawienia"; }
}
public int Programy
{
get { return 1; }
}
public void Wykonaj(IZestawienieComDane pZestawienieComDane)
{
Form1 form1 = new Form1();
form1.Show();
}
}
}
-
Kiedyś napisałem coś takiego, może się przyda:
Krótki kurs pisania zestawień COM w .NET 2.0
Subiekt GT (również Rachmistrz, Rewizor i Gratyfikant) umożliwiają pisanie zestawień COM. Można je również napisać w .NET i z doświadczenia wynika, że bezproblemowo komunikują się one z resztą systemu, a dzięki łatwemu oprogramowywaniu interface-u, jak i operacji bazodanowych pozwalają dodać funkcjonalność, której nie ma w danym programie.
Przypatrzmy się jak można je pisać w Visual Studio C# Express Edition - które jest całkowicie bezpłatnym środowiskiem developerskim!!!
Aby utworzyć takie zestawienie .NET - GT.COM należy utworzyć projekt typy Class Library. Następnie wybieramy z menu Project opcję Właściwości utworzonego projektu i na zakładce Application wybieramy Assembly information. Na samym dole zaznaczamy opcję make assembly COM visible, dzięki czemu nasz moduł .NET będzie poprawnie współpracował z technologią COM obecną w GT.
Następnie sięgamy do dokumentacji zestawień COM udostępnianej przez firmę Insert i dowiadujemy się jakie interface-y musi implementować nasz moduł i jak może komunikować się z systemem GT.
W uproszczeniu wygląda to następująco:
1. Do references modułu należy dodać:
1. ADODB
2. ZestManLib
2. Zmieniamy nazwę klasy class1 wygenerowanej przez VS i dodajemy implementacje interfaceu IZestawienieWlasne do tej klasy
Po tej operacji będzie ona wyglądała np. tak:
[ClassInterface(ClassInterfaceType.AutoDual)]
public class MojModul : IZestawienieWlasne
{
}
Aby zaimplementować ten interface w naszej klasie, musimy zaimplementować następujące metody:
Nazwa
Opis
Programy
Wykonaj
Np. w taki sposób:
public string Nazwa
{
get { return "Mój pierwszy moduł";}
}
public string Opis
{
get { return "To jest pierwszy testowy moduł";}
}
public string Program
{
get { return 1;}
}
public void Wykonaj(ZestManLib.IZestawienieComDane pZestawienieComDane)
{
}
Teraz pozostaje implementacja metody wykonaj - czyli rzeczywiście tego co nasz moduł ma robić. Najprościej stworzyć formę i wywołać metode ShowDialog(). To co znajduje będzie ona robić pozostawiam już inwencji czytelnika, ale właściwie może robić wszystko...
Jeszcze tylko jedna uwaga na temat bazy danych - GT komunikuje się z bazą poprzez ADO, natomiast dla wszystkich komponentów WinForms .NET 2.0 obowiązuje komunikacja poprzez ADO.NET. ADO i ADO.NET różnią się znacznie i chociaż można tworzyć jakieś obejścia pojawią się pytanie po co? Lepiej na podstawie połączenia z bazą danych, które dostarcza GT utworzyć drugie połączenie już przy pomocy ADO.NET, które będzie służyło do całej komunikacji z bazą danych. ADO pozwala odczytać connection string, a na jego podstawie można utworzyć connection string go ADO.NET. Powodzenia!!!
Alwik
-
dzięki za info :)
-
Przepraszam, że odświeżam temat, ale gdzie można znaleźć dokumentację insertu dot. zestawię COM?
Widzę, że chyba niektóre moduły już się pozmieniały (nigdzie nie mogę odnaleźć ZestManLib).
Będę niezmiernie wdzięczny za udostępnienie większej ilości dokumentów/przykładów.
-
Nie chcąc otwierać nowego wątku na ten sam temat podbijam pytanie poprzednika sprzed paru miesięcy.
Czy jest udostępniona gdzieś (może na forum) dokumentacja dotycząca zestawień COM dla inserta? Jeśli nie to może któryś z użytkowników jest w jej posiadaniu i mógłby się podzielić?
-
Mam pytanko do mądrzejszych czy zabierając się za zestawienie com które będzie odpalane z wnętrza Subiekta można w jakiś sposób przechwycić dane ze sfery chodzi mi o dane połączeniowe ?
-
Obiekt Baza, atrybut Polaczenie
-
Oki tylko nie bardzo wiem jak to przechwycić skąd to wyciągnąć.
W zestawieniach odpalam moje zestawienie które uruchamia Formę i teraz z jej pozycji chciałbym się dostać do danych Subiekta i tego za bardzo nie wiem jak zrobic. Wiem jak to wygląda gdy wywołuje połączenie z odrębnej aplikacji ale totalnie nie wiem jak przechwycić to z Subiekta.
-
Witam.
Właśnie męczyłem się z moim pierwszym zestawieniem COM.
Zdecydowanie pomogły mi wpisy kolegów alwik i klonel.
Mam tylko jedną uwagę do postu alwik'a: u mnie w VS 2010 musiałem we właściwościach projektu na zakładce Build zaznaczyć na dole opcję "Register for COM interop".
Po skopiowaniu przykładu i zaznaczeniu tej opcji moje pierwsze zestawienie ożyło :)
-
Witam,
też ostatnio wziąłem się za polepszanie Subiekta. Przeczytalem instrukcje no i napisałem sobie pare formów - działa super. Ale jest problem... ktoś próbował uruchomić swoje zestawienie ponownie, bez wcześniejszego restartu Subiekta?
Moje spostrzeżenia
1. po uruchomieniu Subiekta, dopóki nie wybierzemy zestawienia nie jest ono załadowane (można dll'ke zmieniać)
2. Po załadowaniu zestawienia.. i stosuje tradycyjne ShowDialog() a później w uruchomionym oknie Close() - to niestety nie zwalnia dll'ki (ponowne uruchomienie zestawienia jest niemożliwe)
3. Po takim zabiegu nawet po zamknięciu SUbiekta.. proces subiekta nadal działa :/
4. Po zastosowaniu metod force (np. Enviroment.Exit) zamyka całego subiekta - co było do przewidzenia
Czy ktoś wie.. jak zrobić, aby można było ponownie uruchomić zestawienie? Wg mnie za 1 razem wykonuje tą metodą Wykonaj, a później już nie. A nie wiem jak zmusić subiekta to wyładowania dll'ki
-
Dispose() powinno pomóc, gdyż zgodnie z opisem metody "Form.Close" z pomocy:
The two conditions when a form is not disposed on Close is when (1) it is part of a multiple-document interface (MDI) application, and the form is not visible; and (2) you have displayed the form using ShowDialog. In these cases, you will need to call Dispose manually to mark all of the form's controls for garbage collection.
metoda ta w tym przypadku nie zwolni formy. Kod powinien wyglądać mniej więcej tak:
FormMain formMain = new FormMain(pZestawienieComDane);
formMain.ShowDialog();
formMain.Dispose();
-
Dzięki za odpowiedź. Niestety Dispose() nie działa. Ponadto nawet jakby się wykonała funkcja wówczas GC i tak zwalnia zasoby. Mój kod:
public void Wykonaj(Ins.IZestawienieComDane cd)
{
Ado.Connection ado = (Ado.Connection)cd.Connection;
string host = DanePolaczenia.GetDataSource(ado.ConnectionString);
string baza = DanePolaczenia.GetInitialCatalog(ado.ConnectionString);
string login = "trimpot";
string haslo = "xxx";
this.lc = new LinqConn(host, baza, login, haslo);
Uruchom();
}
public void Uruchom()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
DokumentyF towaryF = new DokumentyF(this.lc);
towaryF.ShowDialog();
towaryF.Dispose();
}
Hmm.. musi istnieć jakieś inne wyjście
-
No to jest winny, zgodnie z opisem z pomocy dla metody "Application.SetCompatibleTextRenderingDefault":
You should never call this method if your Windows Forms code is hosted in another application, such as Internet Explorer. Only call this method in stand-alone Windows Forms applications.
Z tą metoda też miałem podobne zachowanie zestawienia, bez niej działa jak wcześniej, czyli poprawnie.
Napisałem sobie mały starter do zestawień COM i przy próbie drugiego uruchmienia zestawienia z metodą "Application.SetCompatibleTextRenderingDefault" generowany jest wyjątek o treści: "Należy wywołać element SetCompatibleTextRenderingDefault, aby pierwszy obiekt IWin32Window został utworzony w aplikacji." Trzeba doczytać o co chodzi, ale to już innym razem.
-
O jezu.. jaka ze mnie gapa. Tak to jest jak się przekleja kod:) oczywiście nie może być Application.SetCompatibleTextRenderingDefault. Bardzo dziękuję za pomoc.
Mam jeszcze jeden dziwny problem.. u mnie na lapku moduł się bez problemu rejestruje do Subiekta, a jak chciałem dziś dziewczynom wgrać bo błąd: że moduł nie zawiera prawidłowych komponentów :/ Próbowałem nawet rejestrować RegAsm - zgodnie z zaleceniami w dokumentacji, ale bez skutecznie.
Czego to może być wina? Przenosze na inyy komp cały katalog release z VS na inny komp
-
Rozumiem, że to standardowy, nic nie mówiący błąd z Subiekta ? W kodzie widziałem Linq'a, a to już chyba .NET 3.5 - jest na stacji ? No i czy zostały skopiowane wszystkie używane Interop'y ?
-
GT bazuje na dotnecie 2 i taki trzeba używać w rozszerzeniach COM czy Sferycznych inaczej dzieją się jakieś dziwne rzeczy. musiałem np. instalować na końcówkach kawałek VS2010 bo czegoś tam brakowało pomimo wszelkich update'ów. downgrade z 3.5 do 2.0 załatwił problem
-
Pozwole sobie odkopać temat bo mój problem dotyczy poruszanego tu problemu.
Próbuje zapoznać się z zestawieniami COM.
Zgodnie z tym co wyczytałem w tym temacie utworzyłem projekt klasy, we właściwościach projektu wybrałem .NET Framework 2.0, zaznaczyłem Make assembly COM-Visible i dodatkowo automatyczną rejestrację w systemie (Register for COM interop).
Dodałem referencje do ZestManLib, a w kodzie wyklepałem:
using System;
using System.Collections.Generic;
using System.Text;
using ZestManLib;
namespace ClassLibrary3
{
public class Class1: IZestawienieWlasne
{
public string Nazwa
{
get { return "Nazwa mojego zestawienia"; }
}
public string Opis
{
get { return "Opis mojego pierwszego zestawienia"; }
}
public int Programy
{
get { return 1; }
}
public void Wykonaj(IZestawienieComDane pZestawienieComDane)
{
Form1 form1 = new Form1();
form1.Show();
}
}
}
jednak przy próbie dodania do zestawień Subiekt zwraca błąd:
Wskazany plik nie zawiera poprawnych komponentów zestawień.
Co mogłem zrobić źle ?
-
Co mogłem zrobić źle ?
Niestety nie napisałeś co dokładnie zrobiłeś... od momentu utworzenia biblioteki i jej rejestracji ?
-
hmmm....
nie do końca rozumiem...
tak jak napisałem:
1. stworzyłem projekt klasy (zgodnie z opisem w tym temacie)
2. przy kompilacji biblioteka została zarejestrowana w systemie
3. spróbowałem dodać to zestawienie do subiekta (prawoklik dodaj własne COM) i Subiekt zwrócił błąd "Wskazany plik nie zawiera poprawnych komponentów zestawień."
chyba nic więcej nie robiłem :)
-
Jak to często bywa wszystko rozbija się o szczegóły... Nie napisałeś z jakiej lokalizacji wskazywałeś bibliotekę przy dodawaniu zestawienia SQL - z katalogu VS czy gdzieś skopiowałeś ?
-
Wskazywałem plik w domyślej lokalizacji VS czyli u mnie :
C:\Users\Tomasz\Documents\Visual Studio 2013\Projects\ClassLibrary3\ClassLibrary3\bin\Debug
-
Rozumiem, że masz w katalogu biblioteki interop'a "Interop.ZestManLib.dll' ? Spróbuj w takim razie jeszcze wyrejestrować bibliotekę i zarejestrować ponownie za pomocą VS, jeśli to nic nie zmieni to zrób to ręcznie.
-
Ręczna rejestracja biblioteki pomogła - dziękuję za pomoc :)
-
Z góry przepraszam za wykopanie starego tematu, ale czy ktoś z Was mógłby podpowiedzieć, jak w tworzonym zestawieniu COM wykorzystać przestrzeń oferowaną przez okno Subiekta, zamiast tworzyć nową formę?
-
Nijak.
Jeśli używasz Sfery to możesz wywołać pewne okna, ale bezpośrednio do interfejsu GT nie masz dostępu.
-
Nie wiem o co dokładnie pytasz, więc odpowiem na pytanie jak je zrozumiałem... Niestety nie da się uruchomić zestawienia COM w głównym oknie Subiekta/ w kolejnej zakładce, takie możliwości są dopiero w Navireo.
-
Rozumiem, dziękuję bardzo. W miarę możliwości poprosiłbym jeszcze o wyjaśnienie w kwestii dostępu do bazy danych ( C# ).
Czy ktoś mógłby się podzielić działającym przykładem? Czy w chwili obecnej również powinno się korzystać z Connection aby utworzyć połączenie ADO.NET, czy też można wykorzytać do tego celu obiekt PolaczenieAdoNet?
-
Można wykorzystać obiekt PolaczenieAdoNet
-
Spróbuję precyzyjniej, poniższy kod działa, jakkolwiek muszę mieć using ADODB
Connection sqlConn = (Connection)pZestawienieComDane.Connection;
string str = sqlConn.ConnectionString.ToLower();
Dążę do postaci:
SqlConnection sqlConn = (SqlConnection)pZestawienieComDane.PolaczenieAdoNet;
string str = sqlConn.ConnectionString.ToLower();
.. tak by uniknąć (zbędnego?) usinga. Póki co, nie działa. Czy to dobry kierunek?
-
Kierunek dobry, ale co znaczy "nie działa"?
-
Już wyjaśniam, otóż ten kod:
public void Wykonaj(IZestawienieComDane pZestawienieComDane)
{
Connection sqlConn = (Connection)pZestawienieComDane.Connection;
string str = sqlConn.ConnectionString.ToLower();
Form1 form1 = new Form1();
form1.Text = str;
form1.Show();
}
Powoduje otwarcie okna, z tytułem okna o treśći stringa str (działa). Gdy zamienię linijkę z Conenction (..) na:
SqlConnection sqlConn = (SqlConnection)pZestawienieComDane.PolaczenieAdoNet;
okno nie pokazuje się (nie działa).
-
Nie wiem dlaczego tak jest, ale na początek zrobiłbym 2 rzeczy
1. zamiast wyświetlania connectionstinga sprawdziłbym stan połączenia. Wtedy będzie wiadomo coś więcej.
2. miałem przypadki że połączenie nie było tworzone, bo tak. Pomagała zmiana parametrów startowych Subiekta.
Zamiast <nazwa_komputera>\<instancja> spróbuj <ip_komputera>\<instancja>
Jeśli nie pomoże to dodaj jeszcze port (<ip_komputera>\<instancja>,<port>)
Ostatnio walczyłem z takim przypadkiem, kiedy jeden z moich dodatków u jednego klienta nie chciał utworzyć połączenia, dopóki nie dodałem portu.
Tylko u tego jednego klienta.
Nie wiem dlaczego.
-
Zdarzają się takie przypadki nawet w sieci wewnętrznej, ze bez podania portu nie ma połączenia. Nie udało mi się znaleźć przyczyny.
-
Dziękuję zgromadzonym za cierpliwość. Dla potomnych: obecnie najbardziej kompatybilnym rozwiązaniem jest 'poszatkować' uzyskany ciąg połączenia ADO, wyciągając potrzebne parametry (w C# funkcje Substring i IndexOf).
Ostatnia kwestia: gdyby przyszło mi do głowy, aby używać Sfery w zestawawieniu COM, skąd pobrać hasło zalogowanego użytkownika (OperatorHaslo)?
-
Ostatnia kwestia: gdyby przyszło mi do głowy, aby używać Sfery w zestawawieniu COM, skąd pobrać hasło zalogowanego użytkownika (OperatorHaslo)?
No z bazy danych programu, z tabeli z użytkownikami "pd_Uzytkownik", z kolumny "uz_Haslo"...
-
Dla potomnych: obecnie najbardziej kompatybilnym rozwiązaniem jest 'poszatkować' uzyskany ciąg połączenia ADO, wyciągając potrzebne parametry (w C# funkcje Substring i IndexOf).
Guzik prawda.
Dodatek, o którym pisałem, miał pierwotnie takie właśnie rozwiązanie, z tworzeniem własnego connectionstringa i zachowywał się dokładnie tak samo jak sferyczne połączenie. Dorobiłem nawet drugą metodę (jeśli nie zadziała jedna, spróbuj drugiej) i efekt identyczny, czyli lipa.
Żeby było weselej to serwer był ustawiony na porcie 1433, to samo było ustawione w cliconfg i dopóki nie podałem portu wprost ni cholery.
-
Dla potomnych: obecnie najbardziej kompatybilnym rozwiązaniem jest 'poszatkować' uzyskany ciąg połączenia ADO, wyciągając potrzebne parametry (w C# funkcje Substring i IndexOf).
Guzik prawda.
Dodatek, o którym pisałem, miał pierwotnie takie właśnie rozwiązanie, z tworzeniem własnego connectionstringa i zachowywał się dokładnie tak samo jak sferyczne połączenie. Dorobiłem nawet drugą metodę (jeśli nie zadziała jedna, spróbuj drugiej) i efekt identyczny, czyli lipa.
Żeby było weselej to serwer był ustawiony na porcie 1433, to samo było ustawione w cliconfg i dopóki nie podałem portu wprost ni cholery.
Nie jestem jeszcze tak biełgy w te klocki, stwierdzam tylko 'czy działa' lub 'czy nie'.
Co by nie było byłbym wdzięczny gdybyś mógł się podzielić zawartością swojego connection stringa za pomocą obiektu PolaczenieAdoNet, jeśli się czymś różni.
-
Dla potomnych: obecnie najbardziej kompatybilnym rozwiązaniem jest 'poszatkować' uzyskany ciąg połączenia ADO, wyciągając potrzebne parametry (w C# funkcje Substring i IndexOf).
Guzik prawda.
Dodatek, o którym pisałem, miał pierwotnie takie właśnie rozwiązanie, z tworzeniem własnego connectionstringa i zachowywał się dokładnie tak samo jak sferyczne połączenie. Dorobiłem nawet drugą metodę (jeśli nie zadziała jedna, spróbuj drugiej) i efekt identyczny, czyli lipa.
Żeby było weselej to serwer był ustawiony na porcie 1433, to samo było ustawione w cliconfg i dopóki nie podałem portu wprost ni cholery.
Nie jestem jeszcze tak biełgy w te klocki, stwierdzam tylko 'czy działa' lub 'czy nie'.
Co by nie było byłbym wdzięczny gdybyś mógł się podzielić zawartością swojego connection stringa za pomocą obiektu PolaczenieAdoNet, jeśli się czymś różni.
Niczym się nie różni, jak działa to oboma metodami, jak nie działa to żadną.
-
Jeśli pozwolicie, chciałbym odkopać ten temat. W sumie to samo:
[ClassInterface(ClassInterfaceType.AutoDual)]
public class MojeRozszerzenie : IZestawienieWlasne
{
public string Nazwa
{
get { return "Moje rozszerzenie"; }
}
public string Opis
{
get { return "Mój opis"; }
}
public int Programy
{
get { return 1; }
}
public void Wykonaj(IZestawienieComDane pZestawienieComDane)
{
try
{
SqlConnection sq = (SqlConnection)pZestawienieComDane.PolaczenieAdoNet;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Wyskakuje taki błąd: Nie można przekonwertować typu „System.__ComObject” na „System.Data.SqlClient.SqlConnection”.
Tu uprzejma prośba i pytanie: jak poprawnie użyć PolaczenieAdoNet ?
-
Użycie jest poprawne tylko nie wiadomo nic o środowisku programistycznym - czy przypadkiem nie korzystasz z .NET 4.0 lub wyższego ?
-
Dzięki za szybką odpowiedź. C#; .net 4.8.
-
Jako obejście należy pobrać dane logowania z ciągu połączenia obiektu ADODB.Connection i samodzielnie utworzyć ciąg połączenia dla obiektu SqlConnection.