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

 

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

Προσπέλαση μη-συνδεδεμένων-σε-κελί controls του Excel από κώδικα

Îåêßíçóå áðü ôï ìÝëïò antonisV. Τελευταία δημοσίευση από το μέλος manosB στις 23-10-2007, 09:33. Υπάρχουν 5 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  21-10-2007, 12:36 36454

    Προσπέλαση μη-συνδεδεμένων-σε-κελί controls του Excel από κώδικα

    Καλημέρα σε όλους/ες,

    Θα ήθελα να ρωτήσω αν και με ποιον τρόπο μπορεί κάποιος να "διαβάσει" και να αλλάξει την τιμή ενός control που έχει δημιουργηθεί σε ένα αρχείο Excel χρησιμοποιώντας κώδικα Visual Basic(6 ή .NET). Γνωρίζω πως υπάρχουν περισσότεροι του ενός τρόποι να διαβάσεις και να αλλάξεις τις τιμές των κελιών σε αρχείο Excel προγραμματιστικά και φυσικά πως τα controls που δημιουργούνται από το Toolbox του Excel μπορούν να συνδεθούν(Linked Cell Attribute) με κάποιο κελί.

    Το πρόβλημα που αντιμετωπίζω είναι πως το Excel αρχείο στην προκειμένη περίπτωση δε δημιουργείται από εμένα και δεν έχω καν πρόσβαση στον δημιουργό ώστε να εξασφαλίσω ότι τα controls θα είναι συνδεδεμένα με κελιά (και άρα το πρόγραμμα να χρειάζεται να "διαβάσει" απλά αυτά τα κελιά). Πρέπει συνεπώς με κάποιον τρόπο να μπορώ μέσα από τον κώδικα εκτός από τα κελιά να "διαβάζω" και να αλλάζω τις τιμές και των όποιων controls(Calendar, Textbox, Checkbox, DropDown κτλ) ο δημιουργός του αρχείου Excel έχει τοποθετήσει σ'αυτό.

    Ευχαριστώ εκ των προτέρων

  •  22-10-2007, 11:09 36482 σε απάντηση της 36454

    Απ: Προσπέλαση μη-συνδεδεμένων-σε-κελί controls του Excel από κώδικα

    O κλασσικός τρόπος είναι να χρησιμοποιήσεις το Microsoft Excel Object Library. Όμως είναι unmanaged και οι guru εδώ μέσα δικαίως θα γκρινιάξουνBig Smile. Φυσικά σε VB6 δεν τίθεται θέμα.
    Τέλος πάντων κάνε add reference στο project σου από το  Tab των COM και θα το βρεις εκεί μέσα. Υπάρχουν αναρίθμητα παραδείγματα χρήσης στο net, κοίτα για παράδειγμα αυτό. Τώρα το κλασσικό τρόπο να κάνεις record τις κινήσεις σου στο excel το περιγράφω εδώ για να μπορέσεις να προσομοιώσεις κώδικα. (Είναι για Word αλλά με τον ίδιο τρόπο κάνεις record σε excel).

    Manos
  •  22-10-2007, 12:32 36485 σε απάντηση της 36482

    Απ: Προσπέλαση μη-συνδεδεμένων-σε-κελί controls του Excel από κώδικα

    Καταρχάς ευχαριστώ πολύ για την απάντηση manosB. Το παράδειγμα στο οποίο με παρέπεμψες το είχα ήδη κοιτάξει και είχα πειραματιστεί με τον κώδικά του. Ωστόσο το πρόβλημα μου παραμένει. Ο κώδικας στο παράδειγμα περιέχει τα εξής:

    ' Add table headers going cell by cell.
    oSheet.Cells(1, 1).Value = "First Name"

    ' Add a Chart for the selected data.
    oResizeRange = oWS.Range("E2:E6").Resize(ColumnSize:=iNumQtrs)
    oChart = oWS.Parent.Charts.Add

    Με worksheet.Cells λοιπόν κάνουμε access τα κελιά και με worksheet.Parent.Charts τα γραφήματα. Τα controls με ποιο attribute τα κάνουμε access και πώς πέρνουμε τις τιμές τους (κάθε ένα είναι και διαφορετική περίπτωση); Υπάρχει περίπτωση να το καταφέρουμε μέσα από το .Shapes; Το μόνο κάπως σχετικό που είχα καταφέρει να εντοπίσω ήταν το Microsoft.Office.Tools.Excel.Controls το οποίο όμως αναφέρεται σε controls που έχουν φτιαχτεί ναι μεν σε Excel αρχείο αλλά μέσα από το Visual Studio(Windows.Forms). Αυτά που θέλω εγώ να προσπελάσω ΔΕΝ είναι αυτά ! Είναι τα controls που ο δημιουργός του Excel αρχείου έχει βάλει, έχει δηλαδή ανοίξει ένα καινούριο Workbook και πήγε και πρόσθεσε ένα Calendar, ένα DropDown, ένα TextBox κτλ.

    Συγγνώμη αν υπάρχει κάτι προφανές που δε βλέπω, αλλά δεν έχω μεγάλη εμπειρία σε .NET. Αν μπορεις να με διαφωτίσεις περεταίρω με βάση τις διευκρινιστικές ερωτήσεις που έκανα, θα το εκτιμούσα πολύ.

    Ευχαριστώ και πάλι.

  •  22-10-2007, 13:48 36486 σε απάντηση της 36485

    Απ: Προσπέλαση μη-συνδεδεμένων-σε-κελί controls του Excel από κώδικα

    Λοιπόν χρησιμοποίησα το κόλπο που σου είπα για το record για να δημιουργήσω ένα Combo. Ο κώδικας που βγήκε είναι ο εξής:

    Sub
    Macro1()
    '
    ' Macro1 Macro
    ' Macro recorded 22/10/2007 by manos
    '

    ActiveSheet.DropDowns.Add(147.75, 36.75, 187.5, 24).Select
    With Selection
    .ListFillRange = "$E$7:$E$14"
    .LinkedCell = "$G$11"
    .DropDownLines = 8
    .Display3DShading = False
    End With
    End Sub

    Έβαλα πολύ απλά ένα κουμπί στο φύλλο και στο κώδικα  του έγραψα αυτό για να πάρω το range του

    Sub
    Button2_Click()
    MsgBox (ActiveSheet.DropDowns(1).ListFillRange)

    End Sub

    Πιστεύω να μπήκες στη λογική. Ομοίως θα μπορούσα να του θέσω κλπ,κλπ Είδες τι χρήσιμο είναι το record??Wink



    Manos
  •  22-10-2007, 21:50 36494 σε απάντηση της 36486

    Απ: Προσπέλαση μη-συνδεδεμένων-σε-κελί controls του Excel από κώδικα

    Λοιπόν, χρησιμοποίησα το κόλπο που πρότεινες με το 'Record Macro'. Πραγματικά είναι πάρα πολύ χρήσιμο στην προκειμένη περίπτωση. Συγχαρητήρια ! Αν λοιπόν, κάποιος φτιάξει ένα Excel αρχείο και αρχίσιε να προσθέτει controls, προκύπτει ότι ισχύει το εξής:

    1. Αν επιλέξει από το Toolbar 'Forms', τότε το το Record Macro μας δίνει τα arrays που μας ενδιαφέρουν όπως στο παράδειγμά σου (DropDowns κτλ.)

    2. Αν όμως επιλέξει από το Toolbar 'Control ToolBox', τότε το το Record Macro μας δίνει:

    Sub Macro1()
    '
    ' Macro1 Macro
    ' Macro recorded 22/10/2007 by user
    '
       ActiveSheet.OLEObjects.Add(ClassType:="Forms.TextBox.1", Link:=False, _
                               DisplayAsIcon:=False, Left:=277.5, Top:=125.25, Width:=132, Height:= _
                               18).Select

       ActiveSheet.OLEObjects.Add(ClassType:="MSCAL.Calendar.7", Link:=False, _
                               DisplayAsIcon:=False, Left:=285, Top:=168, Width:=255.75, Height:= _
                               157.5).Select

       ActiveSheet.OLEObjects.Add(ClassType:="Forms.ComboBox.1", Link:=False, _
                               DisplayAsIcon:=False, Left:=120, Top:=72.75, Width:=108.75, Height:= _
                               15.75).Select
    End Sub

    Τι κάνουμε σε αυτήν την περίπτωση; Προσπάθησα να κινηθώ ανάλογα με την περίπτωση 1:

    Dim i As Integer
    For i = 1 To xlSht.OLEObjects.count
       MsgBox(xlSht.OLEObjects(i).Name)
    Next

    Τα ονόματα τα παίρνω. Το value όμως που με ενδιαφέρει......και μόλις τώρα το βρήκα !!!!!

    Dim i As Integer
    For i = 1 To xlSht.OLEObjects.count
       MsgBox(xlSht.OLEObjects(i).object.Value)
    Next

    Δε χρησιμοποιούσα το .object και μετά έμπλεκε το πράγμα, έψαχνα να κάνω casting.... Ψάχνωντας πάντως ανακάλυψα πως για να βρεις το πραγματικό Type ενός System.__ComObject χρησιμοποιείς το εξής (όπου xlSht.OLEObjects(i) το System.__ComObject):

    MsgBox(Microsoft.VisualBasic.Information.TypeName(xlSht.OLEObjects(i).object))

    Το ανέφερα γιατί μπορεί να χρησιμέυσει σε κάποιον άλλον αναγνώστη.

    Ευχαριστώ manosB πάρα πολύ. Η πατέντα με το Macro έλυσε στην ουσία το πρόβλημα !Wink

  •  23-10-2007, 09:33 36497 σε απάντηση της 36494

    Απ: Προσπέλαση μη-συνδεδεμένων-σε-κελί controls του Excel από κώδικα

    Εύγε νεανία. Yes
    Αν όμως χρειαστεί να φτιάξεις εσύ ένα excel με .net τότε σου συνιστώ ανεπιφύλακτα τα VSTO. Managed Κώδικας, τρομερές δυνατότητες και the way forward.


    Manos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems