Gültigkeit der VAT-Number (UID-Nummer) mit .NET Standard-Funktionen abfragen (ohne separate komponenten)

    • .NET (FX) 4.5–4.8
    • VB.NET

    Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von slice.

      Gültigkeit der VAT-Number (UID-Nummer) mit .NET Standard-Funktionen abfragen (ohne separate komponenten)

      Hallo Leute,

      lange habe ich nach einer einfachen und funktionierenden Möglichkeit gesucht eine UID-Nummer auf ihre Gültigkeit zu prüfen. Im Netz schwirren viele verschiedene Codefragmente herum die entweder nicht funktionieren oder eine kostenpflichtige Komponente benötigen. Ich bin zwar nicht der Spitzen-Profi-Programmierer, aber ich habe es auch mit .NET Funktionen relativ einfach und funktionierend hinbekommen.

      Da ich diesem Forum viel von meinem Wissen über .NET verdanke, möchte ich auch etwas zurückgeben. Daher hier der Code:

      Aufgerufen wird das Modul ganz einfach mit (z.B. meine UID):

      VB.NET-Quellcode

      1. UeberpruefeUID ("ATU65033000")


      In meinem Beispiel werden die Ergebnisse in den Public-Variablen gespeichert und sind somit in der ganzen Anwendung verfügbar.

      VB.NET-Quellcode

      1. Imports System.Net
      2. Imports System.Xml
      3. Imports System.IO
      4. Module mdl_vatchecker
      5. Public UID_Valid As Boolean = False 'geprüfte UID-Nummer gültig oder nicht
      6. Public UID_Number As String = "" 'Komplette UID-Nummer mit Ländercode (z.B. ATU1234567 oder DE123344556)
      7. Public UID_NumberWhithoutCC As String = "" 'UID-Nummer ohne CountryCode
      8. Public UID_CountryCode As String = "" 'Ländercode (AT, DE, IT, ...)
      9. Public UID_Name As String = "" 'Unternehmensname
      10. Public UID_Address As String = "" 'Unternehmensadresse (nur wenn am EU-Server verfügbar)
      11. Public UID_requestDate As String = "" 'Abfragezeitpunkt
      12. Public UID_Error As String = "" 'Fehlermeldung
      13. Public Sub UeberpruefeUID(CompleteVAT As String)
      14. 'Globale Variablen leeren
      15. UID_Valid = False
      16. UID_Number = ""
      17. UID_NumberWhithoutCC = ""
      18. UID_CountryCode = ""
      19. UID_Name = ""
      20. UID_Address = ""
      21. UID_requestDate = ""
      22. UID_Error = ""
      23. CompleteVAT = CompleteVAT.Replace(" ", "") 'alle Leerzeichen entfernen falls andere Schreibweisen wie z.B. "AT U12345678" oder "DE 123 456 789" übergeben werden
      24. If CompleteVAT.Length < 8 Then
      25. UID_Error = "UID-Nummer ist zu kurz"
      26. UID_Valid = False
      27. Exit Sub
      28. End If
      29. UID_Number = CompleteVAT
      30. 'Hier Countrycode und VatNumber trennen
      31. UID_CountryCode = Left(CompleteVAT, 2)
      32. UID_NumberWhithoutCC = Right(CompleteVAT, CompleteVAT.Length - 2)
      33. Dim client As WebClient = New WebClient()
      34. client.Encoding = System.Text.Encoding.UTF8
      35. Dim request As String = "<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:urn=""urn:ec.europa.eu:taxud:vies:services:checkVat:types"">"
      36. request += "<soapenv:Header/>"
      37. request += "<soapenv:Body>"
      38. request += "<urn:checkVat>"
      39. request += "<urn:countryCode>" + UID_CountryCode + "</urn:countryCode>"
      40. request += "<urn:vatNumber>" + UID_NumberWhithoutCC + "</urn:vatNumber>"
      41. request += "</urn:checkVat>"
      42. request += "</soapenv:Body>"
      43. request += "</soapenv:Envelope>"
      44. Dim response As String = ""
      45. Try
      46. response = client.UploadString("http://ec.europa.eu/taxation_customs/vies/services/checkVatService", request)
      47. client.Dispose()
      48. Catch
      49. client.Dispose()
      50. UID_Error = "Fehler beim Verbindungsaufbau zu ec.europa.eu"
      51. Exit Sub
      52. End Try
      53. If response.Contains("<valid>true</valid>") Then
      54. UID_Valid = True
      55. Dim XSettings As New XmlReaderSettings
      56. 'Unternehmensnamen auslesen
      57. Using SReader As New StringReader(response)
      58. Dim X As XmlReader = XmlReader.Create(SReader, XSettings)
      59. X.ReadToDescendant("name")
      60. UID_Name = X.ReadElementContentAsString
      61. End Using
      62. 'Unternehmensadresse auslesen wenn verfügbar (Abfragestufe 2)
      63. Using SReader As New StringReader(response)
      64. Dim X As XmlReader = XmlReader.Create(SReader, XSettings)
      65. X.ReadToDescendant("address")
      66. UID_Address = X.ReadElementContentAsString
      67. End Using
      68. 'Abfragezeitpunkt des EU-Servers (Serverzeit)
      69. Using SReader As New StringReader(response)
      70. Dim X As XmlReader = XmlReader.Create(SReader, XSettings)
      71. X.ReadToDescendant("requestDate")
      72. UID_requestDate = X.ReadElementContentAsString
      73. End Using
      74. Else
      75. UID_Valid = False
      76. End If
      77. End Sub
      78. End Module


      *Topic verschoben*
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

      @dive26 Wenn Du aus der Sub eine Boolean Function machst, bekommst Du das Resultat sofort mit dem Aufruf.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Einen Namen und eine Adresse, sowie ein Abfragedatum kann man nicht mit einem einzigen Boolean Rückgabewert einer Funktion abbilden ;)

      Vollzitat entfernt. ~Thunderbolt
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Thunderbolt“ ()

      Ich finde es wäre nötig, dass man das ganze auf VB.Net funktionen updated, du verwendest noch einige alte VB6 funktionen hast den Thread aber unter .Net eingeordnet. Zeile 69-87 liese sich bestimmt auch in einem durchgang machen, was das ganze logischer kombiniert und natürlich auch performanter...
      Ich wollte auch mal ne total überflüssige Signatur:
      ---Leer---
      @dive26 aber warum so kompliziert.

      Es gibt ein Webservice. Einbinden und fertig. Die Proxyklassen werden automatisch generiert und dann ist die Abfrage nur noch Formsache.
      ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

      VB.NET-Quellcode

      1. Public Class VatChecker
      2. Private serv As VatCheckService.checkVatService
      3. Public Sub New()
      4. serv = New VatCheckService.checkVatService
      5. End Sub
      6. Public Function IsTaxCodeValid(taxcode As String) As VatInfo
      7. Dim ret As New VatInfo
      8. ret.TaxNumber = taxcode
      9. Dim test = serv.checkVat(taxcode.Substring(0, 2), taxcode.Substring(2), ret.IsValid, ret.CompanyName, ret.CompanyAddress)
      10. Return ret
      11. End Function
      12. End Class
      13. Public Class VatInfo
      14. Public Property IsValid As Boolean
      15. Public Property CompanyName As String
      16. Public Property CompanyAddress As String
      17. Public Property TaxNumber As String
      18. End Class


      Das schöne ist, du bekomst auch gleich den Firmennamen und die Adresse zurück. Wenn also ein Geschäftspartner neu angelegt wird kann man mit eingabe der UID gleich die Daten ausfüllen lassen und der Enduser spart sich das gleich mal. Feine Sache wie ich finde.

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      Dksksm schrieb:

      Gehört das nicht in Tipps & Tricks?
      Um möglichst schnell mehrere tausend Datensätze zu prüfen (bei mir id.R. > 20 TSD bis < 500 TSD) habe ich mir eine eigene Klasse geschrieben.
      Dazu habe ich die Informationen des Bundeszentralamt für Steuern genutzt.


      Zwischen "Prüfen ob das Nummernformat stimmt" und "Prüfen ob die UID-Nummer generell aktiv und dem Geschäftspartner zugeordnet ist" liegen Welten.
      Das Prüfen des Nummernformates erspare ich mir, da mir der EU-Server ohnehin sagt ob die Nummer passt oder nicht.

      Nich selten kommt es vor, dass jemand bei uns im Onlineshop bestellt und eine UID-Nummer wegen steuerfreiem i.G. Einkauf hinterlässt.
      Da muss man dann laut Finanz prüfen ob die UID-Nummer auch zu diesem Unternehmer passt (und nicht die vom letzen Aldi-Kassenzettel verwendet wurde).


      @Nofear23m
      Dein Code sieht schon aufgeräumter aus als meiner.
      Wo bekomme ich dieses Webservice (kostenfrei und lizenztechnisch sauber und ehrlich) her und wie binde ich es (kompliziert oder nicht kompliziert) ein?
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „dive26“ ()

      Hallo

      einfach in VS einen Webverweis hinzufügen und die URI angeben. Alles weitere macht dir VS.
      Den Namen des Service kannst dabei frei wählen. Wählst du selben wie ich kannst du meinen Code Par C&P verwenden.

      Wie man ein Webservice einbindet findest du hier: msdn.microsoft.com/en-us/library/bb628649.aspx

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      @Nofear23m

      Habe ich noch nie gemacht, daher weiß ich nicht was ich falsch mache (siehe Screenshot).
      Bei mir ist ".checkVatService" nicht in der Auflistung.
      Bilder
      • 27092018160606.jpg

        175,72 kB, 942×340, 148 mal angesehen
      • 27092018161034.jpg

        100,68 kB, 817×283, 101 mal angesehen
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
      Sehe ich ja nicht. S kommt nach R ..... ;(
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      kommt nur noch das:
      Bilder
      • 27092018162057.jpg

        44,1 kB, 262×191, 1.389 mal angesehen
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
      Hallo

      In den app.config müsste auch ein Knoten erstelt worden sein. Kannst du den mal zeigen?

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      @Nofear23m

      VB.NET-Quellcode

      1. <system.serviceModel>
      2. <bindings>
      3. <basicHttpBinding>
      4. <binding name="checkVatBinding" />
      5. </basicHttpBinding>
      6. </bindings>
      7. <client>
      8. <endpoint address="http://ec.europa.eu/taxation_customs/vies/services/checkVatService"
      9. binding="basicHttpBinding" bindingConfiguration="checkVatBinding"
      10. contract="VATService.checkVatPortType" name="checkVatPort" />
      11. </client>
      12. </system.serviceModel>
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
      Ne, das wurde falsch eingebunden.

      Ich kann dir Screenshots machen wenn ich daheim bis.

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      @Nofear23m
      Danke für Deine Mühe.

      Mir ist das ehrlich gesagt zu zeitaufwändig und zu kompliziert. Habe jetzt einen halben Tag vergebens damit verbracht, für eine bereits funktionierende Routine eine Alternative mit "Webservice" zu erstellen weil jemand sagt es wäre besser oder einfacher. Ein halber Tag an dem ich schon wieder was anderes programmieren hätte können. Da mein aktueller Code funktioniert, bleibt der auch jetzt mal drin.

      Da ich aber gerne wissen möchte ob und was ich beim Webservice falsch gemacht habe, würde ich mich freuen, wenn Du die Screenshots postest wie Du geschrieben hast.

      jvbsl schrieb:

      Zeile 69-87 liese sich bestimmt auch in einem durchgang machen, was das ganze logischer kombiniert und natürlich auch performanter...


      Dachte ich zuerst auch, brachte aber einen Fehler als ich alles in den USING Container stellte, daher habe ich es dann so gemacht. "Performanter" ja, aber die 3 ms mehr merkt der User nicht ;)

      Beiträge zusammengefügt. ~Thunderbolt
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

      dive26 schrieb:

      Mir ist das ehrlich gesagt zu zeitaufwändig und zu kompliziert. Habe jetzt einen halben Tag vergebens damit verbracht, für eine bereits funktionierende Routine eine Alternative mit "Webservice" zu erstellen weil jemand sagt es wäre besser oder einfacher.
      Jo - da höre ich eine gewisse Lern-Unwilligkeit heraus.
      Das sieht man deim Code auch an, was auch jvbsl anmerkt - die vb6-Relikte etc., oder dass du da mittm XmlReader rumhampelst - vmtl. ist dir XmlDocument ebenfalls unbekannt, und vieles annere auch.

      Das ist ein bischen ein Trugschluss, wenn man denkt, Zeit sparen zu können, indem man sich selbst nicht weiter-entwickelt.
      Heraus kommen da äusserst schlecht wartbare Codes, und an dem Punkt - Wartung bestehender Codes - wird oft die "eingesparte" Zeit vielfach denn doch verbraten.

      Insbesondere würde ich dir Visual Studio - Empfohlene Einstellungen
      Das wäre schoma ein ziemlich gewaltiger Schritt in Richtung OOP-Verständnis.
      Ich dachte ich stell mal einen Code rein (der ja so auch funktioniert und macht was er soll). Statt "Danke" höre ich nur Kritik - immer von den selben Leuten (außer @Nofear23m der mir wirklich aktiv helfen wollte). Ich bin wirklich enttäuscht. Klar kann man es immer noch besser machen. Aber dann postet doch einfach den besseren Code hier rein, anstatt immer nur Bruchstücke oder vage Hinweise zu streuen und dann zu kritisieren, dass derjenige diese Hinweise nicht versteht.

      Ich habe diesen (funktionierenden) Code hier eingestellt, weil es zwar viele LösungsANSÄTZE im Web dafür gibt aber nirgends ein wirklich funktionierendes Codeschnippsel für VB.NET.

      @ErfinderDesRades
      Ich bin immer bereits etwas neues zu lernen. Aber ich bin auch Unternehmer und verantwortlich für 3 Leute und deren Einkommen. Da geht man dann den einfachen Weg. Da ist die Entscheidung zwischen a und b einfach:
      a) verwende ich das was ich geschrieben habe, ich verstehe und das funktioniert (egal ob es nun ein Bilderbuch-Quellcode ist oder nicht)
      b) versuche ich krampfhaft das zu Programmieren was mir andere als "die" Lösung weiß machen, ich aber nicht die blassesten Schimmer von dieser Alternativlösung habe und dann einen Tag damit herumprobiere und unterm Strich dann ich dann erst nichts brauchbares hinbekomme.


      Ich bin eben kein Hauptberuflicher studierte Programmierer der den ganzen Tag nur programmiert. Ich habe ursprünglich Koch- und Kellner gelernt und mir alles bisher selbst beigebracht. Daher ist mein Code eben kein "Bilderbuch-Code". Ich habe 10 Jahre mit VB6 programmiert und bin 2014 auf VB.NET umgestiegen. Klar ist da noch viel VB6 Code im Hinterkopf festgefressen. Aber wenn Microsoft so manche VB6-Funktionen in VB.NET integriert hat, warum dann nicht auch verwenden wenn diese den Zweck erfüllen. Bricht sich ja niemand einen Stein aus der Krone.

      Wenn ich auf meine Firmenlaufbahn zurückblicke, dann kann ich die Sache mit der Programmierung nicht ganz so verkehrt gemacht haben - da über 5000 Lizenznehmer (allesamt Unternehmer) mit meinen bisher 6 verschiedenen VB6 und VB.NET Programmen seit 2005 erfolgreich arbeiten. ;)

      Fazit: Das mit dem Webservice werde ich mir nach Abschluss des Projekts nochmals näher ansehen - möchte ja etwas dazulernen.


      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „dive26“ ()

      @dive26 Ich kann dir mit ruhigen Gewissen sagen, das selbst meine Leute die kurz vor ihren Bachelor-Abschluss in Informatik stehen nicht so richtig programmieren können. :D Es ist halt alles mehr theoretisch statt praktisch, obwohl ich an der Hochschule schon mehr Praktika habe, aber manche einfach nicht lernwillig sind.
      Das alles ist eine Frage des Interesses und Ehrgeizes. Manche wollen und können und andere wiederum verstehen es einfach nicht, weil die Motivation fehlt.
      Also bleib einfach am Ball und versuch nicht immer mit dem Kopf durch die Wand und viel in kurzer Zeit schaffen zu wollen, was ich natürlich auch hin und wieder mache und ich auch nachvollziehen kann, weil es nun mal um Geld geht, sondern die Kunst liegt darin sich am Anfang genug Gedanken zu machen um es langfristig richtig bzw. richtiger zu machen. :) :thumbsup:
      Wie @ErfinderDesRades bereits sagte muss man auch längerfristig an die Wartbarkeit denken und so viel Zeit das bisschen umzuschreiben kostet es auch nicht. Immerhin gibt es viele gescheite Leute die dir hier gerne helfen. ^^

      dive26 schrieb:

      Ich dachte ich stell mal einen Code rein (der ja so auch funktioniert und macht was er soll). Statt "Danke" höre ich nur Kritik
      Dann ist das wohl ein Missverständnis.
      Ich verstehe jeden Code, den man hier einstellt als Einladung, VerbesserungsVorschläge einzubringen - in anneren Worts: zu kritisieren.

      Kränken will ich niemals niemanden. Ich will neugierig machen auf unbekannte Möglichkeiten. Aber da muss man sich halt drauf einlassen.
      Sorry, dassich mich nicht bedanke für den Code, aber ich persönlich benötige keine VAT-Validierung.

      Wofür der Code aber wirklich ein nützlicher Anstoss sein könnte: Wie wärs, wenn NoFear ein klein Video-Tut einstellen täte, wie man eine Web-API konsumiert?
      (Ich könnte sowas auch selbst, aber bin total ausser Übung mit VideoTuts)
      Das fände ich ein unerhört wertvolles und wichtiges Tutorial auf VBParadise, weil dazu gibts bislang nix.
      Da tät ich mich denn bei NoFear bedanken, und natürlich auch bei dir als Anstoss-Geber.
      Hallo in die Runde und Hallo @ErfinderDesRades

      Sorry für die späte Meldung, hatte viele Private probleme und konnte einfach nicht Online gehen.

      Das mit dem Tut ist keine schlechte Idee.
      Werde ich die Tage mal schnell machen. Ein wenig Zeit brache ich aber noch.

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##