ADMIN UsrParam, DHF Import
This commit is contained in:
@@ -1428,24 +1428,7 @@ Public Class usrCntlATLAS_EZA
|
||||
End Function
|
||||
|
||||
|
||||
Private Function ToDoubleSafe(o As Object) As Double
|
||||
If o Is Nothing OrElse IsDBNull(o) Then Return 0
|
||||
|
||||
' Direkte Numerik
|
||||
If TypeOf o Is Double Then Return DirectCast(o, Double)
|
||||
If TypeOf o Is Decimal Then Return Convert.ToDouble(o)
|
||||
If TypeOf o Is Integer OrElse TypeOf o Is Int64 OrElse TypeOf o Is Int16 Then Return Convert.ToDouble(o)
|
||||
|
||||
' String-Fälle (leer, deutsch, englisch)
|
||||
Dim s = o.ToString().Trim()
|
||||
If s = "" Then Return 0
|
||||
|
||||
Dim v As Double
|
||||
If Double.TryParse(s, NumberStyles.Any, CultureInfo.CurrentCulture, v) Then Return v
|
||||
If Double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, v) Then Return v
|
||||
|
||||
Return 0 ' Notfalls 0
|
||||
End Function
|
||||
|
||||
Private Sub pnl_Paint_1(sender As Object, e As PaintEventArgs) Handles pnl.Paint
|
||||
|
||||
@@ -1497,5 +1480,309 @@ Public Class usrCntlATLAS_EZA
|
||||
Private Sub MEYLEXLSXToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles MEYLEXLSXToolStripMenuItem.Click
|
||||
importExcel_MEYLE()
|
||||
End Sub
|
||||
|
||||
Private Sub FressnapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles FressnapToolStripMenuItem.Click
|
||||
|
||||
importExcel_Fressnapf()
|
||||
End Sub
|
||||
|
||||
Private Function importExcel_Fressnapf() As Boolean
|
||||
Dim fd As New OpenFileDialog With {
|
||||
.Filter = "Excel Dateien|*.xls;*.xlsx",
|
||||
.Multiselect = True,
|
||||
.Title = "Bitte eine oder mehrere Excel-Dateien auswählen"
|
||||
}
|
||||
|
||||
If fd.ShowDialog() <> DialogResult.OK Then
|
||||
Me.Cursor = Cursors.Default
|
||||
MsgBox("Keine Datei ausgewählt!")
|
||||
Return False
|
||||
End If
|
||||
|
||||
Dim cnt As Integer = 0
|
||||
|
||||
If EZA.eza_WARENPOS.Count > 0 Then
|
||||
If vbYes = MsgBox("Sollten die aktuellen Einträge gelöscht werden?", vbYesNo) Then
|
||||
EZA.eza_WARENPOS.Clear()
|
||||
End If
|
||||
End If
|
||||
|
||||
Me.Cursor = Cursors.WaitCursor
|
||||
|
||||
For Each filePath As String In fd.FileNames
|
||||
If Not (filePath.ToLower().EndsWith(".xls") OrElse filePath.ToLower().EndsWith(".xlsx")) Then
|
||||
Continue For
|
||||
End If
|
||||
|
||||
Dim exclApp As Excel.Application = Nothing
|
||||
Dim Datei As Excel.Workbook = Nothing
|
||||
Dim Blatt As Excel.Worksheet = Nothing
|
||||
|
||||
Try
|
||||
exclApp = New Excel.Application With {
|
||||
.CutCopyMode = False,
|
||||
.DisplayAlerts = False
|
||||
}
|
||||
|
||||
Datei = exclApp.Workbooks.Open(filePath)
|
||||
Blatt = CType(Datei.Worksheets(1), Excel.Worksheet)
|
||||
Datei.Activate()
|
||||
|
||||
Try : Blatt.ShowAllData() : Catch : End Try
|
||||
|
||||
' --- Prüfe, ob Kopfzeile in Zeile 17 existiert
|
||||
If Not checkExcelHeader_Fressnapf(Blatt) Then
|
||||
Throw New ApplicationException("Excel-Struktur entspricht nicht dem erwarteten Layout (Header-Zeile 17).")
|
||||
End If
|
||||
|
||||
' --- Spalten dynamisch per Header ermitteln (Zeile 17)
|
||||
Dim colDesc = FindHeaderColumn(Blatt, 17, {"warenbeschreibung"})
|
||||
Dim colImpCode = FindHeaderColumn(Blatt, 17, {"importcodenummer", "warentarifnummer", "eztnummer", "ezt-nummer"})
|
||||
Dim colOrigin = FindHeaderColumn(Blatt, 17, {"ursprungsland", "ursprungslandcode"})
|
||||
Dim colCurrency = FindHeaderColumn(Blatt, 17, {"währung", "waehrung", "currency"})
|
||||
Dim colNetMass = FindHeaderColumn(Blatt, 17, {"nettomasse", "nettomasse", "nettomasse kg", "eigenmasse"})
|
||||
Dim colQty = FindHeaderColumn(Blatt, 17, {"menge", "quantity", "qty"})
|
||||
Dim colValue = FindHeaderColumn(Blatt, 17, {"warenwert", "invoice value", "value"})
|
||||
|
||||
' Minimal erforderliche Spalten prüfen
|
||||
If colDesc = -1 OrElse colImpCode = -1 OrElse colOrigin = -1 OrElse colCurrency = -1 OrElse colValue = -1 Then
|
||||
Throw New ApplicationException("Nicht alle erforderlichen Spaltenköpfe gefunden (Beschreibung/Warentarifnummer/Ursprungsland/Währung/Warenwert).")
|
||||
End If
|
||||
|
||||
' --- Datenbereich bestimmen: ab Zeile 18 bis erste Leerzeile in Spalte A (Pos.)
|
||||
Dim startRows As Integer = 18
|
||||
Dim endRows As Integer = startRows
|
||||
Dim usedRows As Integer = Blatt.UsedRange.Rows.Count
|
||||
|
||||
Do While endRows <= usedRows
|
||||
Dim val = Blatt.Range("A" & endRows).Value
|
||||
If val Is Nothing OrElse val.ToString().Trim() = "" Then Exit Do
|
||||
endRows += 1
|
||||
Loop
|
||||
endRows -= 1
|
||||
|
||||
If endRows < startRows Then
|
||||
Throw New ApplicationException("Keine Positionsdaten im Excel gefunden.")
|
||||
End If
|
||||
|
||||
' --- Spaltenanzahl mindestens so groß wie letzte genutzte Spalte
|
||||
Dim colCount As Integer = Math.Max(Blatt.UsedRange.Columns.Count, Math.Max(Math.Max(Math.Max(colDesc, colImpCode), Math.Max(colOrigin, colCurrency)), Math.Max(colValue, If(colNetMass < 0, 0, colNetMass))) + 1)
|
||||
If colCount < 19 Then colCount = 19 ' typischerweise A..S
|
||||
|
||||
' --- Rohdaten in DataTable übernehmen
|
||||
Dim DATA As New DataTable()
|
||||
For c As Integer = 1 To colCount
|
||||
DATA.Columns.Add("Spalte" & c, GetType(String))
|
||||
Next
|
||||
|
||||
For r As Integer = startRows To endRows
|
||||
Dim newRow As DataRow = DATA.NewRow()
|
||||
For c As Integer = 1 To colCount
|
||||
Dim value = Blatt.Cells(r, c).Value
|
||||
newRow(c - 1) = If(value IsNot Nothing, value.ToString(), "")
|
||||
Next
|
||||
' Normalisierung für Gruppierung
|
||||
If colCurrency >= 0 Then newRow(colCurrency) = newRow(colCurrency).ToString().Trim().ToUpper()
|
||||
If colOrigin >= 0 Then newRow(colOrigin) = newRow(colOrigin).ToString().Trim().ToUpper()
|
||||
DATA.Rows.Add(newRow)
|
||||
Next
|
||||
|
||||
' --- Nur numerische Pos.-Zeilen behalten (Spalte A / Index 0)
|
||||
For i As Integer = DATA.Rows.Count - 1 To 0 Step -1
|
||||
Dim posTxt As String = DATA.Rows(i)(0).ToString().Trim()
|
||||
Dim posNum As Integer
|
||||
If Not Integer.TryParse(posTxt, posNum) Then
|
||||
DATA.Rows.RemoveAt(i)
|
||||
End If
|
||||
Next
|
||||
|
||||
' --- Gruppieren nach: Beschreibung, Warentarifnummer, Ursprungsland, Währung
|
||||
Dim resultDATA As DataTable = DATA.Clone()
|
||||
|
||||
Dim groups = From row In DATA.AsEnumerable()
|
||||
Group row By
|
||||
keyDesc = row(colDesc),
|
||||
keyTariff = row(colImpCode),
|
||||
keyOrigin = row(colOrigin),
|
||||
keyCurr = row(colCurrency)
|
||||
Into grp = Group
|
||||
Select keyDesc, keyTariff, keyOrigin, keyCurr, grp
|
||||
|
||||
For Each g In groups
|
||||
Dim newRow As DataRow = resultDATA.NewRow()
|
||||
|
||||
newRow(colDesc) = g.keyDesc
|
||||
newRow(colImpCode) = g.keyTariff
|
||||
newRow(colOrigin) = g.keyOrigin
|
||||
newRow(colCurrency) = g.keyCurr
|
||||
|
||||
' Summenfelder (nur wenn vorhanden)
|
||||
If colQty >= 0 Then newRow(colQty) = g.grp.Sum(Function(r) ToDoubleSafe(r(colQty))).ToString()
|
||||
If colNetMass >= 0 Then newRow(colNetMass) = g.grp.Sum(Function(r) ToDoubleSafe(r(colNetMass))).ToString()
|
||||
newRow(colValue) = g.grp.Sum(Function(r) ToDoubleSafe(r(colValue))).ToString()
|
||||
|
||||
resultDATA.Rows.Add(newRow)
|
||||
Next
|
||||
|
||||
' --- Kopfwerte optional (z. B. Belegnummer)
|
||||
Dim HandlesRgNr As String = ""
|
||||
Try
|
||||
If Blatt.Range("A8") IsNot Nothing AndAlso Blatt.Range("A8").Value IsNot Nothing Then
|
||||
HandlesRgNr = Blatt.Range("A8").Value.ToString().Trim()
|
||||
End If
|
||||
Catch
|
||||
End Try
|
||||
|
||||
' --- Ergebniszeilen in EZA schreiben
|
||||
For Each row As DataRow In resultDATA.Rows
|
||||
Dim tariff As String = row(colImpCode).ToString().Trim()
|
||||
Dim desc As String = row(colDesc).ToString().Trim()
|
||||
If tariff = "" AndAlso desc = "" Then Continue For
|
||||
|
||||
Dim POSITION As New DAKOSY_Worker.cDakosy_EZA_Warenposition
|
||||
|
||||
' *** WARENTARIFNUMMER ***
|
||||
POSITION.ezaWP_WarennummerEZT = tariff
|
||||
|
||||
' Packstücke (nicht aus Excel, Standardwerte)
|
||||
POSITION.ezaWP_PackstueckAnzahl = "0"
|
||||
POSITION.ezaWP_PackstueckArt = "PK"
|
||||
|
||||
' *** ARTIKELPREIS (Warenwert) ***
|
||||
Dim warenwert As Double = ToDoubleSafe(row(colValue))
|
||||
POSITION.ezaWP_Artikelpreis = warenwert.ToString("N2")
|
||||
|
||||
' *** WÄHRUNG ***
|
||||
POSITION.ezaWP_ArtikelpreisWaehrung = row(colCurrency).ToString()
|
||||
|
||||
' *** BESCHREIBUNG ***
|
||||
POSITION.ezaWP_Warenbezeichnung = desc
|
||||
|
||||
' *** EIGENMASSE (aus Nettomasse, wenn vorhanden) ***
|
||||
If colNetMass >= 0 Then
|
||||
Dim netto As Double = ToDoubleSafe(row(colNetMass))
|
||||
POSITION.ezaWP_Eigenmasse = netto.ToString("N1")
|
||||
Else
|
||||
POSITION.ezaWP_Eigenmasse = "0.0"
|
||||
End If
|
||||
|
||||
' *** URSPRUNGSLAND (2-stellig) ***
|
||||
Dim ursprung As String = row(colOrigin).ToString().Trim().ToUpper()
|
||||
If ursprung.Length >= 2 Then POSITION.ezaWP_UrsprungslandCode = ursprung.Substring(0, 2)
|
||||
|
||||
' Unterlagen (optional)
|
||||
If Not String.IsNullOrWhiteSpace(HandlesRgNr) Then
|
||||
POSITION.ezaWP_UNTERLAGEN.Add(New DAKOSY_Worker.cDakosy_EZA_WarenpositionVorgelegteUnterlagen With {
|
||||
.ezaWpUl_Art = "N380",
|
||||
.ezaWpUl_Bereich = "4",
|
||||
.ezaWpUl_VorlageKz = "J",
|
||||
.ezaWpUl_Nummer = HandlesRgNr,
|
||||
.ezaWpUl_DatumAusstellung = Nothing
|
||||
})
|
||||
End If
|
||||
|
||||
EZA.eza_WARENPOS.Add(POSITION)
|
||||
cnt += 1
|
||||
Next
|
||||
|
||||
Catch ex As Exception
|
||||
Me.Cursor = Cursors.Default
|
||||
MsgBox("FEHLER beim Einlesen: " & vbCrLf & ex.Message)
|
||||
Finally
|
||||
' Ressourcen sauber freigeben
|
||||
Try
|
||||
If Datei IsNot Nothing Then Datei.Close(False)
|
||||
Catch
|
||||
End Try
|
||||
Try
|
||||
If exclApp IsNot Nothing Then exclApp.Quit()
|
||||
Catch
|
||||
End Try
|
||||
Try
|
||||
If Blatt IsNot Nothing Then System.Runtime.InteropServices.Marshal.FinalReleaseComObject(Blatt)
|
||||
Catch
|
||||
End Try
|
||||
Try
|
||||
If Datei IsNot Nothing Then System.Runtime.InteropServices.Marshal.FinalReleaseComObject(Datei)
|
||||
Catch
|
||||
End Try
|
||||
Try
|
||||
If exclApp IsNot Nothing Then System.Runtime.InteropServices.Marshal.FinalReleaseComObject(exclApp)
|
||||
Catch
|
||||
End Try
|
||||
Blatt = Nothing : Datei = Nothing : exclApp = Nothing
|
||||
GC.Collect()
|
||||
GC.WaitForPendingFinalizers()
|
||||
End Try
|
||||
|
||||
Console.WriteLine("Verarbeite Datei: " & filePath)
|
||||
Next
|
||||
|
||||
Me.FindForm.SuspendLayout()
|
||||
POSITIONEN.setValues(EZA, True)
|
||||
btnPositionen.PerformClick()
|
||||
Me.FindForm.ResumeLayout()
|
||||
|
||||
MsgBox(cnt & " Datensätze wurden eingelesen.")
|
||||
Me.Cursor = Cursors.Default
|
||||
Return True
|
||||
End Function
|
||||
|
||||
' Liefert die 0-basierte Spaltennummer (DataTable-Index) anhand eines Header-Texts in rowIdx.
|
||||
' Gibt -1 zurück, wenn keine der gesuchten Varianten gefunden wird.
|
||||
Private Function FindHeaderColumn(ws As Excel.Worksheet, rowIdx As Integer, headerVariants As IEnumerable(Of String)) As Integer
|
||||
Dim maxScanCols As Integer = 35 ' etwas Puffer
|
||||
For c As Integer = 1 To maxScanCols
|
||||
Dim cell = ws.Cells(rowIdx, c).Value
|
||||
If cell Is Nothing Then Continue For
|
||||
Dim norm = cell.ToString().Trim().ToLower()
|
||||
For Each hv In headerVariants
|
||||
If norm.Contains(hv.ToLower()) Then
|
||||
Return c - 1 ' DataTable ist 0-basiert
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
Return -1
|
||||
End Function
|
||||
|
||||
Private Function ToDoubleSafe(obj As Object) As Double
|
||||
If obj Is Nothing Then Return 0
|
||||
Dim s As String = obj.ToString().Trim()
|
||||
If s = "" Then Return 0
|
||||
' Komma/Punkt robust behandeln, kulturinvariant parsen
|
||||
Dim d As Double
|
||||
' Erst alle Tausenderpunkte/Kommas vereinheitlichen
|
||||
s = s.Replace(" ", "")
|
||||
' Häufigster Fall: deutsches Komma
|
||||
If s.Contains(",") AndAlso Not s.Contains(".") Then
|
||||
s = s.Replace(".", "")
|
||||
s = s.Replace(",", ".")
|
||||
ElseIf s.Contains(".") AndAlso s.Contains(",") Then
|
||||
' Entferne Tausender-Trenner, behalte Dezimaltrennzeichen als Punkt
|
||||
s = s.Replace(".", "")
|
||||
s = s.Replace(",", ".")
|
||||
End If
|
||||
If Double.TryParse(s, Globalization.NumberStyles.Any, Globalization.CultureInfo.InvariantCulture, d) Then
|
||||
Return d
|
||||
End If
|
||||
Return 0
|
||||
End Function
|
||||
|
||||
' Prüft Kopfzeile in Zeile 17:
|
||||
' A17="Pos.", D17 beginnt mit "Warenbeschreibung",
|
||||
' P17 beginnt mit "Importcodenummer", R17 beginnt mit "Ursprungsland"
|
||||
Private Function checkExcelHeader_Fressnapf(ws As Excel.Worksheet) As Boolean
|
||||
Try
|
||||
Dim a = CStr(ws.Range("A17").Value)
|
||||
Dim d = CStr(ws.Range("D17").Value)
|
||||
If a Is Nothing OrElse d Is Nothing Then Return False
|
||||
Return a.Trim().ToLower() = "pos." AndAlso
|
||||
d.Trim().ToLower().StartsWith("warenbeschreibung")
|
||||
Catch
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
|
||||
End Class
|
||||
|
||||
|
||||
Reference in New Issue
Block a user