Category Archives: c#

download αρχείων με ελληνικά ονόματα

Ήθελα πριν λίγο καιρό να ξεκινήσω ένα μικρό template για να συμπληρώνω κάποια σημεία και να δημιουργείται αυτόματα ένα word έγγραφο, ώστε να μπορώ στη συνέχεια να το τυπώσω όπου θέλω, να συνεχίσω να το επεξεργάζομαι και να το μορφοποιώ. Ξεκίνησα σαν χαρούμενος πληροφορικάριος και κλίκι-κλίκι, άρχισα να γράφω το template το έβαλα σε ένα χώρο, έφτιαξα και μία φόρμα στο web για να συμπληρώνεις τα 2-3 πραγματάκια που χρειάζονται και το τελικό συμπληρωμένο αρχείο το έστελνα για download. Tο δοκίμασα στον chrome που χρησιμοποιώ κυρίως και όλα ήταν μια χαρά. Ευτυχής είπα να το δοκιμάσω και σε Firefox και σε Internet Explorer. Εκεί ήταν που τελείωσε (τόσο σύντομα) το αίσθημα ευτυχίας και τη θέση του πήραν διάφορα κοσμητικά επίθετα. Ο Firefox αποθήκευε μεν το αρχείο με ελληνικά, αλλά δεν έπαιρνε όλο το όνομα, παρά μόνο ότι υπήρχε μέχρι το πρώτο κενό. Ο Internet Explorer έπαιρνε μεν όλο το όνομα, αλλά δεν διαβαζόταν γιατί τα ελληνικά είχαν χαλάσει γιατί τροποποιούσε το όνομα του αρχείου από utf8 encoding που ήταν σε ότι encoding ήθελε. Τελικά με λίγο ψάξιμο κατέληξα στο συμπέρασμα ότι ο κάθε browser έχει τα δικά του βίτσια όχι μόνο ως προς την κατανόηση, τη μορφοποίηση και την εμφάνιση του css, του html και του javascript κώδικα, αλλά ακόμα και στον τρόπο που πρέπει να δίνεις τα ονόματα των αρχείων που θέλεις να στείλεις σαν attachments για download. O κώδικας τελικά από αυτό (σε aspx):

void WriteFile(string filename, string data)
{
    this.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=UTF-8";
    this.Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
    this.Response.Write(data);
}

και αυτό (σε php):

function writeFile($filename, $data)
{
    header('content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=UTF-8');
    header("Content-Disposition: attachment; filename=$filename;");
    echo $data;
}

Έγινε αυτό:

void WriteFile(string filename, string data)
{
    this.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=UTF-8";

    if (this.Request.Browser.Browser == "Firefox")
    {
        filename = filename.Replace(" ","%20");
        this.Response.AddHeader("Content-Disposition", "attachment; filename*=UTF8''" + filename);
    }
    else
    {
        filename = HttpUtility.UrlEncode(filename).Replace('+', ' ');
        this.Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
    }

    this.Response.Write(data);
}

και αυτό αντίστοιχα:

function writeFile($filename, $data)
{
    header('content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=UTF-8');

    $agent = $_SERVER['HTTP_USER_AGENT'];
    if (strlen(strstr(strtolower($agent), 'firefox')) > 0) {
        $filename = str_replace(' ','%20',$filename);
        header("Content-Disposition: attachment; filename*=UTF8''$filename;");
    }
    else {
        $filename = str_replace('+',' ',urlencode($filename));
        header("Content-Disposition: attachment; filename=$filename;");
    }
    echo $data;
}

Με μερικές δοκιμές, μια λίγο πιο απλοποιημένη μορφή θα μπορούσε να είναι:

void WriteFile(string filename, string data)
{
    if (this.Request.Browser.Browser == "InternetExplorer")
    {
        filename = HttpUtility.UrlEncode(filename).Replace('+', ' ');
    }
    this.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=UTF-8";
    this.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\";");
    this.Response.Write(data);
}

και

function writeFile($filename, $data)
{
    header('content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=UTF-8');
    $agent = $_SERVER['HTTP_USER_AGENT'];
    if (strpos(strtolower($agent),'firefox') == false) {
        $filename = str_replace('+',' ',urlencode($filename));
}
header("Content-Disposition: attachment; filename=\"$filename\";");
echo $data;
}

Ώστε να στέλνει διαφορετικό header – ή διαφορετικά κωδικοποιημένο το όνομα – ανάλογα τον browser, σύμφωνα με τα ιδιαίτερα γούστα τους. Αυτό φυσικά δεν σημαίνει ότι άλλες εκδόσεις των browsers ή “περίεργοι” χαρακτήρες στα ονόματα δεν θέλουν περισσότερη εξειδικευμένη αντιμετώπιση. Όμως δεν έχω browsers – ούτε όρεξη προς το παρόν – να το ψάξω… Ίσως κάποια στιγμή αργότερα.

Δείτε το demo.

Δι@ύγεια OpenData API

Συνεχίζοντας την προσπάθεια σε C# να χρησιμοποιήσω το API της Δι@ύγειας για να πάρω πληροφορίες για το έγγραφο που με ενδιαφέρει και μετά από αρκετές αποτυχημένες δοκιμές είπα να προσπαθήσω με παλιότερο κώδικα που ξέρω ότι δουλεύει.

Οπότε παίρνοντας τον παλιότερο κώδικα που χρησιμοποιούσα για να διαβάζω τον html κώδικα μιας ιστοσελίδας (και να βρίσκω την εξωτερική ip του router μου) έκανα την πρώτη δοκιμή στο http://et.diavgeia.gov.gr/f/all/search/results.php?include_ada=1&field_ada=%CE%924%CE%A9%CE%9B%CE%A7-%CE%A8%CE%9A%CE%92

Ο αρχικός κώδικας ήταν λοιπόν:

public static bool CheckDiavgeiaADA(string ADA)
{
    string url = "http://et.diavgeia.gov.gr/f/all/search/results.php?include_ada=1&field_ada=" + ADA;
    string webPage = GetWebResponse(url);
    return true;
}

public static string GetWebResponse(string url)
{
    try
    {
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        request.Method = WebRequestMethods.Http.Get;
        request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.Reload);
        System.Net.HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        String responseText = reader.ReadToEnd();
        reader.Close();
        dataStream.Close();
        response.Close();
        return responseText;
    }
    catch (System.Net.WebException ex)
    {
        System.Diagnostics.Debug.Write(ex.Message);
        return string.Empty;
    }
}

Η πρώτη προσπάθεια ήταν επιτυχής, μπορούσα να διαβάσω το περιεχόμενο της ιστοσελίδας. Μετά ήρθε η ώρα να διαβάσω τη σελίδα όπως λέει το api (http://opendata.diavgeia.gov.gr/api/decisions?ada=Β4ΩΛΧ-ΨΚΒ)

Ο κώδικας έγινε

public static bool CheckDiavgeiaADA(string ADA)
{
    try
    {
        //ADA = System.Web.HttpUtility.UrlEncode(ADA);
        string s = "http://opendata.diavgeia.gov.gr/api/decisions?ada=" + ADA;
        string xmlStr = GetWebResponse(s);
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xmlStr);
    }
    catch (WebException e)
    {
        System.Diagnostics.Debug.Print(e.ToString());
    }
    return false;
}

και εμφανίστηκε πάλι το γνωστό web exception όπως και πριν. Πλέον όμως ο κώδικας έσκαγε μέσα στην GetWebResponse που σε άλλες σελίδες δουλεύει κανονικά. Έκανα μια δοκιμή σε άλλες σελίδες που επιστρέφουν xml document για να επιβεβαιώσω ότι ο κώδικας αυτός δεν περιορίζεται στο να διαβάζει μόνο text και html documents και πάλι έπαιξε κανονικά.

Άρα κάτι “βιτσιόζικο” έχει ο συγκεκριμένος server της διαύγειας. Είτε είναι πολύ αυστηρός στις απαιτήσεις του για να επιστρέψει ένα σωστό xml document, είτε πολύ “αρρωστιάρικος” και αν δεν του δώσεις το request όπως ακριβώς το χρειάζεται, τα χάνει και “βαράει μπιέλες”. Θα έλεγα μάλλον το δεύτερο, κρίνοντας από το exception stack.

Αφού είχα ήδη την προηγούμενη εμπειρία από τον php κώδικα που δούλεψε προσθέτοντας μερικά επιπλέον directions στο request (για την file_get_contents) είπα να κάνω μια προσπάθεια να βάλω τα ίδια directions μήπως και γίνει κάτι.

Ξεκίνησα προσθέτοντας τη γραμμή

request.KeepAlive = true;

μετά το request.CachePolicy αλλά δεν υπήρξε καμία διαφορά. Σειρά είχε λοιπόν να προστεθεί και το

request.Accept = "*/*";

και το θαύμα έγινε. Η σελίδα μου επέστρεψε το xml document. Μα είναι δυνατόν; Τέλος πάντων αφού έπαιξε…

Ο κώδικας τελικά που παίζει και για τις υπόλοιπες ιστοσελίδες και για το OpenData web service της Δι@ύγειας έγινε:

public static bool CheckDiavgeiaADA(string ADA)
{
    try
    {
        //ADA = System.Web.HttpUtility.UrlEncode(ADA);
        string s = "http://opendata.diavgeia.gov.gr/api/decisions?ada=" + ADA;
        string xmlStr = GetWebResponse(s);
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xmlStr);
    }
    catch (WebException e)
    {
        System.Diagnostics.Debug.Print(e.ToString());
    }
    return false;
}

public static string GetWebResponse(string url)
{
    try
    {
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        request.Method = WebRequestMethods.Http.Get;
        request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.Reload);
        request.Accept = "*/*";
        request.KeepAlive = true;
        System.Net.HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        String responseText = reader.ReadToEnd();
        reader.Close();
        dataStream.Close();
        response.Close();
        return responseText;
    }
    catch (System.Net.WebException ex)
    {
        System.Diagnostics.Debug.Write(ex.Message);
        return string.Empty;
    }
}

…εντάξει όχι ακριβώς έτσι γιατί η function CheckDiavgeiaADA δεν κάνει κάτι χρήσιμο έτσι όπως είναι, αλλά τώρα έχουμε το xml για να πάρουμε τα στοιχεία που μας ενδιαφέρουν.

Δι@ύγεια OpenData API

Προσπαθώ να πάρω μερικές πληροφορίες για συγκεκριμένα έγγραφα από το web service της διαύγειας, σύμφωνα με αυτά που αναφέρονται στο http://opendata.diavgeia.gov.gr/

Εχω λοιπόν τον εξής απλούστατο κώδικα:

try
{
 ADA = "Β4ΩΛΧ-ΨΚΒ";
 //ADA = System.Web.HttpUtility.UrlEncode("Β4ΩΛΧ-ΨΚΒ");
 System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
 string s = "http://opendata.diavgeia.gov.gr/api/decisions?ada=" + ADA;
 doc.Load(s);
}
catch (WebException e)
{
 System.Diagnostics.Debug.Print(e.ToString());
}

To οποίο πάντα (μα πάντα) μου πετάει το εξής web exception:

A first chance exception of type 'System.Net.WebException' occurred in System.Xml.dll
System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
 at System.Net.HttpWebRequest.GetResponse()
 at System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials)
 at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials)
 at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
 at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
 at System.Threading.CompressedStack.runTryCode(Object userData)
 at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
 at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
 at System.Xml.XmlTextReaderImpl.OpenUrl()
 at System.Xml.XmlTextReaderImpl.Read()
 at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
 at System.Xml.XmlDocument.Load(XmlReader reader)
 at System.Xml.XmlDocument.Load(String filename)
 at Τest.TestADA.ADACheck(String ADA)

Μόλις πάρω internal server error, φαίνεται ότι κρασάρει ολόκληρο το web service στον server της Διαύγειας και δεν μπορώ να δω ούτε από web browser το xml δίνοντας τη διεύθυνση. Απλώς ο web server της διαύγειας απαντάει με το εξής:

HTTP Status 500 -
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Could not resolve view with name 'xmlView' in servlet with name 'diavgeia-api'
 org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1042)
 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
 org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:344)
 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:110)
 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:98)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:95)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:55)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:36)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:178)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:150)
 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
 org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.29 logs.
Apache Tomcat/6.0.29

Μετά από λίγο (δεν έχω μετρήσει να δώ αν είναι 1 λεπτό ή 10) συνέρχεται ο web server, μέχρι να ξανατρέξω τον κώδικα και να ξανακρασάρει 😮

Υπάρχει καμιά πρόταση, ώστε να παίρνω τις πληροφορίες που θέλω;
Εχω μπροστά μου κάποιο λάθος και δεν το βλέπω;
Δεν ζητάω πολλά, αυτό που δείχνει η διεύθυνση για παράδειγμα http://opendata.diavgeia.gov.gr/api/decisions?ada=Β4ΩΛΧ-ΨΚΒ

Αριθμοί Κυκλοφορίας

Μια απλή κλάση που τροποποιεί τους αριθμούς κυκλοφορίας ώστε να μείνουν μόνο οι επιτρεπτοί χαρακτήρες για τους αριθμούς κυκλοφορίας στις ελληνικές πινακίδες. Οι ελληνικοί χαρακτήρες που δεν υπάρχουν στο λατινικό αλφάβητο αφαιρούνται, και όσοι μένουν μετατρέπονται στον αντίστοιχο (οπτικά) λατινικό χαρακτήρα.
Οι λατινικοί μένουν όπως είναι, αφού αφορούν πινακίδες ξένων κρατών.
Αν τώρα υπάρχουν πινακίδες με αραβικά γράμματα, ταϊλανδέζικα, κινέζικα, κ.λπ. δεν έχω δει, οπότε κάνουμε τον κινέζο. 🙂 Continue reading

Highlight C# source code

Επαιζα πριν λίγο καιρό με την php και χρησιμοποιούσα την show_source για να δείχνω χρωματισμένο τον κώδικα. Κάποια στιγμή που προσπάθησα να μεταφράσω τον κώδικα από php σε C# για να δοκιμάσω την ταχύτητα της αντίστοιχης aspx σελίδας, χρειάστηκα πάλι την show_source, αλλά όσο έψαξα δεν βρήκα να δίνει κάτι αντίστοιχο το .net framework. Continue reading

Ημέρες – Μήνες – Έτη

Όσοι θέλουν τη διαφορά ημερομηνιών σε ημέρες μήνες έτη ας μην ψάξουν παραπέρα. Εγώ τη χρειάστηκα πρόσφατα και φαίνεται να δουλεύει σωστά (όσο μπόρεσα να την τεστάρω με δεδομένα και αποτελέσματα που είχα έτοιμα σε κάποια αρχεία excel.) Continue reading

Greeklish σε Ελληνικά

Εχουν γίνει κατά καιρούς αρκετές προσπάθειες να μεταφραστούν και να ορθογραφηθούν οι λέξεις που γράφουν οι χρήστες του internet από greeklish σε ελληνικά ή κατά το ελληνικότερον greeklish to greek. Το πρόβλημα που αντιμετωπίζουν όλοι είναι σε γενικές γραμμές ένα! Ο καθένας γράφει greeklish όπως του γουστάρει. Αυτό είναι εντελώς φυσιολογικό για μια γλώσσα που ουσιαστικά είναι σε μια κατάσταση “ζόμπι”. Χρησιμοποιείται χωρίς να υπάρχει τεκμηρίωση της! Δεν έχει γραμματική, δεν έχει κανόνες, δεν έχει ορθογραφία, δεν έχει συντακτικό, δεν έχει σημεία στίξης, δεν έχει αλφάβητο, δεν έχει τίποτα. Οποιος θέλει να την χρησιμοποιήσει, ορίζει εκείνη τη στιγμή, όσα και όποια από τα προηγούμενα θέλει κατά το δοκούν. Κατά πως θα του κάτσει. Continue reading

What is my Public/External IP

Ηθελε πριν λίγες μέρες ένας φίλος να φτιάξει ένα προγραμματάκι που να του δείχνει ποιά είναι η IP που έχει ο router του όταν συνδέεται στο Internet. Φυσικά η σύνδεση του είναι με δυναμική IP address και γενικά αυτή αλλάζει κάθε όποτε της καπνίσει. Οι βιβλιοθήκες και τα APIs των Windows (των λειτουργικών γενικότερα) μπορούν να σου δώσουν πληροφορίες για τον υπολογιστή τον ίδιο και όχι κάποια άλλη συσκευή ειδικά όταν αυτή μπορεί να συνδέεται στον υπολογιστή μέσα από κάποιο δίκτυο να υπάρχουν proxies, firewalls, και ότι άλλα καλούδια μπορεί να έχει στημένα κάποιος για να νομίζει πως είναι ασφαλής. Continue reading

Ευρώ Ολογράφως

Εψαχνα εδώ και λίγο διάστημα για μια έτοιμη υλοποίηση εμφάνισης ποσών σε ευρώ στην λεκτική τους αναπαράσταση. Είδα αρκετές υλοποιήσεις σε διάφορες γλώσσες (λέμε τώρα, VB κάτι, ήταν όλες, με κάποιες εξαιρέσεις που ήταν μεταφράσεις σε C# των αντίστοιχων VB) με την κάθε μία να έχει τα υπέρ και τα κατά, αναλόγως τις ανάγκες που υπήρχαν.

Αλλη υλοποίηση υποστηρίζει ποσά μέχρι 999.999€ άλλη υποστηρίζει μέχρι 2 δεκαδικά, άλλη υποστηρίζει μεγαλύτερα ποσά, άλλη αρνητικά ποσά. Το να είναι μια υλοποίηση μετάφραση σε άλλη γλώσσα δεν είναι κάτι το μεμπτό, απλώς μου φάνηκε αστείο που όλες οι υλοποιήσεις ήταν VB ή VB.NET, ή VBScript. Ούτε καν COBOL! (Καλά που την θυμήθηκα αυτή τώρα; 🙂 )

Αυτό που έψαχνα να βρώ είναι μια κομψή υλοποίηση σε κάποια γλώσσα που να μην μου είναι εντελώς άγνωστη ώστε να μπορώ να προσαρμόσω τον κώδικα στα γούστα μου. Τον κώδικα που μου άρεσε περισσότερο τον βρήκα σε μια vb.net υλοποίηση του panos_sniper που έχει αναρτήσει στο dotnetzone.gr. Θα προτιμούσα κάτι σε C ή C++ αλλά και η vb.net δεν είναι πρόβλημα. Μπορεί να τρέξει, να δοκιμαστεί ότι δουλεύει σωστά και αν όλα είναι εντάξει το μόνο που μένει είναι να χρησιμοποιηθεί. Continue reading

Ελεγχος Εγκυρότητας Α.Φ.Μ.

Πρόσφατα χρειάστηκε να μεταφέρω δεδομένα από μια βάση δεδομένων σε μια άλλη. Φυσικά όπως θα γνωρίζουν οι περισσότεροι αυτές οι διαδικασίες ποτέ δεν είναι τόσο απλές όσο ακούγονται, ειδικά όταν πρέπει να πέσει μαγείρεμα στα δεδομένα (βλ. διαφορετικοί πίνακες, διαφορετικοί τύποι πεδίων, διαφορετικές τιμές).

Σε αυτά τα δεδομένα υπήρχε και το ΑΦΜ, και μιας και πολλές φορές γινόταν λανθασμένη καταχώρηση, ήταν ευκαιρία να γίνει ένα ξακαθάρισμα. Ψάχνοντας στο Internet για αλγόριθμους ελέγχου του ΑΦΜ βρήκα κάποιες λύσεις σε διάφορες γλώσσες, οπότε έπιασα μια που βρήκα στο digitalnews.gr (σε C# για να μην κάνω και πολλές αλλαγές – έτσι νόμιζα τουλάχιστον) και (αντ)έγραψα την δικιά μου C# function και, ιδού το αποτέλεσμα: Continue reading