615 lines
28 KiB
VB.net
615 lines
28 KiB
VB.net
Imports ClosedXML.Excel
|
|
Imports System.Globalization
|
|
Imports System.IO
|
|
Imports System.Linq
|
|
|
|
Public Class cVERAG_CustomsDeclarations_Convert
|
|
|
|
Public Const EXPECTED_TEMPLATE_VERSION As String = "CBAM-2026-V1.0"
|
|
|
|
Public Shared Function LOAD_FROM_CBAM_DETAIL_EXCEL(filePath As String,
|
|
Optional ByRef errors As List(Of String) = Nothing,
|
|
Optional stopOnFirstInvalidRow As Boolean = False) As List(Of cVERAG_CustomsDeclarations)
|
|
|
|
Dim result As New List(Of cVERAG_CustomsDeclarations)
|
|
|
|
Try
|
|
If errors Is Nothing Then errors = New List(Of String)
|
|
|
|
If String.IsNullOrWhiteSpace(filePath) Then
|
|
errors.Add("Es wurde kein Dateipfad übergeben.")
|
|
Return result
|
|
End If
|
|
|
|
If Not File.Exists(filePath) Then
|
|
errors.Add("Datei nicht gefunden: " & filePath)
|
|
Return result
|
|
End If
|
|
|
|
Using wb As New XLWorkbook(filePath)
|
|
|
|
Dim ws As IXLWorksheet = Nothing
|
|
|
|
If wb.Worksheets.Any(Function(x) x.Name.Trim().ToUpper() = "CBAM_REPORT") Then
|
|
ws = wb.Worksheet("CBAM_Report")
|
|
Else
|
|
ws = wb.Worksheet(1)
|
|
End If
|
|
|
|
If ws Is Nothing Then
|
|
errors.Add("Kein Worksheet gefunden.")
|
|
Return result
|
|
End If
|
|
|
|
' =========================================================
|
|
' Template-Version prüfen
|
|
' =========================================================
|
|
Dim versionInFile As String = TrimSafe(ws.Cell("F3").GetString())
|
|
|
|
If Not String.Equals(versionInFile, EXPECTED_TEMPLATE_VERSION, StringComparison.OrdinalIgnoreCase) Then
|
|
errors.Add("Ungültige Template-Version in F3. Erwartet: '" & EXPECTED_TEMPLATE_VERSION & "', gefunden: '" & versionInFile & "'")
|
|
Return result
|
|
End If
|
|
|
|
Dim headerRow As Integer = 13
|
|
Dim dataStartRow As Integer = 14
|
|
|
|
Dim lastRow = If(ws.LastRowUsed() Is Nothing, 0, ws.LastRowUsed().RowNumber())
|
|
Dim lastCol = If(ws.LastColumnUsed() Is Nothing, 0, ws.LastColumnUsed().ColumnNumber())
|
|
|
|
If lastRow < dataStartRow OrElse lastCol = 0 Then
|
|
errors.Add("Keine Positionsdaten gefunden.")
|
|
Return result
|
|
End If
|
|
|
|
' =========================================================
|
|
' Header-Mapping aufbauen
|
|
' =========================================================
|
|
Dim colMap As New Dictionary(Of String, Integer)(StringComparer.OrdinalIgnoreCase)
|
|
|
|
For c As Integer = 1 To lastCol
|
|
Dim h = TrimSafe(ws.Cell(headerRow, c).GetString())
|
|
If h <> "" AndAlso Not colMap.ContainsKey(h) Then
|
|
colMap.Add(h, c)
|
|
End If
|
|
Next
|
|
|
|
' =========================================================
|
|
' Pflichtspalten im Excel prüfen
|
|
' =========================================================
|
|
Dim requiredHeaders = New String() {"MRN", "declaration_date", "tariff_code"}
|
|
|
|
For Each req In requiredHeaders
|
|
If Not colMap.ContainsKey(req) Then
|
|
errors.Add("Pflichtspalte im Excel nicht gefunden: " & req)
|
|
End If
|
|
Next
|
|
|
|
If errors.Any(Function(x) x.StartsWith("Pflichtspalte im Excel nicht gefunden:")) Then
|
|
Return result
|
|
End If
|
|
|
|
' =========================================================
|
|
' Bereits vorhandene / ungültige MRN verwalten
|
|
' =========================================================
|
|
Dim skippedExistingMrns As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
|
|
Dim invalidMrns As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
|
|
Dim dict As New Dictionary(Of String, cVERAG_CustomsDeclarations)(StringComparer.OrdinalIgnoreCase)
|
|
Dim artificialCounter As Integer = 0
|
|
|
|
For r As Integer = dataStartRow To lastRow
|
|
|
|
Dim mrn As String = GetCellString(ws, r, colMap, "MRN")
|
|
Dim referenceNo As String = GetCellString(ws, r, colMap, "reference_no")
|
|
Dim tariffCode As String = GetCellString(ws, r, colMap, "tariff_code")
|
|
Dim itemNoTxt As String = GetCellString(ws, r, colMap, "position_no")
|
|
|
|
' Komplette Leerzeile überspringen
|
|
If mrn = "" AndAlso referenceNo = "" AndAlso tariffCode = "" AndAlso itemNoTxt = "" Then
|
|
Continue For
|
|
End If
|
|
|
|
' =====================================================
|
|
' Zeilenvalidierung
|
|
' =====================================================
|
|
Dim validationMessage As String = ""
|
|
If Not ValidateImportRow(ws, r, colMap, validationMessage) Then
|
|
errors.Add(validationMessage)
|
|
|
|
If mrn <> "" Then
|
|
invalidMrns.Add(mrn)
|
|
End If
|
|
|
|
If stopOnFirstInvalidRow Then
|
|
Return result
|
|
End If
|
|
|
|
Continue For
|
|
End If
|
|
|
|
' Wenn MRN bereits als ungültig markiert wurde -> überspringen
|
|
If mrn <> "" AndAlso invalidMrns.Contains(mrn) Then
|
|
Continue For
|
|
End If
|
|
|
|
' =====================================================
|
|
' MRN bereits in DB?
|
|
' Dann komplette Anmeldung überspringen
|
|
' =====================================================
|
|
If mrn <> "" Then
|
|
If skippedExistingMrns.Contains(mrn) Then
|
|
Continue For
|
|
End If
|
|
|
|
If MRN_EXISTS_IN_DB(mrn) Then
|
|
skippedExistingMrns.Add(mrn)
|
|
errors.Add("MRN bereits vorhanden - Import übersprungen: " & mrn & " (Zeile " & r & ")")
|
|
Continue For
|
|
End If
|
|
End If
|
|
|
|
' =====================================================
|
|
' Gruppenschlüssel
|
|
' =====================================================
|
|
Dim grpKey As String = ""
|
|
If mrn <> "" Then
|
|
grpKey = "MRN|" & mrn
|
|
ElseIf referenceNo <> "" Then
|
|
grpKey = "REF|" & referenceNo
|
|
Else
|
|
artificialCounter += 1
|
|
grpKey = "AUTO|" & artificialCounter.ToString()
|
|
End If
|
|
|
|
Dim za As cVERAG_CustomsDeclarations = Nothing
|
|
|
|
If Not dict.ContainsKey(grpKey) Then
|
|
|
|
za = New cVERAG_CustomsDeclarations()
|
|
|
|
za.za_MRN = mrn
|
|
za.za_LRN = referenceNo
|
|
za.za_ReferenceCustomer = GetCellString(ws, r, colMap, "customer_reference")
|
|
za.za_RepresentationCode = GetCellString(ws, r, colMap, "representation_type")
|
|
za.za_DeclarationDate = GetCellDateNullable(ws, r, colMap, "declaration_date")
|
|
za.za_ReleaseDate = GetCellDateNullable(ws, r, colMap, "declaration_date")
|
|
|
|
za.za_CountryDispatch = GetCellString(ws, r, colMap, "dispatch_country")
|
|
za.za_CountryDestination = GetCellString(ws, r, colMap, "destination_country")
|
|
za.za_CountryImport = GetCellString(ws, r, colMap, "destination_country")
|
|
|
|
za.za_MainProcedure = GetCellString(ws, r, colMap, "requested_procedure")
|
|
za.za_InvoiceCurrency = GetCellString(ws, r, colMap, "invoice_currency")
|
|
za.za_InvoiceAmount = GetCellDecimalNullable(ws, r, colMap, "invoice_amount")
|
|
za.za_IsFinalDeclaration = True
|
|
za.za_REGIME = "IMPORT"
|
|
|
|
za.za_System = "CBAM_EXCEL_IMPORT"
|
|
za.za_CustomsSystem = ""
|
|
za.za_CustomsSystemCountry = ""
|
|
za.za_IsExternalSystem = True
|
|
za.za_Firma = ""
|
|
za.za_Niederlassung = ""
|
|
za.za_AdditionalProcedure = ""
|
|
za.za_WarehouseCode = ""
|
|
za.za_Incoterms = ""
|
|
za.za_IncotermsPlace = ""
|
|
za.za_TotGrossMass = Nothing
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="EXPORTER",
|
|
eori:=GetCellString(ws, r, colMap, "sender_eori"),
|
|
name:=GetCellString(ws, r, colMap, "sender_name"),
|
|
street:=GetCellString(ws, r, colMap, "sender_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "sender_country"),
|
|
email:="",
|
|
phone:=""
|
|
))
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="CONSIGNEE",
|
|
eori:=GetCellString(ws, r, colMap, "recipient_eori"),
|
|
name:=GetCellString(ws, r, colMap, "recipient_name"),
|
|
street:=GetCellString(ws, r, colMap, "recipient_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "recipient_country"),
|
|
email:="",
|
|
phone:=""
|
|
))
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="IMPORTER",
|
|
eori:=GetCellString(ws, r, colMap, "importer_eori"),
|
|
name:=GetCellString(ws, r, colMap, "importer_name"),
|
|
street:=GetCellString(ws, r, colMap, "importer_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "importer_country"),
|
|
email:=GetCellString(ws, r, colMap, "importer_email"),
|
|
phone:=GetCellString(ws, r, colMap, "importer_phone")
|
|
))
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="DECLARANT",
|
|
eori:=GetCellString(ws, r, colMap, "declarant_eori"),
|
|
name:=GetCellString(ws, r, colMap, "declarant_name"),
|
|
street:=GetCellString(ws, r, colMap, "declarant_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "declarant_country"),
|
|
email:="",
|
|
phone:=""
|
|
))
|
|
|
|
Dim invNo = GetCellString(ws, r, colMap, "invoice_number")
|
|
Dim invDate = GetCellString(ws, r, colMap, "invoice_date")
|
|
|
|
If invNo <> "" OrElse invDate <> "" Then
|
|
za.Documents.Add(New cVERAG_CustomsDeclarations_Document With {
|
|
.zaDoc_Code = "N380",
|
|
.zaDoc_Reference = invNo,
|
|
.zaDoc_Date = invDate,
|
|
.zaDoc_Description = "Invoice"
|
|
})
|
|
End If
|
|
|
|
dict.Add(grpKey, za)
|
|
|
|
Else
|
|
za = dict(grpKey)
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="EXPORTER",
|
|
eori:=GetCellString(ws, r, colMap, "sender_eori"),
|
|
name:=GetCellString(ws, r, colMap, "sender_name"),
|
|
street:=GetCellString(ws, r, colMap, "sender_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "sender_country"),
|
|
email:="",
|
|
phone:=""
|
|
))
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="CONSIGNEE",
|
|
eori:=GetCellString(ws, r, colMap, "recipient_eori"),
|
|
name:=GetCellString(ws, r, colMap, "recipient_name"),
|
|
street:=GetCellString(ws, r, colMap, "recipient_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "recipient_country"),
|
|
email:="",
|
|
phone:=""
|
|
))
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="IMPORTER",
|
|
eori:=GetCellString(ws, r, colMap, "importer_eori"),
|
|
name:=GetCellString(ws, r, colMap, "importer_name"),
|
|
street:=GetCellString(ws, r, colMap, "importer_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "importer_country"),
|
|
email:=GetCellString(ws, r, colMap, "importer_email"),
|
|
phone:=GetCellString(ws, r, colMap, "importer_phone")
|
|
))
|
|
|
|
AddOrMergeParty(za.Parties, CreateParty(
|
|
role:="DECLARANT",
|
|
eori:=GetCellString(ws, r, colMap, "declarant_eori"),
|
|
name:=GetCellString(ws, r, colMap, "declarant_name"),
|
|
street:=GetCellString(ws, r, colMap, "declarant_address"),
|
|
postalCode:="",
|
|
city:="",
|
|
country:=GetCellString(ws, r, colMap, "declarant_country"),
|
|
email:="",
|
|
phone:=""
|
|
))
|
|
End If
|
|
|
|
Dim it As New cVERAG_CustomsDeclarations_Item()
|
|
|
|
it.zaItem_PosNo = GetCellInt(ws, r, colMap, "position_no", za.Items.Count + 1)
|
|
it.zaItem_HSCode = GetCellString(ws, r, colMap, "tariff_code")
|
|
it.zaItem_OriginCountry = GetCellString(ws, r, colMap, "origin_country")
|
|
it.zaItem_GrossMass = GetCellDecimalNullable(ws, r, colMap, "gross_mass_kg")
|
|
it.zaItem_NetMass = GetCellDecimalNullable(ws, r, colMap, "net_mass_kg")
|
|
it.zaItem_SuppUnitCode = GetCellString(ws, r, colMap, "measurement_unit")
|
|
it.zaItem_PrevProcedure = GetCellString(ws, r, colMap, "previous_procedure")
|
|
it.zaItem_MainProcedure = GetCellString(ws, r, colMap, "requested_procedure")
|
|
it.zaItem_InvoiceValueEUR = GetCellDecimalNullable(ws, r, colMap, "invoice_amount")
|
|
it.zaItem_InvoiceCurrency = GetCellString(ws, r, colMap, "invoice_currency")
|
|
it.zaItem_StatisticalValueEUR = GetCellDecimalNullable(ws, r, colMap, "invoice_amount")
|
|
|
|
Dim remarks As String = ""
|
|
Dim bench = GetCellString(ws, r, colMap, "Benchmark (Default)")
|
|
Dim emi = GetCellString(ws, r, colMap, "Emission (Default)")
|
|
Dim fac = GetCellString(ws, r, colMap, "Factor")
|
|
Dim est = GetCellString(ws, r, colMap, "Estimated Cost")
|
|
|
|
If bench <> "" OrElse emi <> "" OrElse fac <> "" OrElse est <> "" Then
|
|
remarks =
|
|
"CBAM Import | " &
|
|
"Benchmark=" & bench & "; " &
|
|
"Emission=" & emi & "; " &
|
|
"Factor=" & fac & "; " &
|
|
"EstimatedCost=" & est
|
|
End If
|
|
|
|
it.zaItem_Remarks = remarks
|
|
|
|
Dim itemInvNo = GetCellString(ws, r, colMap, "invoice_number")
|
|
Dim itemInvDate = GetCellString(ws, r, colMap, "invoice_date")
|
|
|
|
If itemInvNo <> "" OrElse itemInvDate <> "" Then
|
|
it.Documents.Add(New cVERAG_CustomsDeclarations_Document With {
|
|
.zaDoc_Code = "N380",
|
|
.zaDoc_Reference = itemInvNo,
|
|
.zaDoc_Date = itemInvDate,
|
|
.zaDoc_Description = "Invoice"
|
|
})
|
|
End If
|
|
|
|
za.Items.Add(it)
|
|
|
|
Next
|
|
|
|
For Each za In dict.Values
|
|
If za.Items IsNot Nothing AndAlso za.Items.Count > 0 Then
|
|
za.za_TotGrossMass = za.Items.Sum(Function(x) If(x.zaItem_GrossMass, 0D))
|
|
|
|
If Not za.za_InvoiceAmount.HasValue Then
|
|
Dim invSum = za.Items.Sum(Function(x) If(x.zaItem_InvoiceValueEUR, 0D))
|
|
If invSum <> 0D Then
|
|
za.za_InvoiceAmount = invSum
|
|
End If
|
|
End If
|
|
|
|
result.Add(za)
|
|
End If
|
|
Next
|
|
|
|
End Using
|
|
|
|
Catch ex As Exception
|
|
VERAG_PROG_ALLGEMEIN.cErrorHandler.ERR(ex.Message, ex.StackTrace, Reflection.MethodInfo.GetCurrentMethod.Name)
|
|
End Try
|
|
|
|
Return result
|
|
|
|
End Function
|
|
|
|
Private Shared Function ValidateImportRow(ws As IXLWorksheet,
|
|
row As Integer,
|
|
colMap As Dictionary(Of String, Integer),
|
|
ByRef validationMessage As String) As Boolean
|
|
|
|
validationMessage = ""
|
|
|
|
Dim mrn As String = GetCellString(ws, row, colMap, "MRN")
|
|
Dim tariffCode As String = GetCellString(ws, row, colMap, "tariff_code")
|
|
Dim declarationDate As Date? = GetCellDateNullable(ws, row, colMap, "declaration_date")
|
|
|
|
Dim missing As New List(Of String)
|
|
|
|
If mrn = "" Then missing.Add("MRN")
|
|
If Not declarationDate.HasValue Then missing.Add("declaration_date")
|
|
If tariffCode = "" Then missing.Add("tariff_code")
|
|
|
|
If missing.Count > 0 Then
|
|
validationMessage = "Zeile " & row & " ungültig. Pflichtfeld(er) fehlen oder sind ungültig: " & String.Join(", ", missing)
|
|
Return False
|
|
End If
|
|
|
|
Return True
|
|
|
|
End Function
|
|
|
|
Private Shared Function MRN_EXISTS_IN_DB(mrn As String) As Boolean
|
|
|
|
Try
|
|
mrn = TrimSafe(mrn)
|
|
If mrn = "" Then Return False
|
|
|
|
Dim za = cVERAG_CustomsDeclarations.loadByMRN(mrn, False)
|
|
Return za IsNot Nothing AndAlso za.hasEntry
|
|
|
|
Catch ex As Exception
|
|
VERAG_PROG_ALLGEMEIN.cErrorHandler.ERR(ex.Message, ex.StackTrace, Reflection.MethodInfo.GetCurrentMethod.Name)
|
|
End Try
|
|
|
|
Return False
|
|
|
|
End Function
|
|
|
|
Private Shared Function CreateParty(role As String,
|
|
eori As String,
|
|
name As String,
|
|
street As String,
|
|
postalCode As String,
|
|
city As String,
|
|
country As String,
|
|
email As String,
|
|
phone As String) As cVERAG_CustomsDeclarations_Parties
|
|
|
|
If TrimSafe(eori) = "" AndAlso
|
|
TrimSafe(name) = "" AndAlso
|
|
TrimSafe(street) = "" AndAlso
|
|
TrimSafe(country) = "" AndAlso
|
|
TrimSafe(email) = "" AndAlso
|
|
TrimSafe(phone) = "" Then
|
|
Return Nothing
|
|
End If
|
|
|
|
Return New cVERAG_CustomsDeclarations_Parties With {
|
|
.zaParty_Role = role,
|
|
.zaParty_EORI = TrimSafe(eori),
|
|
.zaParty_Name = TrimSafe(name),
|
|
.zaParty_Street = TrimSafe(street),
|
|
.zaParty_PostalCode = TrimSafe(postalCode),
|
|
.zaParty_City = TrimSafe(city),
|
|
.zaParty_Country = TrimSafe(country),
|
|
.zaParty_Email = TrimSafe(email),
|
|
.zaParty_Phone = TrimSafe(phone)
|
|
}
|
|
|
|
End Function
|
|
|
|
Private Shared Sub AddOrMergeParty(list As List(Of cVERAG_CustomsDeclarations_Parties),
|
|
p As cVERAG_CustomsDeclarations_Parties)
|
|
|
|
If p Is Nothing Then Exit Sub
|
|
If list Is Nothing Then Exit Sub
|
|
|
|
Dim existing = list.FirstOrDefault(Function(x)
|
|
Return String.Equals(TrimSafe(x.zaParty_Role), TrimSafe(p.zaParty_Role), StringComparison.OrdinalIgnoreCase) AndAlso
|
|
String.Equals(TrimSafe(x.zaParty_EORI), TrimSafe(p.zaParty_EORI), StringComparison.OrdinalIgnoreCase) AndAlso
|
|
String.Equals(TrimSafe(x.zaParty_Name), TrimSafe(p.zaParty_Name), StringComparison.OrdinalIgnoreCase)
|
|
End Function)
|
|
|
|
If existing Is Nothing Then
|
|
list.Add(p)
|
|
Else
|
|
If TrimSafe(existing.zaParty_Street) = "" Then existing.zaParty_Street = p.zaParty_Street
|
|
If TrimSafe(existing.zaParty_PostalCode) = "" Then existing.zaParty_PostalCode = p.zaParty_PostalCode
|
|
If TrimSafe(existing.zaParty_City) = "" Then existing.zaParty_City = p.zaParty_City
|
|
If TrimSafe(existing.zaParty_Country) = "" Then existing.zaParty_Country = p.zaParty_Country
|
|
If TrimSafe(existing.zaParty_Email) = "" Then existing.zaParty_Email = p.zaParty_Email
|
|
If TrimSafe(existing.zaParty_Phone) = "" Then existing.zaParty_Phone = p.zaParty_Phone
|
|
End If
|
|
|
|
End Sub
|
|
|
|
Private Shared Function GetCellString(ws As IXLWorksheet,
|
|
row As Integer,
|
|
colMap As Dictionary(Of String, Integer),
|
|
header As String) As String
|
|
|
|
Try
|
|
If ws Is Nothing OrElse colMap Is Nothing Then Return ""
|
|
If Not colMap.ContainsKey(header) Then Return ""
|
|
Return TrimSafe(ws.Cell(row, colMap(header)).GetString())
|
|
Catch
|
|
Return ""
|
|
End Try
|
|
|
|
End Function
|
|
|
|
Private Shared Function GetCellDecimalNullable(ws As IXLWorksheet,
|
|
row As Integer,
|
|
colMap As Dictionary(Of String, Integer),
|
|
header As String) As Decimal?
|
|
|
|
Try
|
|
If ws Is Nothing OrElse colMap Is Nothing Then Return Nothing
|
|
If Not colMap.ContainsKey(header) Then Return Nothing
|
|
|
|
Dim cell = ws.Cell(row, colMap(header))
|
|
If cell Is Nothing OrElse cell.IsEmpty() Then Return Nothing
|
|
|
|
If cell.DataType = XLDataType.Number Then
|
|
Return Convert.ToDecimal(cell.GetDouble())
|
|
End If
|
|
|
|
Dim txt = TrimSafe(cell.GetString())
|
|
If txt = "" Then Return Nothing
|
|
|
|
Dim d As Decimal
|
|
txt = txt.Replace(" ", "")
|
|
|
|
If Decimal.TryParse(txt, NumberStyles.Any, CultureInfo.InvariantCulture, d) Then Return d
|
|
If Decimal.TryParse(txt, NumberStyles.Any, CultureInfo.GetCultureInfo("de-AT"), d) Then Return d
|
|
If Decimal.TryParse(txt, NumberStyles.Any, CultureInfo.GetCultureInfo("de-DE"), d) Then Return d
|
|
|
|
Catch
|
|
End Try
|
|
|
|
Return Nothing
|
|
|
|
End Function
|
|
|
|
Private Shared Function GetCellDateNullable(ws As IXLWorksheet,
|
|
row As Integer,
|
|
colMap As Dictionary(Of String, Integer),
|
|
header As String) As Date?
|
|
|
|
Try
|
|
If ws Is Nothing OrElse colMap Is Nothing Then Return Nothing
|
|
If Not colMap.ContainsKey(header) Then Return Nothing
|
|
|
|
Dim cell = ws.Cell(row, colMap(header))
|
|
If cell Is Nothing OrElse cell.IsEmpty() Then Return Nothing
|
|
|
|
If cell.DataType = XLDataType.DateTime Then
|
|
Return cell.GetDateTime()
|
|
End If
|
|
|
|
If cell.DataType = XLDataType.Number Then
|
|
Return DateTime.FromOADate(cell.GetDouble())
|
|
End If
|
|
|
|
Dim txt = TrimSafe(cell.GetString())
|
|
If txt = "" Then Return Nothing
|
|
|
|
Dim dt As DateTime
|
|
If DateTime.TryParse(txt, CultureInfo.InvariantCulture, DateTimeStyles.None, dt) Then Return dt
|
|
If DateTime.TryParse(txt, CultureInfo.GetCultureInfo("de-AT"), DateTimeStyles.None, dt) Then Return dt
|
|
If DateTime.TryParse(txt, CultureInfo.GetCultureInfo("de-DE"), DateTimeStyles.None, dt) Then Return dt
|
|
|
|
Catch
|
|
End Try
|
|
|
|
Return Nothing
|
|
|
|
End Function
|
|
|
|
Private Shared Function GetCellInt(ws As IXLWorksheet,
|
|
row As Integer,
|
|
colMap As Dictionary(Of String, Integer),
|
|
header As String,
|
|
Optional defaultValue As Integer = 0) As Integer
|
|
|
|
Try
|
|
If ws Is Nothing OrElse colMap Is Nothing Then Return defaultValue
|
|
If Not colMap.ContainsKey(header) Then Return defaultValue
|
|
|
|
Dim cell = ws.Cell(row, colMap(header))
|
|
If cell Is Nothing OrElse cell.IsEmpty() Then Return defaultValue
|
|
|
|
If cell.DataType = XLDataType.Number Then
|
|
Return Convert.ToInt32(Math.Truncate(cell.GetDouble()))
|
|
End If
|
|
|
|
Dim txt = TrimSafe(cell.GetString())
|
|
If txt = "" Then Return defaultValue
|
|
|
|
Dim i As Integer
|
|
If Integer.TryParse(txt, i) Then Return i
|
|
|
|
Dim d As Decimal
|
|
If Decimal.TryParse(txt, NumberStyles.Any, CultureInfo.InvariantCulture, d) Then
|
|
Return Convert.ToInt32(Math.Truncate(d))
|
|
End If
|
|
If Decimal.TryParse(txt, NumberStyles.Any, CultureInfo.GetCultureInfo("de-AT"), d) Then
|
|
Return Convert.ToInt32(Math.Truncate(d))
|
|
End If
|
|
If Decimal.TryParse(txt, NumberStyles.Any, CultureInfo.GetCultureInfo("de-DE"), d) Then
|
|
Return Convert.ToInt32(Math.Truncate(d))
|
|
End If
|
|
|
|
Catch
|
|
End Try
|
|
|
|
Return defaultValue
|
|
|
|
End Function
|
|
|
|
Private Shared Function TrimSafe(value As Object) As String
|
|
If value Is Nothing Then Return ""
|
|
Return Convert.ToString(value).Trim()
|
|
End Function
|
|
|
|
End Class |