Access 2003 lookup values

Συζητήσεις για την τοπική βάση δεδομένων Access της Microsoft

Συντονιστές: Super-Moderators, WebDev Moderators

Απάντηση
Άβαταρ μέλους
verylife
Δημοσιεύσεις: 26
Εγγραφή: 29 Νοέμ 2003 13:34
Τοποθεσία: Athens
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από verylife » 06 Δεκ 2005 13:16

Εχω τους πινακες με τα προιοντα και τον αντιστοιχο με τις κατηγοριες.
tblCategory[ID,Code,Name]
tblProduct[ID,Code,Name,Category_Code]
Θελω να φτιαξω μια φορμα ή ενα ερωτημα που οταν επιλεγω την κατηγορια απο τον πινακα tblCategory να μου
εμφανιζει μονο τα προιοντα του πινακα tblProduct που ανηκουν στην συγκεκριμενη κατηγορια και οχι
ολα.
Ειναι δυνατον αυτο?

Ευχαριστω

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από dva_dev » 06 Δεκ 2005 18:21

Μπορεί να γίνει αλλά θέλει λίγο κώδικα. Θα πρέπει να πιάσεις το event "On Exit" από το πρώτο πεδίο και να κάνεις Requery το δεύτερο.

Στους πίνακες tblCategory και tblProduct τα πεδία ID τί τα χρειάζεσαι αφού έχεις τα πεδίο Code;

Άβαταρ μέλους
verylife
Δημοσιεύσεις: 26
Εγγραφή: 29 Νοέμ 2003 13:34
Τοποθεσία: Athens
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από verylife » 07 Δεκ 2005 08:48

Και πως θα ακριβως θα το κανω αυτο???
To ID απλως το θελω για να εχω σιγουρα ενα κλειδι με μοναδικη εγγραφη στον πινακα μου

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από dva_dev » 07 Δεκ 2005 16:45

Τότε το πεδίο Code τι ρόλο παίζει; Απ' όσο ξέρω κάθε κατηγορία (η προϊόν) μέσα σε μια εταιρία έχει μοναδικό κωδικό. Αρα ένα από τα δύο δεν το χρειάζεσαι. Διαλέγεις ποιό από τα δύο θα χρησιμοποιήσεις και το άλλο το πετάς. Στη θέση σου (μιας και έχεις το Category_Code, οπότε φαντάζομαι ότι έχεις φτιάξει και τα αντίστοιχα relations/indexes) θα κρατούσα και στους δύο πίνακες τα πεδία Code και θα τα δήλωνα σαν πρωτεύοντα κλειδιά.

Στο ζητούμενο:
Βάζεις ένα πεδίο (combo box) στη φόρμα σου το fldCategory το οποίο θα δείχνει τη λίστα με τις κατηγορίες.
Βάζεις ένα δεύτερο combo box το fldProduct το οποίο θα δείχνει τη λίστα με τα αντίστοιχα προϊόντα.

Στις ιδιότητες του fldCategory ορίζεις:
Name: fldCategory
Row Source Type: Table/Query
Row Source: SELECT tblCategory.Code, tblCategory.Name FROM tblCategory;
Bound Column: 1 <-- Ωστε να κρατάει το combo box το πρώτο πεδίο από τα 2 που φέρνει το query
Limit To List: Yes
Column Count: 2 <-- Για να σου δείχνει η λίστα του combo box και τα δύο πεδία που φέρνει το query που όρισες παραπάνω.
Column Heads: No <-- Για να μην φαίνονται τα ονόματα των πεδίων που φέρνει το query
Column Widths: 1cm; <-- Η πρώτη στήλη να έχει πλάτος 1cm και ότι περισσεύει από το πλάτος του Combo Box το παίρνει η δεύτερη. Αν δεν θέλεις να εμφανίζεται ο κωδικός παρά μόνο το όνομα θα βάλεις 0cm;

Στις ιδιότητες του fldProduct ορίζεις:
Name: fldProduct
Row Source Type: Table/Query
Row Source: SELECT tblProduct.Code, tblProduct.Name FROM tblProduct WHERE tblProduct.Category_Code=[fldCategory]; <--Εδώ του λέμε να περιορίσει τα data που φέρνει.
Bound Column: 1 <-- Ωστε να κρατάει το combo box το πρώτο πεδίο από τα 2 που φέρνει το query
Limit To List: Yes
Column Count: 2 <-- Για να σου δείχνει η λίστα του combo box και τα δύο πεδία που φέρνει το query που όρισες παραπάνω.
Column Heads: No <-- Για να μην φαίνονται τα ονόματα των πεδίων που φέρνει το query
Column Widths: 0cm; <-- Η πρώτη στήλη να έχει πλάτος 0cm (δεν φαίνεται) και φαίνεται μόνο η 2η (το όνομα του Προϊόντος). Αν θέλεις να εμφανίζεται και ο κωδικός θα βάλεις π.χ. 1cm;

Τώρα πρέπει να πιάσεις το event OnExit του fldCategory και να κάνεις Requery το fldProduct.

Κώδικας: Επιλογή όλων

Private Sub fldCategory_Exit&#40;Cancel As Integer&#41;
    fldProduct.Requery
End Sub
Επειδή όμως όταν ανοίγει η φόρμα σου σε κάποια εγγραφή ή ο χρήστης μετικινείται σε αυτές πρέπει να συγχρονίσεις τo πεδίo fldProduct με αυτό που δείχνει το fldCategory.

Οπότε πιάνεις το event On Current της φόρμας και γράφεις τον αντίστοιχο κώδικα:

Κώδικας: Επιλογή όλων

Private Sub Form_Current&#40;&#41;
    fldProduct.Requery
