Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Currency???

Îåêßíçóå áðü ôï ìÝëïò Ευθύμης Δημόπουλος. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 23-12-2006, 08:30. Υπάρχουν 37 απαντήσεις.
Σελίδα 2 από 3 (38 εγγραφές)   < 1 2 3 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  19-12-2006, 23:52 22533 σε απάντηση της 22529

    Απ: Currency???

    Αυτό δεν θα το συνιστούσα σε καμμία περίπτωση. Η αλλαγή των regional settings δεν είναι καλύτερη λύση από το να προσπαθείς να "καρφώσεις" την τελεία σαν υποδιαστολή. Είναι ακριβώς αυτό που εννοούσα να "διορθώσει" κανείς τον τρόπο λειτουργίας του .ΝΕΤ. Θα πρέπει να ελέγχεις συνέχεια ότι χρησιμοποιείς το σωστό locale και δεν έχει ξεφύγει κατά λάθος το ένα ή το άλλο locale. Εξάλλου, ο τελικός χρήστης μπορεί να χρησιμοποιήσει οποιοδήποτε locale θέλει. Όσο δεν πειράζεις το locale από τον κώδικα, η επιλογή του χρήστη δεν σε επηρεάζει. Μόλις αρχίσεις να τα πειράζεις, θα πρέπει να κάνεις συνεχώς μετατροπές από το ένα locale στο άλλο.

    Στην περίπτωση εδώ, πέρα από την περίπτωση το PPrice να είναι string, μπορεί τα regional settings να είναι ελληνικά και ο χρήστης να δίνει "3.14" σε κάποιο textbox. Αυτό βάση των ελληνικών regional settings ΕΙΝΑΙ 314. Αν γράψει κανείς Convert.ToDecimal("3.14") και έχει ελληνικά regional settings, θα πάρει πίσω 314. Το ίδιο θα συμβεί αν έχει αμερικάνικα settings και γράψει Convert.ToDecimal("3,14"). Αλλάζοντας με κώδικα τα regional settings από το ένα locale στο άλλο, το μόνο που πετυχαίνει κανείς είναι να αποτύχει η μία ή η άλλη μορφή του 3.14.

    Το πρόβλημα πλέον είναι διαφορετικό. Δεν είναι πλέον το πως γίνεται η μετατροπή από string σε decimal, αλλά πως εξασφαλίζουμε ότι ο χρήστης θα δώσει τη σωστή υποδιαστολή, ή τί κάνουμε αν δώσει λάθος υποδιαστολή. Εδώ τώρα υπάρχουν διάφορες επιλογές, με τα υπέρ και τα κατά τους. Μία λύση, είναι να χρησιμοποιηθεί ένα Masked Text Box, αντί για απλό text box, έτσι ώστε να μην επιτρέπεται ο χρήστης να δώσει λάθος κείμενο. Δυστυχώς, το Masked Text Box είναι λίγο δύσχρηστο. Άλλη λύση είναι να επιτρέπεται μόνο η εισαγωγή υποδιαστολής και όχι του διαχωριστικού χιλιάδων. Αυτό μπορεί να γίνει στο KeyDown του Textbox. Αυτή η λύση είναι καλή αν ξέρουμε ότι θα εισαχθούν μόνο μικρά νούμερα. Αν έχουμε εκατοντάδες χιλιάδες, ο χρήστης σίγουρα θα θέλει να βάλει και διαχωριστικά. Μία επιπλέον λύση, λίγο πιο περίπλοκη, είναι να θεωρούμε ότι η υποδιαστολή είναι το τελευταίο "." ή "," από δεξιά. Μόνο που έτσι μπλέκουμε πάλι με τις χιλιάδες. Ίσως, η καλύτερη λύση θα ήταν να επιτρέπουμε την εισαγωγή μόνο της υποδιαστολής, αλλά να φορμάρουμε τον αριθμό έτσι ώστε να φαίνονται οι χιλιάδες.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  20-12-2006, 09:57 22549 σε απάντηση της 22533

    Απ: Currency???

    Παναγιώτη η PPrice έχει οριστεί σαν decimal

    επίσης στην access το αντίστοιχο πεδίο είναι decimal

    Ο Μ Ω Σ

    το πρόβλημά μου είναι ότι στην vb το μετατρέπω στο κανονικό φορμά ενός δεκαδικού(0.00)

    ΑΛΛΑ η access

    σύμφωνα με τα settings το παίρνει σαν ακέραιο!!! (000)

    τι γίνεται με τα settings και την access???

    όταν έλεγα για region settings δεν εννοούσα αλλαγή αλλά

    ανάλογα με τη ρύθμιση να έστελνα τον αντίστοιχο τύπο δεκαδικού δηλ είτε "0,00" είτε

    "0.00"

    όμως δεν υπάρχει κάτι πιο σωστό από αυτό...?
  •  20-12-2006, 11:39 22554 σε απάντηση της 22549

    Απ: Currency???

    Ε, λοιπόν, φαίνεται ότι το πρόβλημα είναι της Access, και δεν έχει να κάνει με τα regional settings της εφαρμογής!

    Δοκίμασα κι εγώ να φτιάξω ένα command που εισάγει decimals, και διαπίστωσα ότι παρότι έδινα ένα decimal variable με τιμή 3,14, στη βάση κατέληγε 314! Ψάχνοντας βρήκα το PRB: Incorrect NUMERIC and DECIMAL conversions with non-English locales  το οποίο εξηγεί ότι το πρόβλημα βρίσκεται σε ένα function της Oleaut32.dll και έχει διορθωθεί με το Windows 2000 Service Pack 2. Μόνο που εγώ έχω Windows XP!

    Το άρθρο περιέχει μία κάπως υποφερτή λύση, να καλέσει κανείς από τον κώδικα του την SetVarConversionLocaleSetting(1) για να αναγκάσει την oleaut32.dll να χρησιμοποιήσει το locale του thread. Yuck!


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  20-12-2006, 13:56 22561 σε απάντηση της 22554

    Απ: Currency???

    χμμμ

    αυτό ακριβώς εννοούσα

    σε ευχαριστώ πολύ που ασχολήθηκες Παναγιώτη...

    κι εγώ σε XP Pro SP2 δουλεύω...

    θα κάτσω να διαβάσω το άρθρο αλλά δε φαντάζομαι να με καλύψει...
  •  20-12-2006, 18:23 22580 σε απάντηση της 22561

    Απ: Currency???

     pkanavos wrote:


    Στην περίπτωση εδώ, πέρα από την περίπτωση το PPrice να είναι string, μπορεί τα regional settings να είναι ελληνικά και ο χρήστης να δίνει "3.14" σε κάποιο textbox. Αυτό βάση των ελληνικών regional settings ΕΙΝΑΙ 314. Αν γράψει κανείς Convert.ToDecimal("3.14") και έχει ελληνικά regional settings, θα πάρει πίσω 314. Το ίδιο θα συμβεί αν έχει αμερικάνικα settings και γράψει Convert.ToDecimal("3,14"). Αλλάζοντας με κώδικα τα regional settings από το ένα locale στο άλλο, το μόνο που πετυχαίνει κανείς είναι να αποτύχει η μία ή η άλλη μορφή του 3.14.



    Δυστυχώς αν και πιο άπειρος θα διαφωνήσω γιατί αυτό που αναφέρεις δεν είναι λογικο και επειδή το πρόβλημα παρουσιάζεται συχνά σε εφαρμογές θα εξηγήσω. Φυσικά και δεν θα αλλάξεις καρφωτά τα Regional Settings... Μπορείς να κάνεις ελέγχους αν σε ικανοποιούν τα settings του user και αν όχι, τα αλλάζεις κάνεις τη δουλειά σου, και μετά επαναφέρεις τα αρχικά. Άρα η εργασία που θέλεις να εκτελέσεις εκτελείται υπό τις συνθήκες που εσύ ορίζεις και όχι από τη διάθεση του χρήστη. Και επειδή έχω δουλέψει σε εφαρμογές τιμολόγησης όπου εισάγονται τιμές από textbox γνωρίζω τι βάσανο είναι για την υποστήριξη του πελάτη τα προβλήματα με τα regional settings...


    View Παναγιώτης Χαραλάμπους's profile on LinkedIn
    Coding at Mediterranean Acoustics
  •  20-12-2006, 19:09 22588 σε απάντηση της 22580

    Απ: Currency???

     Pak wrote:
     pkanavos wrote:


    Στην περίπτωση εδώ, πέρα από την περίπτωση το PPrice να είναι string, μπορεί τα regional settings να είναι ελληνικά και ο χρήστης να δίνει "3.14" σε κάποιο textbox. Αυτό βάση των ελληνικών regional settings ΕΙΝΑΙ 314. Αν γράψει κανείς Convert.ToDecimal("3.14") και έχει ελληνικά regional settings, θα πάρει πίσω 314. Το ίδιο θα συμβεί αν έχει αμερικάνικα settings και γράψει Convert.ToDecimal("3,14"). Αλλάζοντας με κώδικα τα regional settings από το ένα locale στο άλλο, το μόνο που πετυχαίνει κανείς είναι να αποτύχει η μία ή η άλλη μορφή του 3.14.



    Δυστυχώς αν και πιο άπειρος θα διαφωνήσω γιατί αυτό που αναφέρεις δεν είναι λογικο και επειδή το πρόβλημα παρουσιάζεται συχνά σε εφαρμογές θα εξηγήσω. Φυσικά και δεν θα αλλάξεις καρφωτά τα Regional Settings... Μπορείς να κάνεις ελέγχους αν σε ικανοποιούν τα settings του user και αν όχι, τα αλλάζεις κάνεις τη δουλειά σου, και μετά επαναφέρεις τα αρχικά. Άρα η εργασία που θέλεις να εκτελέσεις εκτελείται υπό τις συνθήκες που εσύ ορίζεις και όχι από τη διάθεση του χρήστη. Και επειδή έχω δουλέψει σε εφαρμογές τιμολόγησης όπου εισάγονται τιμές από textbox γνωρίζω τι βάσανο είναι για την υποστήριξη του πελάτη τα προβλήματα με τα regional settings...



    Πως ακριβώς αλλάζεις τα Regional Settings; Μπορείς να δώσεις λίγο κώδικα;
    Η τακτική να τα αλλάζεις δεν είναι σωστή, γιατί δεν τα αλλάζεις μόνο για την εφαρμογή σου, αλλά για όλο το σύστημα, στο οποίο εκτελούνται πολλά άλλα processes εκτός από τα δικά σου. Αν θέλεις δώσε ένα παράδειγμα για το οποίο μπορεί να θέλεις να τα αλλάξεις και θα δεις ότι μάλλον μπορεί να γίνει και διαφορετικά.
    π.χ. αν θέλεις να μετατρέψεις έναν αριθμό σε string χρησιμοποιώντας το # σαν υποδιαστολή τότε κάνεις το ακόλουθο (και δεν αλλάζεις την υποδιαστολή στα regional options) :
                        Dim myNumber as Decimal = 4.234
                        Dim provider = new System.Globalization.NumberFormatInfo()
                        provider.NumberDecimalSeparator = "#"
                        Dim myString = myNumber.ToString(provider)


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  20-12-2006, 22:22 22602 σε απάντηση της 22580

    Απ: Currency???

    Προφανώς ο Pak εννοεί να αλλάξει κανείς το CultureInfo του Thread. Αλλά όπως ήδη βρήκαμε, δεν είναι εκεί το πρόβλημα. Ίσα-ίσα, αν το δοκίμαζε αυτό ο Efthimis, δεν υπήρχε περίπτωση να βρει ποιό είναι το πραγματικό πρόβλημα και τη λύση του. Όσο για το "σε ικανοποιούν τα setting του user", όλο το πρόβλημα δημιουργείται γιατί το θέμα είναι να ικανοποιηθεί ο χρήστης, όχι να αναγκαστεί να κάνει ότι ζητάει η εφαρμογή. Τί θα του πεις, "γύρνα σε αγγλικά γιατί αυτό υποστηρίζει η εφαρμογή"? "Μήν χρησιμοποιείς το κόμμα" ή "Μή χρησιμοποιείς την τελεία"? Εξάλλου το πρόβλημα μας εδώ δεν είναι η μετατροπή από string σε decimal, αλλά το ότι ο OLEDB driver κάνει μερικές μυστήριες μετατροπές στα ίδια τα decimals. Στην περίπτωση μας, θα πρέπει αντί να χρησιμοποιείς parameterized query ή stored procedures, να χρησιμοποιήσεις χύμα SQL για να μπορέσεις να δώσεις το κατάλληλο string αντί για decimal.

    Και καλά, πες ότι "διόρθωσες" το πρόβλημα αλλάζοντας το Thread.CurrentCulture, ή ακόμα καλύτερα, χρησιμοποίησες τη μορφή της Parse η οποία δέχεται συγκεκριμένο CultureInfo. Τί θα γίνει αν κάποια στιγμή ο χρήστης περάσει σε SQL Server, ή εγκαταστήσει ένα Service Pack που διορθώνει το πρόβλημα? Τότε το "fix" θα σκάσει και θα πρέπει να γράψεις ξανά-μανά κι άλλο κώδικα για να "διορθώσεις" τη "διόρθωση", ή να αφαιρέσεις όλες τις "διορθώσεις".
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  20-12-2006, 22:42 22603 σε απάντηση της 22588

    Απ: Currency???

     papadi wrote:

    Πως ακριβώς αλλάζεις τα Regional Settings; Μπορείς να δώσεις λίγο κώδικα;
    Η τακτική να τα αλλάζεις δεν είναι σωστή, γιατί δεν τα αλλάζεις μόνο για την εφαρμογή σου, αλλά για όλο το σύστημα, στο οποίο εκτελούνται πολλά άλλα processes εκτός από τα δικά σου. Αν θέλεις δώσε ένα παράδειγμα για το οποίο μπορεί να θέλεις να τα αλλάξεις και θα δεις ότι μάλλον μπορεί να γίνει και διαφορετικά.
    π.χ. αν θέλεις να μετατρέψεις έναν αριθμό σε string χρησιμοποιώντας το # σαν υποδιαστολή τότε κάνεις το ακόλουθο (και δεν αλλάζεις την υποδιαστολή στα regional options) :
                        Dim myNumber as Decimal = 4.234
                        Dim provider = new System.Globalization.NumberFormatInfo()
                        provider.NumberDecimalSeparator = "#"
                        Dim myString = myNumber.ToString(provider)

    ΛΑΘΟΣ!!! ο εξής κώδικας αλλάζει το cultureinfo σε επίπεδο application

    System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

    ενοοώ το εξής

    string OriginalInfo = System.Threading.Thread.CurrentThread.CurrentCulture.ToString();

    if(System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()!="el-GR")

    {

    System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("el-GR");

    //DO YOUR JOB...

    System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(OriginalInfo);

    }

    else

    {

    //DO YOUR JOB...

    }

    Έτσι τήν ώρα της εκτέλεσης της κρίσιμης λειτουργίας είσαι βέβαιος ότι το cultureInfo είναι αυτό το οποίο έχεις υπ όψην...

     


    View Παναγιώτης Χαραλάμπους's profile on LinkedIn
    Coding at Mediterranean Acoustics
  •  20-12-2006, 22:47 22604 σε απάντηση της 22603

    Απ: Currency???

    Συμφωνώ, το πρόβλημα είναι αλλού και έχουμε ξεφύγει!! Αν θέλετε το συζητάμε σε άλλο φόρουμ... Προφανώς υπάρχει διάσταση απόψεων!!!:)
    View Παναγιώτης Χαραλάμπους's profile on LinkedIn
    Coding at Mediterranean Acoustics
  •  20-12-2006, 22:48 22605 σε απάντηση της 22604

    Απ: Currency???

    Διόρθωση ... Σε άλλο topic...
    View Παναγιώτης Χαραλάμπους's profile on LinkedIn
    Coding at Mediterranean Acoustics
  •  21-12-2006, 01:08 22613 σε απάντηση της 22605

    Απ: Currency???

    Τελικά το βρήκα! Το πρόβλημα εμφανίζεται μόνο αν ο τύπος της παραμέτρου είναι OleDbType.Decimal!

    Αν η παράμετρος οριστεί ως OleDbType.Currency ή OleDbType.Double, όλα δουλεύουν ρολόι. Η συμπεριφορά αυτή δεν επηρεάζεται από το culture του thread ούτε από την κλήση της SetVarConversionLocaleSetting, αλλά από το locale του συστήματος, το οποίο χρειάζεται reboot για να αλλάξει. Μάλλον πέσαμε σε bugάκι του driver, ή του oleaut32.dll! Δυστυχώς, το πρόβλημα αυτό επηρεάζει και τους data adapters που χρησιμοποιούμε. Αν χρησιμοποιούμε datasets με Access, θα πρέπει να αλλάξουμε τις παραμέτρους τύπου Decimal σε Currency στους data adapters για να μην έχουμε το ίδιο πρόβλημα.

    Παρακάτω είναι ο κώδικας που χρησιμοποίησα για τις δοκιμές:



    Imports System.Data
    Imports System.Data.OleDb
    Imports System.Threading
    Imports System.Globalization

    Public Class Form1
        Declare Auto Function SetVarConversionLocaleSetting Lib "oleaut32.dll" (ByVal flags As UInt32) As UInt32

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '*** Uncomment to see that the thread's culture doesn't affect the results
            'SetVarConversionLocaleSetting(1)
            'Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US")
            'Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US")

            Using con As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\db1.mdb")
                con.Open()
                Dim deleteCmd As New OleDbCommand("Delete from Books ")
                deleteCmd.Connection = con
                deleteCmd.ExecuteNonQuery()

                Dim insertCmd As New OleDbCommand("Insert Into Books (Title,Price) VALUES(@title,@price)")
                insertCmd.Parameters.Add("@title", OleDbType.Char).Value = "Zonk1"
                insertCmd.Parameters.Add("@price", OleDbType.Currency).Value = 3.14
                '*** Uncomment to reproduce error
                'insertCmd.Parameters.Add("@price", OleDbType.Decimal).Value = 3.14
                insertCmd.Connection = con
                insertCmd.ExecuteNonQuery()

                Dim selectCmd As New OleDbCommand("select * from Books")
                selectCmd.Connection = con
                Using reader As OleDbDataReader = selectCmd.ExecuteReader
                    While reader.Read()
                        Console.WriteLine("{0} {1}", reader(0).ToString(), reader(1).ToString())
                    End While
                End Using
            End Using

        End Sub
    End Class

    Pak, μπορείς να ξεκινήσεις νέο topic αν θέλεις. Όπως όμως βλέπεις, το πρόβλημα του Efthimis δεν είχε να κάνει με το αν πρέπει ή δεν πρέπει να αλλάζουμε το locale της εφαρμογής.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  21-12-2006, 09:52 22625 σε απάντηση της 22613

    Απ: Currency???

    Να συμπληρώσω ότι το ίδιο ακριβώς πρόβλημα με τους decimals παρουσιάζεται σε .ΝΕΤ 1.1 (τουλάχιστον) με τον Odbc provider της Oracle.

    Νατάσα Μανουσοπούλου
  •  21-12-2006, 10:01 22626 σε απάντηση της 22603

    Απ: Currency???

     Pak wrote:

     papadi wrote:

    Πως ακριβώς αλλάζεις τα Regional Settings; Μπορείς να δώσεις λίγο κώδικα;
    Η τακτική να τα αλλάζεις δεν είναι σωστή, γιατί δεν τα αλλάζεις μόνο για την εφαρμογή σου, αλλά για όλο το σύστημα, στο οποίο εκτελούνται πολλά άλλα processes εκτός από τα δικά σου. Αν θέλεις δώσε ένα παράδειγμα για το οποίο μπορεί να θέλεις να τα αλλάξεις και θα δεις ότι μάλλον μπορεί να γίνει και διαφορετικά.
    π.χ. αν θέλεις να μετατρέψεις έναν αριθμό σε string χρησιμοποιώντας το # σαν υποδιαστολή τότε κάνεις το ακόλουθο (και δεν αλλάζεις την υποδιαστολή στα regional options) :
                        Dim myNumber as Decimal = 4.234
                        Dim provider = new System.Globalization.NumberFormatInfo()
                        provider.NumberDecimalSeparator = "#"
                        Dim myString = myNumber.ToString(provider)

    ΛΑΘΟΣ!!!


    Που ακριβώς είναι το λάθος;

    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  21-12-2006, 10:13 22627 σε απάντηση της 22626

    Απ: Currency???

    Είναι πολύ σημαντικό, σε αυτή τη δουλειά μου κάνουμε, να είμαστε όσο το δυνατόν πιο ακριβής στις εκφράσεις μας. Γι αυτό και σου ζήτησα να δώσεις λίγο κώδικα για να καταλάβω τι εννοείς λέγοντας "αλλαγή των regional options για να γίνει η δουλειά και μετά επαναφορά". Ο κώδικας που έγραψες δεν αλλάζει τα regional options αλλά το cultureinfo του currentthread. Δεν είναι το ίδιο.
    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  21-12-2006, 11:15 22636 σε απάντηση της 22627

    Smile [:)] Απ: Currency???

    Προφανώς μιλούσα για το cultureinfo της εφαρογής και όχι για τα regional options του συστήματος! Συγνώμη αν δεν έγινα κατανοητός...Smile <img src=" src="/cs/emoticons/emotion-1.gif">. Έχω αυτό το ελάττωμα...
    View Παναγιώτης Χαραλάμπους's profile on LinkedIn
    Coding at Mediterranean Acoustics
Σελίδα 2 από 3 (38 εγγραφές)   < 1 2 3 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems