This is my corner for documenting my ideas.
It mostly contains posts for Access Databases (samples, full applications, etc.) as i like rapid software application development. Occasionally you will find other stuff like physics notes.

Friday, 9 July 2010

Γεννήτρια Τυχαίων Ημερομηνιών

Πρόσφατα χρειάστηκε να γεμίσω πίνακες που αποτελούνταν από στοιχεία καθορισμού φυσικών προσώπων και επιχειρήσεων. Τα στοιχεία αυτά ήταν ψευδή (τυχαία) και για τα πρόσωπα ήταν επώνυμο, όνομα, φύλο, ημερομηνία γέννησης, αριθμός ταυτότητας, διεύθυνση, τηλέφωνα κλπ., ενώ για τις επιχειρήσεις επωνυμία, ΑΦΜ, δραστηριότητα, διεύθυνση, τηλέφωνα κλπ.  Όπως γίνεται εύκολα αντιληπτό, όσο μεγαλύτερος ο πίνακας (ο αριθμός των εγγραφών δηλαδή - προσώπων και επιχειρήσεων) τόσο πιο δύσκολο το έργο, με την χειρωνακτική αντιμετώπιση του επιθυμητή όσο λιγότερο γίνεται.

Με αφορμή την εργασία αυτή, μου γεννήθηκε η ιδέα μιας εφαρμογής παραγωγής τέτοιων ψευδοστοιχείων προσαρμοσμένα στην ελληνική πραγματικότητα καθώς αντίστοιχα εργαλεία πχ. για την αμερικανική πραγματικότητα υπάρχουν και συχνά στο Microsoft Excel. Φυσικά τα Αγλλικά ονόματα ή οι αριθμοί κοινωνικής ασφάλισης άλλων χωρών μας είναι άχρηστα. Το πρόβλημα στην πλειοψηφία των περιπτώσεων που αποτελείται από επιλογή εγγραφών από μία υπάρχουσα λίστα (π.χ. ονόματα) είναι να δηλωθεί ο αριθμός των επιθυμητών εγγραφών και όποια άλλη ιδιαιτερότητα καθορίζει τη λίστα αυτή (π.χ. στα ονόματα μπορεί να επιθυμούμε μόνο ανδρικά ή γυναικεία). Στην περίπτωση των ονομάτων θα πρέπει να έχουμε συγκεντρώσει σε ένα πίνακα (λίστα) έναν μεγάλο αριθμό ελληνικών μικρών ονομάτων και να έχουμε αντιστοιχίσει τα ονόματα με το φύλο στο οποίο απευθύνονται. Εάν δε επιθυμούμε μεγάλη ακρίβεια στο τυχαίο επιθυμητό δείγμα των ονομάτων θα πρέπει να έχουμε ορίσει και τις πραγματικές συχνότητες εμφάνισης τους στον πληθυσμό και αυτές να αναπαράγονται με επιτυχία στο τυχαίο δείγμα αλλά αυτό είναι ένας βαθμός δυσκολίας παραπάνω.

Ξεκινώντας από την πιο εύκολη περίπτωση όπου δεν απαιτείται η ύπαρξη μίας τέτοιας λίστας από την οποία θα πρέπει να επιλεχθούν τυχαίες εγγραφές αλλά θα πρέπει να δημιουργηθούν όπως πχ. τυχαίες ημερομηνίες, οι απαραίτητες εισαγωγές από τον χρήστη θα πρέπει να είναι ο επιθυμητός αριθμός εγγραφών (ημερομηνιών) και το εύρος στο οποίο θα κινούνται, ένα έτος έναρξης και ένα έτος λήξης δηλαδή. Όταν ειδικά θέλουμε οι τυχαίες αυτές ημερομηνίες να αντιπροσωπεύουν ημερομηνίες γέννησης είναι πιο εύκολο για το χρήστη να δώσει το εύρος ηλικιών των προσώπων (πχ. από 22 εως 35 ετών).

Στο forum ms-office.gr στο οποίο είμαι γραμμένος (μαντέψτε με τι nickname) έθεσα τους παραπάνω προβληματισμούς και η συζήτηση έχει πάρει φωτιά ειδικά για το θέμα των ονομάτων και των συχνοτήτων εμφάνισης μιας και το επίπεδο δυσκολίας εξιτάρει τους φοβερούς σε γνώσεις συμφορουμίτες. Το θέμα των ημερομηνιών λύθηκε εύκολα και πρώτο και το παρουσιάζω και από εδώ. Πρώτα θα πρέπει να γραφεί μία συνάρτηση που θα παράγει τις τυχαίες ημερομηνίες. Ιδού:
Public Function fncRndDate() As Date
    Dim rY As Integer
    Dim rM As Integer
    Dim rD As Integer
    Randomize
       
    'Τυχαίο Έτος
    rY = CInt(Rnd * (Form_TyhaiesHmnies.EndYear - Form_TyhaiesHmnies.StartYear)) + Form_TyhaiesHmnies.StartYear + 1
    'Τυχαίος Μήνας
    rM = CInt(Rnd * 12) + 1
    'Τυχαία Μέρα
    rD = CInt(Day(DateSerial(rY, rM + 1, 0)) * Rnd) + 1
   
    'Τυχαία Ημερομηνία
    fncRndDate = DateSerial(rY, rM, rD)

End Function
Φτιάχνοντας μία μικρή φόρμα όπου ο χρήστης θα δηλώνει πόσες ημερομηνίες θέλει και για ποιες ηλικίες (εικόνα) θα πρέπει να αντιστοιχήσουμε τον παρακάτω κώδικα στο κουμπί που θα ξεκινάει την δημιουργία τους:

Private Sub CmdRndDate_Click()
    On Error GoTo CmdRndDate_Error
    Dim numOfDates As Long
    Dim i As Long
    
    DoCmd.SetWarnings False
    'Απόρριψη πινάκων αν υπάρχουν
    On Error Resume Next
    DoCmd.RunSQL "drop table tblRndDates"
    On Error GoTo 0

    'Δημιουργία πίνακα με τυχαίες ημερομηνίες
    DoCmd.RunSQL "create table tblRndDates (RndDate Date);"
    Application.RefreshDatabaseWindow
    numOfDates = Me.numOfDates
    For i = 1 To numOfDates
        DoCmd.RunSQL "Insert into tblRndDates (RndDate) values(fncRndDate());"
    Next

CmdRndDate_Exit:
    DoCmd.SetWarnings True
    Exit Sub
   
CmdRndDate_Error:
    MsgBox Err.Description
    GoTo CmdRndDate_Exit
End Sub

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