End Sub
Επειδή όμως μπορεί να έχεις έναν ψυχάκια χρήστη ο οποίος δεν έχει δουλειά να κάνει και έχει ανοίξει τη φόρμα σου και έχει κολλημένο το δάχτυλο (όχι στη σκανδάλη) αλλά στο tab και το fldCategory χάνει το focus αρκετές φορές το δευτερόλεπτο, αναγκάζοντας την εφαρμογή σου να κάνει ένα σωρό άχρηστα requeries (τα οποία ειδικά αν γίνονται μέσω δικτύου σε κάποιον άλλο Η/Υ με παραφορτωμένη βάση μπορεί να αργούν αρκετά) φτάνοντας τον υπολογιστή σου στο αμήν, καλό είναι να γνωρίζεις αν είναι ανάγκη να γίνει αυτό το καταραμένο requery ή όχι. Οπότε σκόπιμο θα ήταν να χρησιμοποιήσεις μια μεταβλητή (την bNeedRequeryProducts <-- boolean) για αυτό το σκοπό.

Ετσι όταν αλλάξει τιμή το fldCategory θα πρέπει να κάνουμε requery (όπως και όταν μετακινούμαστε από μια εγγραφή σε κάποια άλλη) και όταν απλώς χάνει το focus το fldCategory χωρίς να έχουμε αλλάξει την τιμή του όχι.

Συνεπώς πιάνουμε το event On Change του fldCategory, δηλώνουμε και τη μεταβλητή bNeedRequeryProducts (σαν member μεταβλητή της φόρμας), και αλλάζουμε και τις υπάρχουσες procedures που γράψαμε ώστε να εκμεταλλεύονται αυτή την μεταβλητή. Ενα ακόμα σημείο που πρέπει να προσέξουμε εδώ, είναι όταν το fldProduct έχει κάποια τιμή, και εμείς αλλάζουμε τιμή στο fldCategory τότε αυτόματα η τιμή του fldProduct γίνεται invalid, και το απλούστερο που μπορούμε να κάνουμε είναι να την σβήσουμε, ώστε ο χρήστης να το προσέξει και να ξανασυμπληρώσει το fldProduct με νέα valid τιμή.

O κώδικας συνολικά με τις νέες τροποποιήσεις έχει ως εξής:

Κώδικας: Επιλογή όλων

Option Explicit

Dim bNeedRequeryProducts As Boolean

Private Sub fldCategory_Change&#40;&#41;
    bNeedRequeryProducts = True
End Sub

Private Sub fldCategory_Exit&#40;Cancel As Integer&#41;
    If &#40;bNeedRequeryProducts <> False&#41; Then
        fldProduct.Value = Null
        fldProduct.Requery
        bNeedRequeryProducts = False
    End If
End Sub

Private Sub Form_Current&#40;&#41;
    fldProduct.Requery
    bNeedRequeryProducts = False
End Sub
Φυσικά σηκώνει ακόμα περισσότερες βελτιστοποιήσεις αλλά με αυτά μπορείς να κάνεις τη δουλειά σου και δεν νομίζω πως υπάρχει λόγος να κάνουμε ολόκληρη διατριβή για δύο ρημαδοπεδία.

Ελπίζω να βοήθησα.
:D

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από dva_dev » 07 Δεκ 2005 16:58

Μια μικρή δοκιμαστική βάση (σε Access 2000 format) για όποιον θέλει να δοκιμάσει (ή να παιδεύεται) τα παραπάνω.
Συνημμένα
test.zip
(17.14 KiB) Μεταφορτώθηκε 754 φορές

Άβαταρ μέλους
verylife
Δημοσιεύσεις: 26
Εγγραφή: 29 Νοέμ 2003 13:34
Τοποθεσία: Athens
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από verylife » 08 Δεκ 2005 16:27

ευχαριστω πολυ ... ακολουθησα τις συμβουλες σου και εχω ηδη σβησει καποια πεδια
Απλως να ρωτησω, πρεπει να γινει και ενας τριτος πινακας για να λειτουργησει?
Γιατι ηδη οι πινακες που εχω και ακολουθουν την δομη φτανουν σε τεταρτο επιπεδο και οπως καταλαβαινεις ειναι πολυ δυσκολο στο να κανω και αλλους πινακες μιας και αυτο ειναι επι 3 φορες.
Ευχαριστω παντως και παλι

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από dva_dev » 08 Δεκ 2005 19:09

Τον πίνακα tblTest δεν τον χρειάζεσαι.

Οι πίνακες αυτοί που έχεις και φτάνουν σε 4ο επίπεδο χρησιμοποιούνται σε κάποιον άλλο 5ο? Αυτός ο 5ος πίνακας που έχεις εσύ είναι ο tblTest που χρησιμοποίησα στο παράδειγμα.

Η διαδικασία που περιγράφω μπορεί να δουλέψει για οποιονδήποτε πίνακα αρκεί να ενημερώσεις τα αντίστοιχα Record source της φόρμας, Control source και row source των πεδίων με τα ονόματα των πινάκων που έχεις εσύ στη δική σου batabase.

Άβαταρ μέλους
verylife
Δημοσιεύσεις: 26
Εγγραφή: 29 Νοέμ 2003 13:34
Τοποθεσία: Athens
Επικοινωνία:

Access 2003 lookup values

Δημοσίευση από verylife » 12 Δεκ 2005 11:18

@dva_dev

ΟΚ. εγιναν ολα οπως ακριβως τα ηθελα να εισαι καλα φιλε!!!!
Ευχαιστω πολυ για την αμεση απαντηση σου

Απάντηση

Επιστροφή στο “MS Access”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες