de173 Δημοσ. 7 Σεπτεμβρίου 2012 Δημοσ. 7 Σεπτεμβρίου 2012 Καλησπέρα και πάλι! Προσπαθώ να δημιουργήσω ένα πρόγραμμα εξαγωγής δεδομένων από μία SQL βάση και αποθήκευσής τους σε αρχεία. Το σενάριο είναι το παρακάτω: Υπάρχει πίνακας ο οποίος περιέχει 5 στήλες και 1000 γραμμές. Μέσα σε αυτές τις γραμμές υπάρχει μία στήλη (Cod_Id) η οποία προσδιορίζει το είδος της γραμμής με έναν συγκεκριμένο κωδικό ο οποίος όμως κάθε φορά είναι άγνωστος. Κάθε φορά πρέπει να γίνεται ένα select distinct ώστε να μπορέσουμε να αναγνωρίσουμε ποιοι κωδικοί είναι καταχωρημένοι στο πίνακα. Το ζητούμενο: να αναγνωρισθούν οι κωδικοί και να εξαχθούν τα δεδομένα ανά κωδικό δημιουργώντας διαφορετικά αρχεία με filename βάσει του κωδικού. Επίσης στο τέλος κάθε αρχείου θα πρέπει να εισάγεται μία γραμμή η οποία θα αφορά το άθροισμα μίας από τις 5 στήλες του πίνακα (Amount). Θα μπορούσε κάποιος να βοηθήσει; Μέχρι στιγμής, με όσες προσπάθειες έχω κάνει, θεωρώ ότι ακολουθώ λάθος δρόμο... Ευχαριστώ εκ των προτέρων!
MitsakosGR Δημοσ. 7 Σεπτεμβρίου 2012 Δημοσ. 7 Σεπτεμβρίου 2012 Ας τα πάρουμε ένα ένα στη σειρα. Έχεις φτιάξει το ερώτημα στην SQL για να σου φέρνει τα δεδομένα που θέλεις; Το Select Distinct πώς θα σε βοηθήσει;;; Κάτι δεν καταλαβαίνω σωστά στην δομή του πίνακα ή χρειάζεσαι group by. Άκυρο, το κατάλαβα. Γιατί να κάνεις πρώτα Select Distinct και μετά select για κάθε κωδικό και δεν κάνεις κατευθείαν group by;
de173 Δημοσ. 8 Σεπτεμβρίου 2012 Μέλος Δημοσ. 8 Σεπτεμβρίου 2012 Διότι θέλω για κάθε group που θα έχω μέσα στο πίνακα, να βγάζω και ξεχωριστό αρχείο. Δηλαδή για κάθε αποτέλεσμα του δεύτερου select (αυτό των δεδομένων) το οποίο θα εκτελείται για κάθε αποτέλεσμα του πρώτου select (αυτό των κατηγοριών) να εξάγω ένα αρχείο το οποίο θα έχει και το όνομα από κάθε κατηγορία. Τουλάχιστον έτχι το έχω σκεφτεί.. Ως δύο διαφορετικά selects..
Reselie-206 Δημοσ. 8 Σεπτεμβρίου 2012 Δημοσ. 8 Σεπτεμβρίου 2012 Πολύ πρόχειρα(σορρυ για τυχόν λάθη, απροσεξίες κτλπ απλά για παράδειγμα το έκανα και δε μπορώ να δουλέψω σοβαρά μιας και βρίσκομαι σε χώρο που δε μπορώ να ασχοληθώ ιδιαίτερα...λοιπές μεθόδους προστασίας και ελέγχου δεν έχω συμπεριλάβει... Oυσιαστικά η ουσία είναι : κάνεις 1 σελέκτ τους κωδικούς...τους κρατάς σε πίνακα κάνεις 2 σελέκτ μέσα σε loop ώστε για κάθε κωδικό να τραβήξεις τα λοιπά στοιχεία και μετά να τα περάσεις σε αρχείο (Filename & CoD_ID προτείνω για να είναι μοναδικός ο τίτλος αλλα και να ξεχωρίζει) .Υπολογίζω και τα αθροίσματα που θές λαμβάνοντας υπόψην το v3 column της access db που σου επισυνάπτω... Δέ ξέρω σε τι βάση θα δουλέψεις αλλα όπως και να έχει η λογική δεν αλλάζει... Το Δοκίμασα και λειτουργεί Β) το path εξαγωγής των αρχείων είναι o C:\ γ) Download: https://dl.dropbox.com/u/19856467/TestProjectFor_de173.rar δ) είναι απλά για παράδειγμα ο κώδικας και λειτουργεί μεσω access database.συνεπώς αν θέλεις να δοκιμάσεις την εφαρμογή (στο solution είναι στο debug folder) θα πρέπει να έχεις και access εγκατεστημένo e) ελπίζω να βοήθησα >Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click COD_TABLETableAdapter.Connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & My.Application.Info.DirectoryPath & "\test.accdb" Dim Str As String = "" Dim Sumz As Double = 0 Me.COD_TABLETableAdapter.FillBy(Me.TestDataSet.COD_TABLE) 'όπου cod_table = bound με το datagrid. If DataGridView1.RowCount > 0 Then ' MsgBox("step1") Dim a(DataGridView1.RowCount) As String For i = 0 To DataGridView1.RowCount - 1 a(i) = DataGridView1.Rows(i).Cells(0).Value ' MsgBox("step2") Next Dim rowCount As Integer = DataGridView1.RowCount 'MsgBox("step3") For i = 0 To rowCount - 1 Me.COD_TABLETableAdapter.FillByCOD_ID(Me.TestDataSet.COD_TABLE, a(i)) Dim txt_Write As New IO.StreamWriter("C:\File_" & a(i) & ".txt") ' MsgBox("step4") For r1 = 0 To DataGridView1.RowCount - 1 For c1 = 0 To DataGridView1.ColumnCount - 1 Str = Str & DataGridView1.Rows(r1).Cells(c1).Value & "|" ' MsgBox("step5") Next txt_Write.WriteLine(Str.Remove(Str.LastIndexOf("|"), 1)) For Sum = 0 To DataGridView1.RowCount - 1 If IsNumeric(DataGridView1.Rows(r1).Cells(4).Value) Then Sumz = Sumz + DataGridView1.Rows(r1).Cells(4).Value Next txt_Write.WriteLine("SUM: " & Sumz) Sumz = 0 Next txt_Write.Close() txt_Write.Dispose() Str = "" Next ' MsgBox("stepEXIT") End If End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub End Class
de173 Δημοσ. 8 Σεπτεμβρίου 2012 Μέλος Δημοσ. 8 Σεπτεμβρίου 2012 Σε ευχαριστώ! Θα προσπαθήσω να μετατρέψω το πρόγραμμα ώστε να διαβάζω sql βάση...
Reselie-206 Δημοσ. 8 Σεπτεμβρίου 2012 Δημοσ. 8 Σεπτεμβρίου 2012 Σε ευχαριστώ! Θα προσπαθήσω να μετατρέψω το πρόγραμμα ώστε να διαβάζω sql βάση... Το δοκίμασες καθόλου? αυτό δε θέλεις να κάνεις ή δεν κατάλαβα εγώ καλά και έκανα οτι'ναναι πρόγραμμα? Microsoft SQL υποστηρίζει το visual studio αρα με τον ίδιο τροπο θα δουλέψει ακριβώς απλά θα συνδεθείς me sql αντι για access database...
de173 Δημοσ. 8 Σεπτεμβρίου 2012 Μέλος Δημοσ. 8 Σεπτεμβρίου 2012 Αυτό ακριβώς ήθελα.. Τώρα το συνδέω με SQL και επανέρχομαι με νεότερα... Ευχαριστώ!
MitsakosGR Δημοσ. 8 Σεπτεμβρίου 2012 Δημοσ. 8 Σεπτεμβρίου 2012 Εγώ θα σου πρότεινα την εξής λύση: Κάνεις ένα μόνο select που θα σου φέρει όλα τα δεδομένα σου ταξινομημένα με βάση τον κωδικό. Αρχίζεις να διαβάζεις το reader. Γράφεις τα στοιχεία στο αρχείο με όνομα τον κωδικό ενώ παράλληλα κρατάς και sum. Μόλις δεις οτι άλλαξε ο κωδικός γράφεις το sum στο προηγούμενο αρχείο και συνεχίζεις την διαδικασία για αυτό τον κωδικό. Πιστεύω ότι είναι πολύ πιο απλή λύση και χρησιμοποιεί λιγότερους πόρους στην βάση σου, στο δίκτυο και στον υπολογιστή σου. (Θα επανέλθω αργότερα με κώδικα).
de173 Δημοσ. 8 Σεπτεμβρίου 2012 Μέλος Δημοσ. 8 Σεπτεμβρίου 2012 Εγώ θα σου πρότεινα την εξής λύση: Κάνεις ένα μόνο select που θα σου φέρει όλα τα δεδομένα σου ταξινομημένα με βάση τον κωδικό. Αρχίζεις να διαβάζεις το reader. Γράφεις τα στοιχεία στο αρχείο με όνομα τον κωδικό ενώ παράλληλα κρατάς και sum. Μόλις δεις οτι άλλαξε ο κωδικός γράφεις το sum στο προηγούμενο αρχείο και συνεχίζεις την διαδικασία για αυτό τον κωδικό. Πιστεύω ότι είναι πολύ πιο απλή λύση και χρησιμοποιεί λιγότερους πόρους στην βάση σου, στο δίκτυο και στον υπολογιστή σου. (Θα επανέλθω αργότερα με κώδικα). Καλή και αυ΄τη η λογική του κώδικα. Θα ήταν αξιόλογο να δούμε και αυτή τη λύση! Πάλεψα το απόγευμα λίγο με το κώδικα του Reselie για να προσπαθήσω να δω τι κάνει.. (sorry αλλά είμαι πολύ newbie σε εφαρμογές vb net και συνδέσεις με βάσεις δεδομένων και εξαγωγές αρχείων..)
MitsakosGR Δημοσ. 9 Σεπτεμβρίου 2012 Δημοσ. 9 Σεπτεμβρίου 2012 (επεξεργασμένο) Συγνώμη για την καθυστέρηση. Ορίστε ο κώδικας, αύριο θα βάλω και τα σχόλια. Ο κωδικας χρειάζεται error handling και διάφορους ελέγχους για να είναι "πιο σωστός" αλλά έτσι θα καταλάβεις γενικα πως γίνεται. Χρησιμοποίησα MySQL σαν βάση δεδομένων. > Imports MySql.Data.MySqlClient Imports System.IO Module Module1 Sub Main() Dim file As StreamWriter = StreamWriter.Null 'Φτιάχνουμε το StreamWriter για εγγραφή σε αρχείο. Dim con As New MySqlConnection("Server=localhost;Database=testDB;Uid=USERNAME;Pwd=PASSWORD;charset=utf8")'Η σύνδεση με τη βάση MySQL Dim command As New MySqlCommand("SELECT id, code, data1, data2, data3, num1 FROM testdb.mytable ORDER BY code", con) 'To sql statement που θα μας φέρει τα δεδομένα con.Open()'Ανοίγουμε τη σύνδεση με τη βάση Dim dr As MySqlDataReader = command.ExecuteReader() 'Εκτελούμε το command σαν Reader Dim prevFile As String = String.Empty 'μεταβλητή που κρατάει το αρχείο που γράψαμε στο προηγούμενο loop Dim sum As Integer = 0 'Μεταβλητή που κρατάει τα επι μέρους αρθροίσματα While dr.Read() 'Όσο το reader έχει δεδομένα (γραμμές) If prevFile <> Convert.ToString(dr.GetValue(1)) Then'Εάν έχει αλλάξει ο κωδικός If prevFile <> String.Empty Then 'Αν ο προηγούμενος κωδικός δεν είναι String.Empty, δηλαδή η αρχική τιμή file.WriteLine(sum.ToString()) 'Γράψε το sum στο αρχείο file.Close() 'Το αρχείο δεν χρειάζεται πλέον οπότε το κλείνουμε End If prevFile = Convert.ToString(dr.GetValue(1)) 'αλλάζουμε το prevFile ώστε να δείχνει στον καινούργιο κωδικό. sum = Convert.ToInt32(dr.GetValue(5)) 'Αλλάζουμε την τιμή του sum στην πρώτη τιμή file = New StreamWriter(prevFile & ".txt", True) ' Ανολιγουμε ένα καινούργιο αρχείο με όνομα τον κωδικό Else'Εάν δεν έχει αλλάξει ο κωδικός sum += Convert.ToInt32(dr.GetValue(5))'Συνεχίζουμε το sum. End If 'Γράφουμε σε ένα String τα δεδομένα από τις στήλες της γραμμής που έχουμε διαβάσει Dim fileLine As String = Convert.ToString(dr.GetValue(0)) & ": " fileLine += Convert.ToString(dr.GetValue(1)) & ", " fileLine += Convert.ToString(dr.GetValue(2)) & ", " fileLine += Convert.ToString(dr.GetValue(3)) & ", " fileLine += Convert.ToString(dr.GetValue(4)) & ", " fileLine += Convert.ToString(dr.GetValue(5)) file.WriteLine(fileLine) 'Γράφουμε το string στο αρχείο End While 'Σε αυτό το σημείο δεν έχουμε άλλα δεδομένα αλλά δεν έχει γράψει το τελευταίο sum file.WriteLine(sum.ToString()) 'Γράφουμε το τελευταίο sum file.Close()'Κλείνουμε το αρχείο con.Close()'Κλείνουμε τη σύνδεση με τη βάση End Sub End Module Επεξ/σία 10 Σεπτεμβρίου 2012 από MitsakosGR 1
de173 Δημοσ. 10 Σεπτεμβρίου 2012 Μέλος Δημοσ. 10 Σεπτεμβρίου 2012 Συγνώμη για την καθυστέρηση. Ορίστε ο κώδικας, αύριο θα βάλω και τα σχόλια. Ο κωδικας χρειάζεται error handling και διάφορους ελέγχους για να είναι "πιο σωστός" αλλά έτσι θα καταλάβεις γενικα πως γίνεται. Χρησιμοποίησα MySQL σαν βάση δεδομένων. Το μετέτρεψα για βάση SQL αρκετά εύκολα. Σε ευχαριστώ πολύ για τα φώτα σου! Όποτε ευκαιρέσεις, θα ήταν πολύ καλό να είχαμε και τα σχόλιά σου, για να υπάρχει ένας κώδικας κατανοητός για τον οποιοδήποτε. Σας ευχαριστώ και τους δύο και πάλι!
de173 Δημοσ. 10 Σεπτεμβρίου 2012 Μέλος Δημοσ. 10 Σεπτεμβρίου 2012 Να ρωτήσω και κάτι πιο δύσκολο.. Πως μπορεί να μπει ναι μεν το σύνολο σε κάθε αρχείο στη τελευταία γραμμή αλλά να γραφτεί και διαφορετικη αιτιολογία δίπλα σε κάθε σύνολο. Δηλαδή για το πρώτη αρχείο να γράφει στη τελευταία γραμμή "Σύνολο κωδικού <code>: " <sum>
MitsakosGR Δημοσ. 10 Σεπτεμβρίου 2012 Δημοσ. 10 Σεπτεμβρίου 2012 Έβαλα τα σχόλια αλλά το formating το κάνει να φαίνεται λίγο χάλια. Για να βάλεις άλλα σχόλια στην τελευταία γραμμή του αρχείου αλλάζεις το > file.WriteLine(sum.ToString()) ώστε να γράψει ότι θέλεις εσύ. Για να κρατάς το code θα κάνεις ότι και με τον prevFile, απλά θα κρατάς τον κωδικό.
de173 Δημοσ. 10 Σεπτεμβρίου 2012 Μέλος Δημοσ. 10 Σεπτεμβρίου 2012 Πώς μπορεί να ορισθεί η κωδικοποίηση; Δηλαδή αυτή τη στιγμή δημιουργεί αρχείο ως UTF-8. Θα ήθελα να το αλλάξω σε windows-1253.
de173 Δημοσ. 11 Σεπτεμβρίου 2012 Μέλος Δημοσ. 11 Σεπτεμβρίου 2012 Πώς μπορεί να ορισθεί η κωδικοποίηση; Δηλαδή αυτή τη στιγμή δημιουργεί αρχείο ως UTF-8. Θα ήθελα να το αλλάξω σε windows-1253. Λύθηκε και αυτό.. Από (UTF-8) file = New StreamWriter(prevFile & ".txt", True) έγινε (ANSI) file = New StreamWriter(prevFile & ".txt", True, System.Text.Encoding.GetEncoding("Windows-1253")) Ευχαριστώ και πάλι!
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα