Skocz do zawartości

Łukasz Kubacki

InsERT
  • Liczba zawartości

    148
  • Rejestracja

  • Ostatnia wizyta

  • Wygrane w rankingu

    2

Zawartość dodana przez Łukasz Kubacki

  1. Co do tego: Ten "Error!" nie ma znaczenia - wysepuje on zawsze, gdy używa się metody z kodu w edytorze. Na moim przykładzie użycia metody PobierzWartoscSlownikaWlasnego też pojawia się taki sam "Error!" W podglądzie nigdy nie będzie wartości pól - bo nie są ładowane żadne prawdziwe dane. Pole jest puste na wydruku, dlatgo, że identyfikatorowi "I0" nie odpowiada żadne pole zaawansowane lub odpowiada pole inne niż słownikowe o słowniku "Wykonawca"
  2. We wzorcu brakuje usinga: using InsERT.Moria.Wydruki; Nie ma to znaczenia - ja wstawiam na końcu klasy.
  3. W takim razie zdejmiemy blokadę na dezaktywację wykorzystanych pozycji słownika. Co do wyświetlania w Popraw, to musimy się jeszcze zastanowić czy wybrać puste, czy nadal wyświetlać wartość, czy jakoś inaczej jeszcze to pokazywać. Będę dążył, aby weszło to do wersji wiosennej, ale 100% gwarancji w tej chwili dać nie mogę
  4. Nie pokazanie na liście jest oczywiste, ale gdy wartość jest wybrana w jakimś obiekcie i dokonano jej dezaktywacji w słowniku, czyli:
  5. Taka opcja jest w polach własnych v2: Po wyłączeniu opcji "Aktywna" przy danej wartości słownika, ta wartość nie pojawi się już na liście wartości do wyboru. Komunikat, który Pan otrzymuje przy próbie zapisania słownika po wyłączeniu opcji "Aktywna" dla pewnych wartości: wynika stąd, że wartość, którą próbuje pan dezaktywować została użyta - w Pana przypadku została użyta w obiekcie "Zamówienie od klienta" W tej chwili nie dopuszczamy do dezaktywacji wartości, która została użyta. Jeśli dopuszczalibyśmy możliwość dezaktywacji wartości, która została użyta, to co miało by się wyświetlić w obiekcie "Zamówienie od klienta", gdy wybranej wartości już nie ma do wyboru? "brak" - a czy nie byłoby to mylące? bo "brak" oznacza, że nie ustawiono żadnej wartości w słowniku. Z powyższego względu zdecydowaliśmy się narazie na taką blokadę - być może ta blokada jest jednak zbyt dużym ograniczeniem i powinna zostać zniesiona z wyświetlaniem "brak" zamiast nieaktywnej wartości? Na teraz, jeśli ustawi Pan w obiekcie "Zamówienie od klienta" wartość słownika na "brak", wtedy będzie Pan mógł dezaktywować daną wartość.
  6. Od nexo 32.0.0 w module konfiguracji pól własnych obiektu można wyświetlić kolumnę Id (domyślnie jest ona ukryta):
  7. Tak jak napisał Pan Ząbik proszę przywrócić podmiot z kopii zapasowej utworzonej sprzed dodania pól własnych v1. Jeśli nie ma Pan takiej kopii lub została wykonana dawno i nie może Pan jej użyć, to bez przesłania podmiotu do nas się nie obejdzie. Taki problem występuje tylko w polach v1. W polach v2 nigdy nie będzie takiego problemu, dlatego po przywróceniu z kopii zapasowej proszę przeczytać informację o przejściu na pola własne v2. Informacja taka pojawia się w nexo od wersji 30.0.0. Pola własne v1 nie są już rozwijane.
  8. Pola słownikowe Jeszcze chciałbym zwrócić uwagę na pola słownikowe. W moim przykładzie mam dwa pola słownikowe: Pole typu "Słownik własny" o nazwie "pz slownik", które ma identyfikator: Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv2.I1 Pole typu "Słownik systemowy" walut o nazwie "pz waluta", które ma identyfikator: Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv2.G0 Identyfikatory pól słownikowych mają w sobie klucz pozycji słownika, a nie wartość pozycji słownika. Dlatego do pobrania wartości pozycji słownika, na podstawie klucza trzeba posłużyć się pomocniczymi metodami, które trzeba dodać w zakładce "Code": Najpierw trzeba dodać na początku wzorca użycie przestrzeni nazw (ang. using): using InsERT.Moria.PolaWlasne2; using InsERT.Moria.Narzedzia.PolaWlasne2; //trzeba też sprawdzić, czy we wzorcu są poniższe dwa usingi i gdy jakiegoś brakuje, to należy go także wstawić: using InsERT.Moria.Wydruki; using System.Linq; Następnie można wstawić poniższe metody: public string PobierzWartoscSlownikaWlasnego(string nazwaSlownika, int? klucz) { if (klucz == null) return null; var pw2Helper = PolaWlasne2Helper.BusinessObjectValue as IPolaWlasne2HelperWydruku; var slownik = pw2Helper.SlownikiWlasne.PobierzDefinicjeSlownikaWlasnego(nazwaSlownika); if (slownik == null) throw new InvalidOperationException("Nie znaleziono słownika własnego: " + nazwaSlownika); var pozycja = slownik.UtworzZapytanieLinq().FirstOrDefault(p => p.Klucz == klucz); return pozycja != null ? pozycja.Wartosc : null; } public string PobierzWartoscSlownikaWlasnegoSqlByInt(string nazwaSlownika, int? klucz) { if (klucz == null) return null; var pw2Helper = PolaWlasne2Helper.BusinessObjectValue as IPolaWlasne2HelperWydruku; var slownik = pw2Helper.SlownikiWlasne.PobierzDefinicjeSlownikaWlasnegoSql(nazwaSlownika); if (slownik == null) throw new InvalidOperationException("Nie znaleziono słownika własnego SQL: " + nazwaSlownika); var pozycja = ((ISlownikoweZrodloDanych<int>)slownik).UtworzZapytanieLinq().FirstOrDefault(p => p.Klucz == klucz); return pozycja != null ? pozycja.Wartosc : null; } public string PobierzWartoscSlownikaWlasnegoSqlByGuid(string nazwaSlownika, Guid? klucz) { if (klucz == null) return null; var pw2Helper = PolaWlasne2Helper.BusinessObjectValue as IPolaWlasne2HelperWydruku; var slownik = pw2Helper.SlownikiWlasne.PobierzDefinicjeSlownikaWlasnegoSql(nazwaSlownika); if (slownik == null) throw new InvalidOperationException("Nie znaleziono słownika własnego SQL: " + nazwaSlownika); var pozycja = ((ISlownikoweZrodloDanych<Guid>)slownik).UtworzZapytanieLinq().FirstOrDefault(p => p.Klucz == klucz); return pozycja != null ? pozycja.Wartosc : null; } public InsERT.Moria.ModelDanych.Waluta PobierzWartoscSlownikaSystemowegoWalut(Guid? klucz) { if (klucz == null) return null; var pw2Helper = PolaWlasne2Helper.BusinessObjectValue as IPolaWlasne2HelperWydruku; var slownik = pw2Helper.SlownikiWlasne.PobierzDefinicjeSlownikaWalut(); return slownik.UtworzZapytanieLinqTypowane().FirstOrDefault(p => p.Id == klucz); } public InsERT.Moria.ModelDanych.Magazyn PobierzWartoscSlownikaSystemowegoMagazynow(int? klucz) { if (klucz == null) return null; var pw2Helper = PolaWlasne2Helper.BusinessObjectValue as IPolaWlasne2HelperWydruku; var slownik = pw2Helper.SlownikiWlasne.PobierzDefinicjeSlownikaMagazynow(); return slownik.UtworzZapytanieLinqTypowane().FirstOrDefault(p => p.Id == klucz); } public InsERT.Moria.ModelDanych.RachunekBankowy PobierzWartoscSlownikaSystemowegoRachunkow(int? klucz) { if (klucz == null) return null; var pw2Helper = PolaWlasne2Helper.BusinessObjectValue as IPolaWlasne2HelperWydruku; var slownik = pw2Helper.SlownikiWlasne.PobierzDefinicjeSlownikaRachunkowBankowych(); return slownik.UtworzZapytanieLinqTypowane().FirstOrDefault(p => p.Id == klucz); } Metody te służą odpowiednio: PobierzWartoscSlownikaWlasnego(nazwaSlownika, klucz) - zwraca wartość słownika własnego dla danego klucza PobierzWartoscSlownikaWlasnegoSqlByInt(nazwaSlownika, klucz) - zwraca wartość słownika własnego SQL o kluczu Int PobierzWartoscSlownikaWlasnegoSqlByGuid(nazwaSlownika, klucz) - zwraca wartość słownika własnego SQL o kluczu Guid PobierzWartoscSlownikaSystemowegoWalut(klucz) - zwraca walutę dla danego klucza PobierzWartoscSlownikaSystemowegoMagazynow(klucz) - zwraca magazyn dla danego klucza PobierzWartoscSlownikaSystemowegoRachunkow(klucz) - zwraca rachunek bankowy dla danego klucza Poniżej przykład użycia:
  9. Istnieją dwa sposoby na odczytanie wartości pól własnych v2 na wydrukach: po przez użycie interfejsu IPolaWlasneAdv2Accessor; szczegóły znajdują się w osobnym poście: po przez użycie identyfikatorów pól własnych; co zostało opisane w tym poście Historycznie rzecz ujmując najpierw powstał sposób związany z użyciem interfejsu IPolaWlasneAdv2Accessor jednak okazało się, że zwraca on zawsze pola z pierwszej pozycji na wydruku, w związku z tym problemem powstał sposób oparty o identyfikatory. W wersji 43.0.0 nexo poprawiliśmy jednak problem ze zwracaniem pierwszej pozycji na wydruku przy użyciu IPolaWlasneAdv2Accessor, dlatego oba powyższe sposoby stały się tak samo akceptowalne. Identyfikator pola własnego to nazwa kolumny w bazie danych, pod którą dostępne jest to pole. Aby sprawdzić jaki identyfikator odpowiada jakiemu polu należy wejść do modułu konfiguracji pól własnych obiektu i wyświetlić tam kolumnę Id (dostępną od nexo 32.0.0). Domyślnie kolumna Id jest ukryta: Więcej o identyfikatorach pól własnych można poczytać w poście dotyczącym struktury pól własnych v2 w bazie danych: Po tym wstępie możemy przejść do konkretów: Aby móc odwoływać się do pól własnych na wzorcu po przez ich identyfikatory, należy w drzewie obiektów znaleźć obiekt, który posiada pola własne v2 np. chcąc na wzorcu "FS standard" mieć dostęp do pól własnych v2 nabywcy, trzeba znaleźć: "Business Objects->Nabywca->Podmiot->PodmiotDlaKtoregoHistoria". Po znalezieniu kliknąć prawym przyciskiem myszy i wybrać "New Business Object", zaznaczyć "Child of Business Object", wybrać "PolaWlasneAdv2", kliknąć "OK" i ponownie "OK": Po wykonaniu tego w drzewie obiektów pojawią się identyfikatory pól własnych v2: Aby widzieć jakie identyfikatory odpowiadają jakim polom, identyfikatorom można ustawić aliasy. Robi się to po przez kliknięcie 2x na dany identyfikator i wypełnienie "Alias": Po przydzieleniu aliasów, pojawią się one obok identyfikatorów: Od tej pory można używać pól własnych v2 po przez ich identyfikatory np.:
  10. Zaktualizowałem zapytanie wypisujące wszystkie pola zaawansowane o wyświetlanie nazw nowych słowników systemowych Magazynów i Rachunków bankowych dodanych w nexo v31
  11. The error of compilation The error of compilation is found in the 'ZkStandard' report: Nie można odnaleźć nazwy typu lub przestrzeni nazw „IPolaWlasne2HelperWydruku” (czy nie brakuje dyrektywy „using” lub odwołania do zestawu?). Na wydruku brakuje linijki: using InsERT.Moria.Wydruki; Jak się okazuje nie wszystkie wzorce wydruków mają powyższy "using", o czym pisząc przykład nie wiedziałem.
  12. Tak, co wynika z całkowicie innej architektury pól własnych v2. W uwagach do przykładu napisano: A więc w Pana przypadku zamiast wywołania: { Dokument.PolaWlasneAdv.Torba } Należy napisać tak: { PodajTorbeDokumentu() } gdzie metodę PodajTorbeDokumentu() należy zdefiniować w zakładce "Code" tak, jak to opisano w rzeczonym przykładzie. W Pana przypadku będzie to wyglądać tak: private string PodajTorbeDokumentu() { var dokumentPW2Accessor = UtworzPolaWlasneAdv2Accessor(Dokument); //zakladajac, że nazwa pola v2 to "Torba", a typ pola to "Tekst" piszemy: return dokumentPW2Accessor.PobierzWartoscTypuTekst("Torba"); }
  13. Proszę skorzystać z tabeli: select * from ModelDanychContainer.KonwersjaZaawansowanychPolWlasnychDoWersji2Info
  14. Co do operacji zbiorczych w polach v2 - w najbliższej wersji tego nie planujemy, zanotowałem to jednak jako rzecz do zrobienia.
  15. Proszę zobaczyć na zrzut ekranu - taki efekt osiągnąłem w polach v2 bez trudu. A zatem odpowiadając na Państwa sugestie: Grupowanie można łatwo osiągnąć dodając pole tekstowe z nazwą grupy, wpisując jako wartość domyślną kreski "----" oraz odznaczając opcję "Edytowalne". Pola v2 można ustawić w dowolnej kolejności (podczas edycji pól proszę kliknąć na jakieś pole prawym przyciskiem myszki i wybrać jedną z opcji "Przenieś…") Jakiś czas temu rozmawialiśmy wewnętrznie na temat potrzeby istnienia takiego pola - narazie odłożyliśmy realizację na bliżej nieokreślony termin. Pola v2 rozciągają się już prawidłowo (zajmując całą swoją kolumnę) - jak to widać na obrazku Zapisałem jako rzecz do zrobienia. Konkretnego terminu nie jestem stanie w tej chwili Panu podać.
  16. A więc obecnie nie da się zrobić takiej zależności głownie z powodu tego, że wartości pól zapisują się w bazie dopiero po zapisaniu całego obiektu, czyli jak Pan zmieni wartość w PoleA, to PoleB wykonując SQL z bazy nie odczyta tej wartości. Obecne typy słownikowe nie są dostosowane do takiego działania. Musielibyśmy prawdopodobnie zrobić nowy typ słownikowy coś w rodzaju: "Słownik zależny". W najbliższej przyszłości raczej nie planujemy tego - jeśli już to w trochę dalszej. Na dzień dzisiejszy proponuję zdefiniować słownik własny SQL z zapytaniem zwracającym połączone wartości w taki sposób, że jeśli TabelaA ma: Id | Nazwa 1 Kowalski 2 Nowak TabelaB ma Id | IdTabeliA | Nazwa 1 1 Jan 2 1 Michał 3 1 Janusz 4 2 Andrzej 5 2 Jan 6 2 Michał to niech zapytanie SQL zwraca połączone wartości tak: Klucz | Wartość 1 | Kowalski - Jan 2 | Kowalski - Michał 3 | Kowalski - Janusz 4 | Nowak - Andrzej 5 | Nowak - Jan 6 | Nowak - Michał będzie zatem jedno pole ze zbiorem wszystkich wartości połączonych np. myślnikiem "nadrzędna-podrzędna"
  17. W celu odczytania nazw tabel, w których przechowywane są wartości pól zaawansowanych, należy wykonać poniższe zapytanie: select konf.NazwaWyswietlanaDluga as [Nazwa w module konfiguracji pol wlasnych], extensionEntities.TableName as [Tabela z wartosciami pol zaawansowanych] from ModelDanychContainer.KonfiguracjePolWlasnych2 konf inner join DataExtensions.CurrentExtensionEntities extensionEntities on konf.MetadaneZaawansonychPolWlasnych_Id = extensionEntities.Id order by konf.NazwaWyswietlanaDluga Z powyższego zapytania dowiadujemy się, że np. tabela przechowująca wartości zaawansowanych pól własnych asortymentu to: ModelDanychContainer.Asortymenty_PolaWlasneAsortyment_Adv2 A więc aby wyświetlić wartości wszystkich pól zaawansowanych dla asortymentu trzeba wykonać zapytanie: select * from ModelDanychContainer.Asortymenty_PolaWlasneAsortyment_Adv2 gdzie [Id] [int] NOT NULL - klucz główny będący jednocześnie kluczem obcym do kolumny [Id] z tabeli ModelDanychContainer.Asortymenty [S0..99] [nvarchar](256) NULL - kolumny przechowujące wartości pól typu "Tekst" [I0..99] [int] NULL - kolumny przechowujące wartości pól typu "Liczba całkowita" [D0..99] [decimal](18, 6) NULL - kolumny przechowujące wartości pól typu "Liczba rzeczywista" [B0..99] [bit] NULL - kolumny przechowujące wartości pól typu "Wartość logiczna" [T0..99] [datetime2](7) NULL - kolumny przechowujące wartości pól typu "Data" [G0..99] [uniqueidentifier] NULL - kolumny przechowujące wartości typu GUID Widać, że nazwy kolumn przechowujące wartości pól zaawansowanych tworzone są według schematu {S|I|D|B|T|G}0..99 gdzie 0..99 jest unikatowym (w ramach typu pola) numerem. Po utworzeniu danego pola nazwa jego kolumny pozostaje już niezmienna. Poniższe zapytanie wypisze wszystkie pola zaawansowane, odpowiadające im nazwy kolumn oraz informacje o powiązanych słownikach: select extensionEntities.TableName as [Tabela z wartosciami pol zaawansowanych], extensionProperties.[Name] as [Nazwa pola], (case extensionProperties.TypeId when 1 then 'I' when 2 then 'G' when 3 then 'S' when 4 then 'D' when 5 then 'T' when 6 then 'B' end) + cast(extensionProperties.PlaceholderIndex as nvarchar(2)) as [Nazwa kolumny pola], case extensionProperties.DataSourceKind when 0 then null when 1 then N'Slownik wlasny' when 2 then N'Slownik systemowy' when 3 then N'Slownik wlasny SQL' end as [Rodzaj slownika], case extensionProperties.DataSourceKind when 0 then null when 1 then (select sw.Nazwa from ModelDanychContainer.SlownikiWlasne sw where sw.Id = extensionProperties.DataSourceId) when 2 then case extensionProperties.DataSourceId when 1 then N'ModelDanychContainer.Waluty' when 2 then N'ModelDanychContainer.Magazyny' when 3 then N'ModelDanychContainer.CentraGromadzeniaFinansow_RachunekBankowy' end when 3 then (select sd.[Name] from ModelDanychContainer.SqlDictionaries sd where sd.Id = extensionProperties.DataSourceId) end as [Nazwa slownika], case extensionProperties.DataSourceKind when 0 then null when 1 then (select sw.Id from ModelDanychContainer.SlownikiWlasne sw where sw.Id = extensionProperties.DataSourceId) when 2 then null when 3 then (select sd.Id from ModelDanychContainer.SqlDictionaries sd where sd.Id = extensionProperties.DataSourceId) end as [Id slownika] from DataExtensions.CurrentExtensionEntities extensionEntities inner join DataExtensions.CurrentExtensionProperties extensionProperties on extensionEntities.Id = extensionProperties.EntityId order by extensionEntities.TableName, extensionProperties.[Name] W przypadku, gdy pole jest typu "Słownik własny", wtedy takie pole przechowywane jest w kolumnie z prefiksem I, która to kolumna zawiera klucz obcy do pozycji słownika własnego. W przypadku, gdy pole jest typu "Słownik własny SQL", wtedy takie pole przechowywane jest w kolumnie z prefiksem I lub G w zależności od typu klucza obcego. W przypadku, gdy pole jest typu "Słownik systemowy", wtedy takie pole przechowywane jest w kolumnie I lub G w zależności od typu klucza obcego. Słowniki własne przechowywane są w tabeli ModelDanychContainer.SlownikiWlasne, a ich wartości w tabeli ModelDanychContainer.PozycjeSlownikowWlasnych Słowniki własne SQL przechowywane są w tabeli ModelDanychContainer.SqlDictionaries a wartośći oczywiście pochodzą ze zdefiniowanego zapytania SQL
  18. Istnieją dwa sposoby na odczytanie wartości pól własnych v2 na wydrukach: po przez użycie interfejsu IPolaWlasneAdv2Accessor; co zostało opisane w tym poście po przez użycie identyfikatorów pól własnych; szczegóły znajdują się w osobnym poście: Historycznie rzecz ujmując najpierw powstał sposób związany z użyciem interfejsu IPolaWlasneAdv2Accessor jednak okazało się, że zwraca on zawsze pola z pierwszej pozycji na wydruku, w związku z tym problemem powstał sposób oparty o identyfikatory. W wersji 43.0.0 nexo poprawiliśmy jednak problem ze zwracaniem pierwszej pozycji na wydruku przy użyciu IPolaWlasneAdv2Accessor, dlatego oba powyższe sposoby stały się tak samo akceptowalne. Ten post składa się z następujących części: Utworzenie przykładowego wydruku z użyciem pól własnych v1 Przejście na pola własne v2 i modyfikacja wydruku Podsumowanie Uwagi dodatkowe Utworzenie przykładowego wydruku z użyciem pól własnych v1 Na potrzeby przykładu załóżmy, że chcemy odwołać się do pól zaawansowanych nabywcy na powielonym wzorcu "FS standard" Załóżmy, że nexo jest w trybie pól v1 oraz, że zdefiniowano następujące "Pola własne klienta": - pole typu "Tekst" o nazwie "pz tekst" - pole typu "Liczba całkowita" o nazwie "pz int" - pole typu "Kwota" o nazwie "pz decimal" - pole typu "Pole wyboru" o nazwie "pz bool" - pole typu "Data" o nazwie "pz data" - pole typu "Słownik własny" o nazwie "pz slownik" - pole typu "Słownik systemowy" walut o nazwie "pz waluta" Następnie powielamy wzorzec "FS standard" i wybieramy "Popraw wzorzec". Na potrzeby przykładu w zakładce "Code" znajdujemy metodę PodajTekstNabywcy() i modyfikujemy ją tak, aby wyświetlała wartości wszystkich zaawansowanych pól własnych v1 nabywcy: private string PodajTekstNabywcy() { StringBuilder textBuilder = new StringBuilder(); //Odczyt wartości pola typu 'Tekst' string pzTekst = Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv.pztekst; textBuilder.Append(pzTekst).AppendLine(); //Odczyt wartości pola typu 'Liczba calkowita' int? pzInt = Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv.pzint; textBuilder.Append(pzInt).AppendLine(); //Odczyt wartości pola typu 'Kwota' decimal? pzDec = Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv.pzdecimal; textBuilder.Append(pzDec).AppendLine(); //Odczyt wartości pola typu 'Pole wyboru' bool? pzBool = Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv.pzbool; textBuilder.Append(pzBool).AppendLine(); //Odczyt wartości pola typu 'Data' DateTime? pzData = Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv.pzdata; textBuilder.Append(pzData).AppendLine(); //Odczyt wartości pola typu 'Słownik wlasny' var pozycjaSlownika = Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv.pzslownik; textBuilder.Append(pozycjaSlownika.Id).Append("-"); textBuilder.Append(pozycjaSlownika.Nazwa).AppendLine(); //Odczyt wartości pola typu 'Slownik systemowy' walut var waluta = Nabywca.Podmiot.PodmiotDlaKtoregoHistoria.PolaWlasneAdv.pzwaluta; textBuilder.Append(waluta.Symbol).Append("-"); textBuilder.Append(waluta.Nazwa).AppendLine(); return textBuilder.ToString(); } Proszę zwrócić uwagę na to, że encja, z której odczytujemy pola własne v1 to: Nabywca.Podmiot.PodmiotDlaKtoregoHistoria Przejście na pola własne v2 i modyfikacja wydruku Przechodzimy na pola własne v2. Po przejściu wybieramy nasz powielony wzorzec, klikamy w "Popraw wzorzec" i przechodzimy do zakładki Code. Zaczynamy od dodania na początku linijek: using InsERT.Moria.PolaWlasne2; using InsERT.Moria.Narzedzia.PolaWlasne2; //trzeba też sprawdzić, czy we wzorcu są poniższe dwa usingi i gdy jakiegoś brakuje, to należy go także wstawić: using InsERT.Moria.Wydruki; using System.Linq; następnie dodajemy poniższą metodę: private IPolaWlasneAdv2Accessor UtworzPolaWlasneAdv2Accessor(object obj) { var pw2Helper = PolaWlasne2Helper.BusinessObjectValue as IPolaWlasne2HelperWydruku; return pw2Helper.UtworzPolaWlasneAdv2Accessor(obj); } Metoda UtworzPolaWlasneAdv2Accessor(obj) przyjmuje obiekt, który posiada zaawansowane pola własne v2. Metoda ta zwraca obiekt, IPolaWlasneAdv2Accessor który umożliwia odczyt i zapis wartości pól własnych v2. IPolaWlasneAdv2Accessor został szczegółowo opisany w pomocy do Sfery. Możemy teraz zmodyfikować PodajTekstNabywcy() tak, aby wyświetlała wartości wszystkich zaawansowanych pól własnych v2 nabywcy: private string PodajTekstNabywcy() { var nabywcaPW2Accessor = UtworzPolaWlasneAdv2Accessor(Nabywca.Podmiot.PodmiotDlaKtoregoHistoria); StringBuilder textBuilder = new StringBuilder(); //Odczyt wartości pola typu 'Tekst' string pzTekst = nabywcaPW2Accessor.PobierzWartoscTypuTekst("pz tekst"); textBuilder.Append(pzTekst).AppendLine(); //Odczyt wartości pola typu 'Liczba calkowita' int? pzInt = nabywcaPW2Accessor.PobierzWartoscTypuLiczbaCalkowita("pz int"); textBuilder.Append(pzInt).AppendLine(); //Odczyt wartości pola typu 'Liczba rzeczywista' decimal? pzDec = nabywcaPW2Accessor.PobierzWartoscTypuLiczbaRzeczywista("pz decimal"); textBuilder.Append(pzDec).AppendLine(); //Odczyt wartości pola typu 'Wartosc logiczna' bool? pzBool = nabywcaPW2Accessor.PobierzWartoscTypuLogicznego("pz bool"); textBuilder.Append(pzBool).AppendLine(); //Odczyt wartości pola typu 'Data' DateTime? pzData = nabywcaPW2Accessor.PobierzWartoscTypuData("pz data"); textBuilder.Append(pzData).AppendLine(); //Odczyt wartości pola typu 'Slownik wlasny' var pozycjaSlownika = nabywcaPW2Accessor.PobierzWartoscTypuSlownikWlasny("pz slownik"); if (pozycjaSlownika != null) { textBuilder.Append(pozycjaSlownika.Klucz).Append("-"); textBuilder.Append(pozycjaSlownika.Wartosc).AppendLine(); } //Odczyt wartości pola typu 'Slownik systemowy' walut var waluta = nabywcaPW2Accessor.PobierzWartoscTypuSlownikSystemowyWalut("pz waluta"); if (waluta != null) { textBuilder.Append(waluta.Symbol).Append("-"); textBuilder.Append(waluta.Nazwa).AppendLine(); } return textBuilder.ToString(); } Podsumowanie W celu odczytania wartości pól zaawansowanych v2 danego obiektu należy w zakładce Code użyć metody UtworzPolaWlasneAdv2Accessor(obj) przekazując do niej obiekt zawierający pola własne v2 według następującej zasady: //Jeśli w trybie pól v1 odwołanie do pola wyglądało tak: string wartoscPola = Obj1.Obj2.Obj3.PolaWlasneAdv.MojePole; //to po przejściu na pola v2 należy wywołać: var encjaPW2Accessor = UtworzPolaWlasneAdv2Accessor(Obj1.Obj2.Obj3); string wartoscPola = encjaPW2Accessor.PobierzWartoscTypuTekst("Moje Pole"); Uwagi dodatkowe Uwaga 1: Skończyłem robić wydruk, uruchamiam go i otrzymuję wyjątek zamiast wartości pól v2 - oznacza to, że albo obiekt przekazany do metody UtworzPolaWlasneAdv2Accessor(obj) nie zawiera żadnego pola zaawansowanego albo pola o danych nazwach nie zostały zdefiniowane. Uwaga 2: Chciałbym odwołać się pól własnych v2 kolejnych pozycji wydruku np. kolejnych pozycji ze wzorca "FS Standard" - zalecamy utworzyć w zakładce Code metodę, która przyjmie jako parametr obiekt danej pozycji i wywołać ją: Gdzie metoda PodajPolaAsortymentu() ma postać: private string PodajPolaAsortymentu(object aso) { StringBuilder textBuilder = new StringBuilder(); var asoPW2Accessor = UtworzPolaWlasneAdv2Accessor(aso); //Odczyt wartości pola typu 'Tekst' string pzTekst = asoPW2Accessor.PobierzWartoscTypuTekst("pz tekst"); textBuilder.Append(pzTekst).AppendLine(); //analogicznie dla pozostalych pól asortymentu return textBuilder.ToString(); } Uwaga 3: Jak odczytać wartość pola typu "Słownik własny SQL" - proszę zajrzeć do pliku pomocy Sfery - interfejs IPolaWlasneAdv2Accessor został opisany w pomocy do Sfery
  19. Pozwoliłem sobie stworzyć oficjalny temat dotyczący zaawansoanych pól własnych v2:
  20. Poniższe informacje zostały pierwotnie opublikowane na Formu dla Parnterów. Pozwoliłem sobie je tu skopiować. W odpowiedzi na braki i problemy związane z funkcjonowaniem zaawansowanych pól własnych w obecnej postaci, podjęliśmy decyzję o stworzeniu nowego mechanizmu pól zaawansowanych. Ma on docelowo zastąpić mechanizm dotychczasowy. Nowe pola własne są niekompatybilne ze starymi i potrzebna będzie migracja danych. Proces migracji istniejących baz będzie bezproblemowy poza przypadkami, gdy w podmiocie są zaawansowane pola własne i dodatkowo używane są wykorzystujące je rozwiązania własne/partnerskie (rozwiązania sferyczne, raporty LINQ, raporty SQL czy wydruki własne). W takich przypadkach konieczne będzie dostosowanie tych rozwiązań do nowego mechanizmu. W związku z koniecznością zmian w rozwiązaniach własnych przewidujemy rozłożenie w czasie procesu migracji podmiotów klienckich. Zakładany harmonogram: - jesień 2019 – (wersja 27) – dodanie do nexo w laboratorium dostępnej opcji przejścia na nowe pola własne, - wiosna 2020 (wersja 30) staną się następujące rzeczy: podmioty utworzone w wersji 30 lub wyższej będą od razu działały z włączonymi polami zaawansowanymi v2 podmioty konwertowane z wersji wcześniejszej do wersji 30, które nie posiadają żadnych pól zaawansowanych, od wersji 30 będą działały z włączonymi polami v2 podmioty konwertowane z wersji wcześniejszej do wersji 30, które posiadają pola zaawansowane, pozostaną w trybie pól v1, przy czym: przycisk przejścia na pola v2 stanie się ogólnie dostępny dla wszystkich użytkowników użytkownicy będą zachęcani do przejścia na pola v2 (m.in. z sugestią wcześniejszego skontaktowania się z Partnerem/Serwisantem) powyższe oznacza, że użytkownicy z zaawansowanymi polami własnymi będą mogli odroczyć migrację na pola własne v2 do wersji 31 (czerwiec/lipiec 2020), kiedy to nastąpi automatyczna migracja Usprawnienia w nowej wersji zaawansowanych pól własnych: brak rekompilacji modelu danych po zmianach w zaawansowanych polach własnych, przyspieszony restart aplikacji po zmianach w zaawansowanych polach własnych, usunięcie błędów i problemów w działaniu, w tym także związanych z aktualizacją do nowej wersji nexo, możliwość tworzenia słowników własnych SQL. w których zbiór wartości pochodzi z wykonania zdefiniowanego zapytania SELECT, możliwość wybrania wartości domyślnej dla pola słownikowego, zastąpienie typu "kwota" bardziej uniwersalnym typem "liczba rzeczywista", dla którego można określić ilość miejsc po przecinku, możliwość określenia, oprócz wymagalności i widoczności, także tego czy pole zaawansowane ma być edytowalne oraz klonowalne, możliwość określenia kolejności wyświetlania pól zaawasnowanych w oknie edycji pól własnych obiektu, zaawansowanemu polu własnemu można przypisać dowolną ilość unikatowych aliasów nazwy. Aby pobrać lub ustawić wartość w polu można użyć jego nazwy lub jednego ze zdefiniowanych aliasów. Pozwala to na wykorzystanie tego samego pola w różnych rozwiązaniach własnych, gdy każde z rozwiązań odwołuje się do pola pod inną nazwą,[/list] Jak wypróbować nowe pola własne w wersji wcześniejszej niż 30 Aby przejść na nowe pola własne należy wejść do modułu laboratorium (Ctrl + Space + XX) i wybrać opcję "PRZEJDŹ NA POLA WŁASNE W WERSJI 2." W celu definiowania pól własnych oraz słowników w nowej wersji: 1. W konfiguracji należy wybrać "System", a następnie wyszukać jeden z modułów: - "Pola własne" - po jego wybraniu wyświetlone zostają wszystkie obiekty, dla których można definiować pola własne - "Słowniki własne" - umożliwia wyświetlanie oraz dodanie/edycję/usunięcie słowników własnych i słowników własnych SQL 2. W konfiguracji zamiast "System" można także wybrać "Pola własne" Użycie pól własnych w wersji 2 w rozwiązaniach własnych 1. W dokumentacji do sfery InsERT.nexo.Sfera.chm (gałąź "Rozszerzanie/Pola własne") znajdują się informacje: - W jaki sposób sprawdzić bieżącą wersję pól własnych - W jaki sposób odczytać informacje o zdefiniowanych zaawansowanych polach własnych wersji 2. oraz słownikach własnych wersji 2. - W jaki sposób odczytać i ustawić wartości pól zaawansowanych wersji 2. - W jaki sposób używać pól własnych w wersji 2. w zapytaniach LINQ 2. Mechanizm prostych pól własnych nie uległ zmianie - nie jest wymagana modyfikacja rozwiązania własnego, które korzysta tylko z prostych pól własnych 3. Rozwiązania własne korzystające z zaawansowanych pól własnych muszą zostać dostosowane do współpracy z wersją 2. Po konwersji podmiotu do pól własnych wersji 2., rozwiązanie własne które korzysta z zaawansowanych pól własnych w wersji 1. przestanie działać poprawnie. Użycie pól własnych w wersji 2 na wydrukach Proszę zajrzeć do osobnego tematu: Struktura pól własnych v2 w bazie danych Proszę zajrzeć do osobnego tematu:
  21. Aktualnie nie mamy opisu struktury kolumn dla "użytkowników". W najbliższym czasie postaram się napisać jak to wygląda. Dobrze Pan zauważył
  22. Pana poprzednie przykłady: Dostęp do pól v1: var towarPW = towarBO.Dane.PobierzEncjeZaawansowanychPolWlasnych(); var niebieski = sfera.PodajObiektTypu<ISlownikiWlasne>()["kolory"].Znajdz("niebieski").Dane; towarPW.UstawWartoscPola("Poleslownikowe2", niebieski); Dostęp do pól v2 od wersji 29 nexo: var towarPW = sfera.UtworzPolaWlasneAdv2Accessor(towarBO.Dane); var niebieski = towarPW.PobierzWartosciTypuSlownikWlasny("Poleslownikowe2").First(p => p.Wartosc == "niebieski"); towarPW.UstawWartoscTypuSlownikWlasny("Poleslownikowe2", niebieski.Klucz); Dostęp do pól v1: string dictk; string dictv; string dictn; foreach(dynamic dict in results.dict) { dictk = dict.k; dictn = dict.n; dictv = dict.v; var wartoscslownika = sfera.PodajObiektTypu<ISlownikiWlasne>()[dictk].Znajdz(dictv).Dane; towarPW.UstawWartoscPola(dictn,wartoscslownika); } Dostęp do pól v2 od wersji 29 nexo: var towarPW = sfera.UtworzPolaWlasneAdv2Accessor(towarBO.Dane); string dictk; string dictv; string dictn; foreach(dynamic dict in results.dict) { dictk = dict.k; dictn = dict.n; dictv = dict.v; var wartoscslownika = towarPW.PobierzWartosciTypuSlownikWlasny(dictn).First(p => p.Wartosc == dictv); towarPW.UstawWartoscTypuSlownikWlasny(dictn, wartoscslownika.Klucz); }
  23. Odczytywanie i zapisywanie wartości zaawansowanych pól własnych v2 od wersji 29 nexo W wersji 29 nexo wprowadziliśmy prostszy sposób na odczytywanie i zapisywanie wartości zaawansowanych pól własnych v2. Nowy sposób ma za zadanie ułatwić odczyt/zapis wartości dla pól typu "Słownik własny", "Słownik własny SQL" oraz "Słownik systemowy".Przykładowo, jeżeli dla Asortymentu zdefiniowano pole własne typu "Słownik własny" o nazwie "pz slownik", wtedy aby odczytać lub zapisać wartość tego pola będzie można zrobić tak: using (Uchwyt sfera = UruchomSfere()) { IAsortymenty asortymenty = sfera.PodajObiektTypu<IAsortymenty>(); IAsortyment aso = asortymenty.Znajdz("T1"); IPolaWlasneAdv2Accessor asoPW2Accessor = sfera.UtworzPolaWlasneAdv2Accessor(aso.Dane); //odczyt biezacej wartosci pola var biezacaPozycja = asoPW2Accessor.PobierzWartoscTypuSlownikWlasny("pz slownik"); if (biezacaPozycja != null) { int biezacyKlucz = biezacaPozycja.Klucz; string biezacaWartosc = biezacaPozycja.Wartosc; } //pobranie wszystkich pozycji slownika var pozycjeSlownika = asoPW2Accessor.PobierzWartosciTypuSlownikWlasny("pz slownik"); foreach (var pozycja in pozycjeSlownika) { int klucz = pozycja.Klucz; string wartosc = pozycja.Wartosc; } //zapis nowej wartosci pola (dla przykładu wybieram ostatnią pozycję słownika) var nowaPozycja = pozycjeSlownika.Last(); asoPW2Accessor.UstawWartoscTypuSlownikWlasny("pz slownik", nowaPozycja.Klucz); } Metoda sfera.UtworzPolaWlasneAdv2Accessor(encja) przyjmuje encję, która posiada zaawansowane pola własne v2. Metoda ta zwraca obiekt, który umożliwia odczyt i zapis wartości pól z tej encji. Odczytanie i zapis wartości pól typu "Słownik własny SQL" i "Słownik Systemowy" odbywa się w analogiczny sposób. Odpowiednie przykłady znajdą Państwo w dokumentacji do sfery v29 w pliku InsERT.nexo.Sfera.chm (gałąź "Rozszerzanie/Pola własne/Pola własne w wersji 2"). Nowy sposób odczytu/zapisu wartości można zastosować do pól zaawansowanych wszystkich typów, nie tylko typów słownikowych. Przykładowo, jeśli dla asortymentu zdefiniowano następujące pola: 1. pole typu "Tekst" o nazwie "pz tekst" 2. pole typu "Liczba całkowita" o nazwie "pz int" 3. pole typu "Liczba rzeczywista" o nazwie "pz decimal" 4. pole typu "Wartość logiczna" o nazwie "pz bool" 5. pole typu "Data" o nazwie "pz data" Wtedy odczyt/zapis wartości tych pól wygląda następująco: using (Uchwyt sfera = UruchomSfere()) { IAsortymenty asortymenty = sfera.PodajObiektTypu<IAsortymenty>(); IAsortyment aso = asortymenty.Znajdz("T1"); IPolaWlasneAdv2Accessor asoPW2Accessor = sfera.UtworzPolaWlasneAdv2Accessor(aso.Dane); string pzTekst = asoPW2Accessor.PobierzWartoscTypuTekst("pz tekst"); //odczyt asoPW2Accessor.UstawWartoscTypuTekst("pz tekst", "abcd"); //zapis int? pzInt = asoPW2Accessor.PobierzWartoscTypuLiczbaCalkowita("pz int"); //odczyt asoPW2Accessor.UstawWartoscTypuLiczbaCalkowita("pz int", 5); //zapis decimal? pzDec = asoPW2Accessor.PobierzWartoscTypuLiczbaRzeczywista("pz decimal"); //odczyt asoPW2Accessor.UstawWartoscTypuLiczbaRzeczywista("pz decimal", 1.23m); //zapis bool? pzBool = asoPW2Accessor.PobierzWartoscTypuLogicznego("pz bool"); //odczyt asoPW2Accessor.UstawWartoscTypuLogicznego("pz bool", true); //zapis DateTime? pzData = asoPW2Accessor.PobierzWartoscTypuData("pz data"); //odczyt asoPW2Accessor.UstawWartoscTypuData("pz data", DateTime.Now); //zapis }
  24. Dotychczasowy harmonogram przewidywał: W wersji wiosennej (30) (koniec marca) staną się następujące rzeczy: podmioty utworzone w wersji 30 lub wyższej będą od razu działały z włączonymi polami zaawansowanymi v2 podmioty konwertowane z wersji wcześniejszej do 30, które nie posiadają żadnych pól zaawansowanych, od wersji 30 będą działały z włączonymi polami v2 podmioty konwertowane z wersji wcześniejszej do 30, które posiadają pola zaawansowane, pozostaną w trybie pól v1, przy czym:- przycisk przejścia na pola v2 stanie się ogólnie dostępny dla wszystkich użytkowników- użytkownicy będą zachęcani do przejścia na pola v2 (m.in. z sugestią wcześniejszego skontaktowania się z Partnerem/Serwisantem)Powyższe oznacza, że użytkownicy z zaawansowanymi polami własnymi będą mogli odroczyć migrację na pola własne v2 do wersji 31 (czerwiec/lipiec 2020), kiedy to nastąpi automatyczna migracja.
  25. Tak, pola własne v2 są przechowywane całkowicie inaczej w bazie niż pola v1
×
×
  • Dodaj nową pozycję...