Imports System.Data.SqlClient Imports System.Reflection ' =========================================================== ' =============== KOPF (imDHFAnm) ====================== ' =========================================================== Public Class cDHF_Import ' ====== Primärschlüssel (zusammengesetzt) ====== Public LizenzNr As String = "S01122" Public Property OperatorID As String Public Property VorgangID As String Public Property AnmID As String Public Property Kennung As String ' ====== Datenfelder Kopf imDHFAnm (wie geliefert) ====== Public Property DatenKomplett As Object Public Property LRN As Object Public Property TotPack As Object Public Property TotGross As Object Public Property Dest As Object Public Property InMo As Object Public Property BordMo As Object Public Property DepIdnt As Object Public Property DepNat As Object Public Property CrossIdnt As Object Public Property CrossIdntNat As Object Public Property TermDelCd As Object Public Property TermDelSit As Object Public Property InvCurr As Object Public Property InvVal As Object Public Property ConeeTraNa As Object Public Property ConeeTraStrt As Object Public Property ConeeTraPst As Object Public Property ConeeTraCty As Object Public Property ConeeTraCtry As Object Public Property ConeeTraFremdAdressID As Object Public Property ExitCORef As Object Public Property RechnungsNr As Object Public Property RechnungsDatum As Object Public Property DecTy As Object Public Property Disp As Object Public Property ArrLocAuth As Object Public Property ContInd As Object Public Property TransacCd As Object Public Property ConorTraNa As Object Public Property ConorTraStrt As Object Public Property ConorTraPst As Object Public Property ConorTraCty As Object Public Property ConorTraCtry As Object Public Property ConorTraFremdAdressID As Object Public Property KzPool As Object Public Property ConeeTraUIDCtry As Object Public Property ConeeTraUID As Object Public Property EntryCORef As Object Public Property SendungsDatum As Object Public Property PDTy As Object Public Property DRef As Object Public Property CInf As Object Public Property Cat As Object Public Property InfoText As Object Public Property SendungsNr As Object Public Property ConorTraUIDCtry As Object Public Property ConorTraUID As Object Public Property AnschreibeNr As Object Public Property RIN As Object Public Property KzAutomatik As Object Public Property SecInd As Object Public Property SpecCirc As Object Public Property TransPayTy As Object Public Property ComRef As Object Public Property LodCoRef As Object Public Property ResCd As Object Public Property DLimit As Object Public Property Route As Object Public Property SNr As Object Public Property KzEigenmassenaufteilung As Object Public Property MusterName As Object Public Property ConvRef As Object Public Property ProArrDT As Object Public Property LoadPlc As Object Public Property UnloadPlcCd As Object Public Property UnloadPlc As Object Public Property FirEntryCoRef As Object Public Property CarrTraNa As Object Public Property CarrTraStrt As Object Public Property CarrTraPst As Object Public Property CarrTraCty As Object Public Property CarrTraCtry As Object Public Property CarrTraFremdAdressID As Object Public Property NotifyTraNa As Object Public Property NotifyTraStrt As Object Public Property NotifyTraPst As Object Public Property NotifyTraCty As Object Public Property NotifyTraCtry As Object Public Property NotifyTraFremdAdressID As Object Public Property RepTraFremdAdressID As Object Public Property SumDecTraFremdAdressID As Object Public Property DecPlc As Object Public Property DecDT As Object Public Property RelationsID As Object Public Property SSt_LizenzNr As Object Public Property SSt_ID As Object Public Property SSt_ArtID As Object Public Property SSt_ProtokollKopfID As Object Public Property KzPredeclaration As Object Public Property AccDT As Object Public Property PayTy As Object Public Property DepoCd As Object Public Property WarTy As Object Public Property WarCtry As Object Public Property War As Object Public Property ZLID As Object Public Property TermDelCtry As Object Public Property TermDelPlc As Object ' ====== Navigation / Unterobjekte ====== Public Property GdsItems As New List(Of cDHF_Import_GdsItem) Private Const TBL As String = "imDHFAnm" Private ReadOnly SQL As New SQL ' ---- Konstruktor (Leeres Objekt) ---- Public Sub New() End Sub ' ---- Konstruktor mit Schlüssel + Auto-Load ---- Public Sub New(lizenzNr As String, operatorId As String, vorgangId As String, anmId As String, kennung As String) Me.LizenzNr = lizenzNr : Me.OperatorID = operatorId : Me.VorgangID = vorgangId : Me.AnmID = anmId : Me.Kennung = kennung Load() End Sub ' ---- Parameterliste dynamisch erzeugen (PK markiert) ---- Private Function GetVarList(Optional includePK As Boolean = True) As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) Dim l As New List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) ' PK If includePK Then l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("LizenzNr", LizenzNr, "LizenzNr", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("OperatorID", OperatorID, "OperatorID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("VorgangID", VorgangID, "VorgangID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("AnmID", AnmID, "AnmID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("Kennung", Kennung, "Kennung", True)) End If ' Alle Felder (Non-PK) Dim allProps = Me.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance). Where(Function(p) p.CanRead AndAlso p.CanWrite AndAlso p.Name <> NameOf(GdsItems)) For Each p In allProps If {"LizenzNr", "OperatorID", "VorgangID", "AnmID", "Kennung"}.Contains(p.Name) Then Continue For l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable(p.Name, p.GetValue(Me), p.Name, False)) Next Return l End Function ' ---- Save: Upsert + Kinder in Transaktion ---- Public Function Save() As Boolean Using conn As SqlConnection = SQL.GetNewOpenConnectionFMZOLL() Using tr = conn.BeginTransaction() Try ' Upsert Kopf Dim vars = GetVarList(includePK:=True) Dim wherePk = "WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung" Dim sqlCheck = $"IF EXISTS(SELECT 1 FROM [{TBL}] {wherePk}) BEGIN {_SqlDyn.BuildUpdateCmd(TBL, vars)} END ELSE BEGIN {_SqlDyn.BuildInsertCmd(TBL, vars)} END" Using cmd As New SqlCommand(sqlCheck, conn, tr) _SqlDyn.AddParams(cmd, vars) cmd.ExecuteNonQuery() End Using ' Kinder neu schreiben: erst löschen, dann einfügen (vereinfachte Konsistenz) DeleteChildren(conn, tr) ' Positionen + Unterpositionen schreiben For Each it In GdsItems it.LizenzNr = Me.LizenzNr it.OperatorID = Me.OperatorID it.VorgangID = Me.VorgangID it.AnmID = Me.AnmID it.Kennung = Me.Kennung it.Save(conn, tr) Next tr.Commit() Return True Catch ex As Exception tr.Rollback() VERAG_PROG_ALLGEMEIN.cErrorHandler.ERR(ex.Message, ex.StackTrace, MethodBase.GetCurrentMethod().Name) Return False End Try End Using End Using End Function Private Sub DeleteChildren(conn As SqlConnection, tr As SqlTransaction) ' Löscht alle abhängigen Einträge (DocCerts + Pack zuerst, dann GdsItems) Dim pkWhere = "WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung" Dim delDoc = $"DELETE d FROM [imDHFAnmGdsItemDocCerts] d INNER JOIN [imDHFAnmGdsItem] i ON d.LizenzNr=i.LizenzNr AND d.OperatorID=i.OperatorID AND d.VorgangID=i.VorgangID AND d.AnmID=i.AnmID AND d.Kennung=i.Kennung AND d.GdsItemID=i.GdsItemID {pkWhere.Replace("WHERE", "WHERE i.")}" Dim delPack = $"DELETE p FROM [imDHFAnmGdsItemPack] p INNER JOIN [imDHFAnmGdsItem] i ON p.LizenzNr=i.LizenzNr AND p.OperatorID=i.OperatorID AND p.VorgangID=i.VorgangID AND p.AnmID=i.AnmID AND p.Kennung=i.Kennung AND p.GdsItemID=i.GdsItemID {pkWhere.Replace("WHERE", "WHERE i.")}" Dim delIt = $"DELETE FROM [imDHFAnmGdsItem] {pkWhere}" Dim pars As New List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) From { New VERAG_PROG_ALLGEMEIN.SQLVariable("LizenzNr", LizenzNr, "LizenzNr", True), New VERAG_PROG_ALLGEMEIN.SQLVariable("OperatorID", OperatorID, "OperatorID", True), New VERAG_PROG_ALLGEMEIN.SQLVariable("VorgangID", VorgangID, "VorgangID", True), New VERAG_PROG_ALLGEMEIN.SQLVariable("AnmID", AnmID, "AnmID", True), New VERAG_PROG_ALLGEMEIN.SQLVariable("Kennung", Kennung, "Kennung", True) } For Each s In {delDoc, delPack, delIt} Using cmd As New SqlCommand(s, conn, tr) _SqlDyn.AddParams(cmd, pars) cmd.ExecuteNonQuery() End Using Next End Sub ' ---- Load: Kopf + Kinder ---- Public Sub Load() Using conn As SqlConnection = SQL.GetNewOpenConnectionFMZOLL() ' Kopf Dim selectHead = $"SELECT * FROM [{TBL}] WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung" Using cmd As New SqlCommand(selectHead, conn) cmd.Parameters.AddWithValue("@LizenzNr", LizenzNr) cmd.Parameters.AddWithValue("@OperatorID", OperatorID) cmd.Parameters.AddWithValue("@VorgangID", VorgangID) cmd.Parameters.AddWithValue("@AnmID", AnmID) cmd.Parameters.AddWithValue("@Kennung", Kennung) Using dr = cmd.ExecuteReader() If dr.Read() Then _SqlDyn.DataReaderToObject(dr, Me, GetVarList(includePK:=False)) End If End Using End Using ' Kinder laden Me.GdsItems.Clear() Dim selectIt = "SELECT * FROM [imDHFAnmGdsItem] WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung ORDER BY ItNr" Using cmd As New SqlCommand(selectIt, conn) cmd.Parameters.AddWithValue("@LizenzNr", LizenzNr) cmd.Parameters.AddWithValue("@OperatorID", OperatorID) cmd.Parameters.AddWithValue("@VorgangID", VorgangID) cmd.Parameters.AddWithValue("@AnmID", AnmID) cmd.Parameters.AddWithValue("@Kennung", Kennung) Using dr = cmd.ExecuteReader() While dr.Read() Dim it As New cDHF_Import_GdsItem() With { .LizenzNr = dr("LizenzNr").ToString(), .OperatorID = dr("OperatorID").ToString(), .VorgangID = dr("VorgangID").ToString(), .AnmID = dr("AnmID").ToString(), .Kennung = dr("Kennung").ToString(), .GdsItemID = dr("GdsItemID").ToString() } it.FillFromReader(dr) GdsItems.Add(it) End While End Using End Using ' Unterobjekte je Position laden For Each it In GdsItems it.LoadChildren(conn) Next End Using End Sub End Class ' =========================================================== ' =============== POSITION (imDHFAnmGdsItem) =========== ' =========================================================== Public Class cDHF_Import_GdsItem ' ====== FK/PK-Teil (Kopfbezug + pos-ID) ====== Public Property LizenzNr As String Public Property OperatorID As String Public Property VorgangID As String Public Property AnmID As String Public Property Kennung As String Public Property GdsItemID As String ' ====== Positionsfelder ====== Public Property ItNr As Object Public Property ComCd As Object Public Property GdsDes As Object Public Property Gross As Object Public Property Net As Object Public Property ProcCd As Object Public Property ProcAddCd As Object Public Property ItVal As Object Public Property Orig As Object Public Property Pref As Object Public Property Quota As Object Public Property ValMet As Object Public Property VATInd As Object Public Property ArtikelCode As Object Public Property InfoText As Object Public Property ArtikelMenge As Object Public Property ArtikelMengenEH As Object Public Property RezOrt As Object Public Property SNr As Object Public Property ProcTxt As Object Public Property ComplPer As Object Public Property ProsYield As Object Public Property SpecMod As Object Public Property RecCd As Object Public Property SurvCORef As Object Public Property EndCORef As Object Public Property ComRef As Object Public Property UNDangCd As Object Public Property GlobCd As Object Public Property GlobPer As Object Public Property CondCd As Object Public Property TransPayTy As Object Public Property ConorTraNa As Object Public Property ConorTraStrt As Object Public Property ConorTraPst As Object Public Property ConorTraCty As Object Public Property ConorTraCtry As Object Public Property ConorTraTIN As Object Public Property ConorTraAdressIDDHF As Object Public Property ConeeTraNa As Object Public Property ConeeTraStrt As Object Public Property ConeeTraPst As Object Public Property ConeeTraCty As Object Public Property ConeeTraCtry As Object Public Property ConeeTraTIN As Object Public Property ConeeTraAdressIDDHF As Object Public Property ExtraDEBundesland As Object ' ====== Unterlisten ====== Public Property DocCerts As New List(Of cDHF_Import_GdsItemDocCerts) Public Property Packs As New List(Of cDHF_Import_GdsItemPack) Private Const TBL As String = "imDHFAnmGdsItem" Friend Sub FillFromReader(dr As SqlDataReader) Dim props = Me.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance). Where(Function(p) p.CanRead AndAlso p.CanWrite AndAlso p.Name <> NameOf(DocCerts) AndAlso p.Name <> NameOf(Packs)) For Each p In props If dr.GetSchemaTable().Rows.Cast(Of DataRow)().Any(Function(r) r("ColumnName").ToString() = p.Name) Then If dr.IsDBNull(dr.GetOrdinal(p.Name)) Then p.SetValue(Me, Nothing) Else p.SetValue(Me, dr(p.Name)) End If End If Next End Sub Private Function GetVarList(Optional includePK As Boolean = True) As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) Dim l As New List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) If includePK Then l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("LizenzNr", LizenzNr, "LizenzNr", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("OperatorID", OperatorID, "OperatorID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("VorgangID", VorgangID, "VorgangID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("AnmID", AnmID, "AnmID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("Kennung", Kennung, "Kennung", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("GdsItemID", GdsItemID, "GdsItemID", True)) End If Dim skip = New HashSet(Of String)(StringComparer.OrdinalIgnoreCase) From { "LizenzNr", "OperatorID", "VorgangID", "AnmID", "Kennung", "GdsItemID", NameOf(DocCerts), NameOf(Packs) } For Each p In Me.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance) If Not p.CanRead OrElse Not p.CanWrite OrElse skip.Contains(p.Name) Then Continue For l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable(p.Name, p.GetValue(Me), p.Name, False)) Next Return l End Function Friend Sub Save(conn As SqlConnection, tr As SqlTransaction) ' Upsert Position Dim vars = GetVarList(includePK:=True) Dim wherePk = "WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung AND [GdsItemID]=@GdsItemID" Dim sqlCheck = $"IF EXISTS(SELECT 1 FROM [{TBL}] {wherePk}) BEGIN {_SqlDyn.BuildUpdateCmd(TBL, vars)} END ELSE BEGIN {_SqlDyn.BuildInsertCmd(TBL, vars)} END" Using cmd As New SqlCommand(sqlCheck, conn, tr) _SqlDyn.AddParams(cmd, vars) cmd.ExecuteNonQuery() End Using ' Kinder neu schreiben (DocCerts, Packs): delete + insert DeleteChildren(conn, tr) For Each d In DocCerts d.LizenzNr = LizenzNr : d.OperatorID = OperatorID : d.VorgangID = VorgangID : d.AnmID = AnmID : d.Kennung = Kennung d.GdsItemID = GdsItemID d.Save(conn, tr) Next For Each p In Packs p.LizenzNr = LizenzNr : p.OperatorID = OperatorID : p.VorgangID = VorgangID : p.AnmID = AnmID : p.Kennung = Kennung p.GdsItemID = GdsItemID p.Save(conn, tr) Next End Sub Private Sub DeleteChildren(conn As SqlConnection, tr As SqlTransaction) Dim wherePk = "WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung AND [GdsItemID]=@GdsItemID" For Each ttt In {"imDHFAnmGdsItemDocCerts", "imDHFAnmGdsItemPack"} Using cmd As New SqlCommand($"DELETE FROM [{ttt}] {wherePk}", conn, tr) cmd.Parameters.AddWithValue("@LizenzNr", LizenzNr) cmd.Parameters.AddWithValue("@OperatorID", OperatorID) cmd.Parameters.AddWithValue("@VorgangID", VorgangID) cmd.Parameters.AddWithValue("@AnmID", AnmID) cmd.Parameters.AddWithValue("@Kennung", Kennung) cmd.Parameters.AddWithValue("@GdsItemID", GdsItemID) cmd.ExecuteNonQuery() End Using Next End Sub Friend Sub LoadChildren(conn As SqlConnection) ' DocCerts DocCerts.Clear() Dim sDoc = "SELECT * FROM [imDHFAnmGdsItemDocCerts] WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung AND [GdsItemID]=@GdsItemID ORDER BY DocCertsID" Using cmd As New SqlCommand(sDoc, conn) cmd.Parameters.AddWithValue("@LizenzNr", LizenzNr) cmd.Parameters.AddWithValue("@OperatorID", OperatorID) cmd.Parameters.AddWithValue("@VorgangID", VorgangID) cmd.Parameters.AddWithValue("@AnmID", AnmID) cmd.Parameters.AddWithValue("@Kennung", Kennung) cmd.Parameters.AddWithValue("@GdsItemID", GdsItemID) Using dr = cmd.ExecuteReader() While dr.Read() Dim d As New cDHF_Import_GdsItemDocCerts() With { .LizenzNr = LizenzNr, .OperatorID = OperatorID, .VorgangID = VorgangID, .AnmID = AnmID, .Kennung = Kennung, .GdsItemID = GdsItemID, .DocCertsID = dr("DocCertsID").ToString() } d.FillFromReader(dr) DocCerts.Add(d) End While End Using End Using ' Packs Packs.Clear() Dim sPack = "SELECT * FROM [imDHFAnmGdsItemPack] WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung AND [GdsItemID]=@GdsItemID ORDER BY PackID" Using cmd As New SqlCommand(sPack, conn) cmd.Parameters.AddWithValue("@LizenzNr", LizenzNr) cmd.Parameters.AddWithValue("@OperatorID", OperatorID) cmd.Parameters.AddWithValue("@VorgangID", VorgangID) cmd.Parameters.AddWithValue("@AnmID", AnmID) cmd.Parameters.AddWithValue("@Kennung", Kennung) cmd.Parameters.AddWithValue("@GdsItemID", GdsItemID) Using dr = cmd.ExecuteReader() While dr.Read() Dim p As New cDHF_Import_GdsItemPack() With { .LizenzNr = LizenzNr, .OperatorID = OperatorID, .VorgangID = VorgangID, .AnmID = AnmID, .Kennung = Kennung, .GdsItemID = GdsItemID, .PackID = dr("PackID").ToString() } p.FillFromReader(dr) Packs.Add(p) End While End Using End Using End Sub End Class ' =========================================================== ' ============ DOC/CERTS (imDHFAnmGdsItemDocCerts) ===== ' =========================================================== Public Class cDHF_Import_GdsItemDocCerts ' FK/PK Public Property LizenzNr As String Public Property OperatorID As String Public Property VorgangID As String Public Property AnmID As String Public Property Kennung As String Public Property GdsItemID As String Public Property DocCertsID As String ' Felder Public Property DocCd As Object Public Property DTy As Object Public Property DRef As Object Public Property IssD As Object Public Property IssCtry As Object Public Property DTIN As Object Public Property Curr As Object Public Property Avail As Object Public Property UidVid As Object Public Property IssAdm As Object Public Property ValD As Object Public Property MaxValD As Object Public Property CInf As Object Public Property InfoLNG As Object Public Property Unit As Object Public Property Quant As Object Public Property MaxQuant As Object Public Property WOUnit As Object Public Property WOoUnit As Object Public Property WOCurr As Object Public Property WOInQuant As Object Public Property WOQuant As Object Public Property WORemQunat As Object Public Property CRefTy As Object Public Property CRefRef As Object Public Property CRefIt As Object Public Property CRefLNG As Object Public Property AvailDT As Object Public Property AdressIDDHF As Object Public Property Na As Object Public Property Strt As Object Public Property Pst As Object Public Property Cty As Object Public Property Ctry As Object Public Property LNG As Object Private Const TBL As String = "imDHFAnmGdsItemDocCerts" Private Function GetVarList(Optional includePK As Boolean = True) As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) Dim l As New List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) If includePK Then l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("LizenzNr", LizenzNr, "LizenzNr", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("OperatorID", OperatorID, "OperatorID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("VorgangID", VorgangID, "VorgangID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("AnmID", AnmID, "AnmID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("Kennung", Kennung, "Kennung", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("GdsItemID", GdsItemID, "GdsItemID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("DocCertsID", DocCertsID, "DocCertsID", True)) End If Dim skip = New HashSet(Of String)(StringComparer.OrdinalIgnoreCase) From { "LizenzNr", "OperatorID", "VorgangID", "AnmID", "Kennung", "GdsItemID", "DocCertsID" } For Each p In Me.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance) If Not p.CanRead OrElse Not p.CanWrite OrElse skip.Contains(p.Name) Then Continue For l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable(p.Name, p.GetValue(Me), p.Name, False)) Next Return l End Function Friend Sub Save(conn As SqlConnection, tr As SqlTransaction) Dim vars = GetVarList(includePK:=True) Dim wherePk = "WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung AND [GdsItemID]=@GdsItemID AND [DocCertsID]=@DocCertsID" Dim sqlCheck = $"IF EXISTS(SELECT 1 FROM [{TBL}] {wherePk}) BEGIN {_SqlDyn.BuildUpdateCmd(TBL, vars)} END ELSE BEGIN {_SqlDyn.BuildInsertCmd(TBL, vars)} END" Using cmd As New SqlCommand(sqlCheck, conn, tr) _SqlDyn.AddParams(cmd, vars) cmd.ExecuteNonQuery() End Using End Sub Friend Sub FillFromReader(dr As SqlDataReader) Dim props = Me.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance) For Each p In props If {"LizenzNr", "OperatorID", "VorgangID", "AnmID", "Kennung", "GdsItemID", "DocCertsID"}.Contains(p.Name) Then Continue For If dr.GetSchemaTable().Rows.Cast(Of DataRow)().Any(Function(r) r("ColumnName").ToString() = p.Name) Then If dr.IsDBNull(dr.GetOrdinal(p.Name)) Then p.SetValue(Me, Nothing) Else p.SetValue(Me, dr(p.Name)) End If End If Next End Sub End Class ' =========================================================== ' ================ PACK (imDHFAnmGdsItemPack) ========== ' =========================================================== Public Class cDHF_Import_GdsItemPack ' FK/PK Public Property LizenzNr As String Public Property OperatorID As String Public Property VorgangID As String Public Property AnmID As String Public Property Kennung As String Public Property GdsItemID As String Public Property PackID As String ' Felder Public Property Mark As Object Public Property Kind As Object Public Property Nr As Object Public Property Piec As Object Private Const TBL As String = "imDHFAnmGdsItemPack" Private Function GetVarList(Optional includePK As Boolean = True) As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) Dim l As New List(Of VERAG_PROG_ALLGEMEIN.SQLVariable) If includePK Then l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("LizenzNr", LizenzNr, "LizenzNr", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("OperatorID", OperatorID, "OperatorID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("VorgangID", VorgangID, "VorgangID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("AnmID", AnmID, "AnmID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("Kennung", Kennung, "Kennung", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("GdsItemID", GdsItemID, "GdsItemID", True)) l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("PackID", PackID, "PackID", True)) End If Dim skip = New HashSet(Of String)(StringComparer.OrdinalIgnoreCase) From { "LizenzNr", "OperatorID", "VorgangID", "AnmID", "Kennung", "GdsItemID", "PackID" } For Each p In Me.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance) If Not p.CanRead OrElse Not p.CanWrite OrElse skip.Contains(p.Name) Then Continue For l.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable(p.Name, p.GetValue(Me), p.Name, False)) Next Return l End Function Friend Sub Save(conn As SqlConnection, tr As SqlTransaction) Dim vars = GetVarList(includePK:=True) Dim wherePk = "WHERE [LizenzNr]=@LizenzNr AND [OperatorID]=@OperatorID AND [VorgangID]=@VorgangID AND [AnmID]=@AnmID AND [Kennung]=@Kennung AND [GdsItemID]=@GdsItemID AND [PackID]=@PackID" Dim sqlCheck = $"IF EXISTS(SELECT 1 FROM [{TBL}] {wherePk}) BEGIN {_SqlDyn.BuildUpdateCmd(TBL, vars)} END ELSE BEGIN {_SqlDyn.BuildInsertCmd(TBL, vars)} END" Using cmd As New SqlCommand(sqlCheck, conn, tr) _SqlDyn.AddParams(cmd, vars) cmd.ExecuteNonQuery() End Using End Sub Friend Sub FillFromReader(dr As SqlDataReader) Dim props = Me.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance) For Each p In props If {"LizenzNr", "OperatorID", "VorgangID", "AnmID", "Kennung", "GdsItemID", "PackID"}.Contains(p.Name) Then Continue For If dr.GetSchemaTable().Rows.Cast(Of DataRow)().Any(Function(r) r("ColumnName").ToString() = p.Name) Then If dr.IsDBNull(dr.GetOrdinal(p.Name)) Then p.SetValue(Me, Nothing) Else p.SetValue(Me, dr(p.Name)) End If End If Next End Sub End Class ' ----------------------------------------------- ' Gemeinsame Utilities für dynamische SQLs nach dem Muster aus _BASE ' ----------------------------------------------- Friend Module _SqlDyn Friend Function BuildUpdateCmd(tableName As String, vars As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable)) As String Dim sets As New List(Of String) Dim wheres As New List(Of String) For Each v In vars If v.isPrimaryParam Then wheres.Add("[" & v.Text & "] = @" & v.Scalarvariable) Else sets.Add("[" & v.Text & "] = @" & v.Scalarvariable) End If Next If sets.Count = 0 Then Throw New Exception("Keine Non-PK-Spalten für UPDATE.") Return $"UPDATE [{tableName}] SET {String.Join(",", sets)} WHERE {String.Join(" AND ", wheres)}" End Function Friend Function BuildInsertCmd(tableName As String, vars As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable)) As String Dim cols As New List(Of String) Dim pars As New List(Of String) For Each v In vars If Not v.isPrimaryParam Then cols.Add("[" & v.Text & "]") pars.Add("@" & v.Scalarvariable) Else ' PK-Spalten oft ebenfalls explizit spaltenseitig – hier mit aufnehmen, ' sofern in DB nicht als IDENTITY definiert: cols.Add("[" & v.Text & "]") pars.Add("@" & v.Scalarvariable) End If Next Return $"INSERT INTO [{tableName}] ({String.Join(",", cols)}) VALUES({String.Join(",", pars)})" End Function Friend Sub AddParams(cmd As SqlCommand, vars As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable)) For Each v In vars cmd.Parameters.AddWithValue("@" & v.Scalarvariable, If(v.Value, DBNull.Value)) Next End Sub Friend Sub DataReaderToObject(dr As SqlDataReader, target As Object, vars As List(Of VERAG_PROG_ALLGEMEIN.SQLVariable)) Dim t = target.GetType() For Each v In vars Dim pi = t.GetProperty(v.Text) If pi IsNot Nothing AndAlso Not dr.IsDBNull(dr.GetOrdinal(v.Text)) Then pi.SetValue(target, dr(v.Text)) ElseIf pi IsNot Nothing Then pi.SetValue(target, Nothing) End If Next End Sub Sub test() '' Verwendung(Beispiel) ' Kopf anlegen Dim imp As New cDHF_Import("LIC", "OP", "VORG", "ANM", "KENN") imp.RechnungsNr = "INV-2025-001" imp.InvCurr = "EUR" imp.InvVal = 12345D ' Position hinzufügen Dim it = New cDHF_Import_GdsItem() With { .GdsItemID = "1", .ItNr = 1, .ComCd = "85044030", .GdsDes = "Power Supply", .Net = 12.34D, .ItVal = 999D } ' Doc/Certs it.DocCerts.Add(New cDHF_Import_GdsItemDocCerts() With { .DocCertsID = "1", .DocCd = "N380", .DRef = "REF-123", .Avail = 1 }) ' Packstücke it.Packs.Add(New cDHF_Import_GdsItemPack() With { .PackID = "1", .Kind = "PK", .Piec = 3 }) imp.GdsItems.Add(it) ' Speichern -> speichert Kopf + Position + Unterzeilen in einer Transaktion Dim ok = imp.Save() ' Laden Dim imp2 As New cDHF_Import("S01122", "1", "VORG", "ANM", "KENN") ' -> imp2 ist nun inkl. GdsItems, DocCerts und Packs befüllt End Sub End Module