Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα και πάλι!

 

Προσπαθώ να δημιουργήσω ένα πρόγραμμα εξαγωγής δεδομένων από μία SQL βάση και αποθήκευσής τους σε αρχεία. Το σενάριο είναι το παρακάτω:

 

Υπάρχει πίνακας ο οποίος περιέχει 5 στήλες και 1000 γραμμές. Μέσα σε αυτές τις γραμμές υπάρχει μία στήλη (Cod_Id) η οποία προσδιορίζει το είδος της γραμμής με έναν συγκεκριμένο κωδικό ο οποίος όμως κάθε φορά είναι άγνωστος. Κάθε φορά πρέπει να γίνεται ένα select distinct ώστε να μπορέσουμε να αναγνωρίσουμε ποιοι κωδικοί είναι καταχωρημένοι στο πίνακα.

 

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

 

Θα μπορούσε κάποιος να βοηθήσει;

 

Μέχρι στιγμής, με όσες προσπάθειες έχω κάνει, θεωρώ ότι ακολουθώ λάθος δρόμο... :(

 

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

Δημοσ.

Ας τα πάρουμε ένα ένα στη σειρα.

Έχεις φτιάξει το ερώτημα στην SQL για να σου φέρνει τα δεδομένα που θέλεις;

 

Το Select Distinct πώς θα σε βοηθήσει;;; Κάτι δεν καταλαβαίνω σωστά στην δομή του πίνακα ή χρειάζεσαι group by.

Άκυρο, το κατάλαβα. Γιατί να κάνεις πρώτα Select Distinct και μετά select για κάθε κωδικό και δεν κάνεις κατευθείαν group by;

Δημοσ.

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

 

Τουλάχιστον έτχι το έχω σκεφτεί.. Ως δύο διαφορετικά selects..

Δημοσ.

Πολύ πρόχειρα(σορρυ για τυχόν λάθη, απροσεξίες κτλπ απλά για παράδειγμα το έκανα και δε μπορώ να δουλέψω σοβαρά μιας και βρίσκομαι σε χώρο που δε μπορώ να ασχοληθώ ιδιαίτερα...λοιπές μεθόδους προστασίας και ελέγχου δεν έχω συμπεριλάβει...

 

Oυσιαστικά η ουσία είναι : κάνεις 1 σελέκτ τους κωδικούς...τους κρατάς σε πίνακα

κάνεις 2 σελέκτ μέσα σε loop ώστε για κάθε κωδικό να τραβήξεις τα λοιπά στοιχεία και μετά να τα περάσεις σε αρχείο (Filename & CoD_ID προτείνω για να είναι μοναδικός ο τίτλος αλλα και να ξεχωρίζει) .Υπολογίζω και τα αθροίσματα που θές λαμβάνοντας υπόψην το v3 column της access db που σου επισυνάπτω...

 

Δέ ξέρω σε τι βάση θα δουλέψεις αλλα όπως και να έχει η λογική δεν αλλάζει...

 

 

Το Δοκίμασα και λειτουργεί

Β) το path εξαγωγής των αρχείων είναι o C:\

γ)File.png 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

Δημοσ.

Σε ευχαριστώ! Θα προσπαθήσω να μετατρέψω το πρόγραμμα ώστε να διαβάζω sql βάση...

Δημοσ.

Σε ευχαριστώ! Θα προσπαθήσω να μετατρέψω το πρόγραμμα ώστε να διαβάζω sql βάση...

:-D

 

Το δοκίμασες καθόλου? αυτό δε θέλεις να κάνεις ή δεν κατάλαβα εγώ καλά και έκανα οτι'ναναι πρόγραμμα?

 

Microsoft SQL υποστηρίζει το visual studio αρα με τον ίδιο τροπο θα δουλέψει ακριβώς απλά θα συνδεθείς me sql αντι για access database...

Δημοσ.

Αυτό ακριβώς ήθελα.. Τώρα το συνδέω με SQL και επανέρχομαι με νεότερα... Ευχαριστώ!

Δημοσ.

Εγώ θα σου πρότεινα την εξής λύση:

Κάνεις ένα μόνο select που θα σου φέρει όλα τα δεδομένα σου ταξινομημένα με βάση τον κωδικό.

Αρχίζεις να διαβάζεις το reader.

Γράφεις τα στοιχεία στο αρχείο με όνομα τον κωδικό ενώ παράλληλα κρατάς και sum.

Μόλις δεις οτι άλλαξε ο κωδικός γράφεις το sum στο προηγούμενο αρχείο και συνεχίζεις την διαδικασία για αυτό τον κωδικό.

 

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

Δημοσ.

Εγώ θα σου πρότεινα την εξής λύση:

Κάνεις ένα μόνο select που θα σου φέρει όλα τα δεδομένα σου ταξινομημένα με βάση τον κωδικό.

Αρχίζεις να διαβάζεις το reader.

Γράφεις τα στοιχεία στο αρχείο με όνομα τον κωδικό ενώ παράλληλα κρατάς και sum.

Μόλις δεις οτι άλλαξε ο κωδικός γράφεις το sum στο προηγούμενο αρχείο και συνεχίζεις την διαδικασία για αυτό τον κωδικό.

 

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

Καλή και αυ΄τη η λογική του κώδικα. Θα ήταν αξιόλογο να δούμε και αυτή τη λύση!

 

Πάλεψα το απόγευμα λίγο με το κώδικα του Reselie για να προσπαθήσω να δω τι κάνει.. (sorry αλλά είμαι πολύ newbie σε εφαρμογές vb net και συνδέσεις με βάσεις δεδομένων και εξαγωγές αρχείων..)

Δημοσ. (επεξεργασμένο)

Συγνώμη για την καθυστέρηση.

Ορίστε ο κώδικας, αύριο θα βάλω και τα σχόλια. Ο κωδικας χρειάζεται 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


Επεξ/σία από MitsakosGR
  • Like 1
Δημοσ.

Συγνώμη για την καθυστέρηση.

Ορίστε ο κώδικας, αύριο θα βάλω και τα σχόλια. Ο κωδικας χρειάζεται error handling και διάφορους ελέγχους για να είναι "πιο σωστός" αλλά έτσι θα καταλάβεις γενικα πως γίνεται. Χρησιμοποίησα MySQL σαν βάση δεδομένων.

Το μετέτρεψα για βάση SQL αρκετά εύκολα.

Σε ευχαριστώ πολύ για τα φώτα σου!

Όποτε ευκαιρέσεις, θα ήταν πολύ καλό να είχαμε και τα σχόλιά σου, για να υπάρχει ένας κώδικας κατανοητός για τον οποιοδήποτε.

 

Σας ευχαριστώ και τους δύο και πάλι!

Δημοσ.

Να ρωτήσω και κάτι πιο δύσκολο.. Πως μπορεί να μπει ναι μεν το σύνολο σε κάθε αρχείο στη τελευταία γραμμή αλλά να γραφτεί και διαφορετικη αιτιολογία δίπλα σε κάθε σύνολο. Δηλαδή για το πρώτη αρχείο να γράφει στη τελευταία γραμμή "Σύνολο κωδικού <code>: " <sum>

Δημοσ.

Έβαλα τα σχόλια αλλά το formating το κάνει να φαίνεται λίγο χάλια.

 

Για να βάλεις άλλα σχόλια στην τελευταία γραμμή του αρχείου αλλάζεις το

>
file.WriteLine(sum.ToString())

ώστε να γράψει ότι θέλεις εσύ.

Για να κρατάς το code θα κάνεις ότι και με τον prevFile, απλά θα κρατάς τον κωδικό.

Δημοσ.

Πώς μπορεί να ορισθεί η κωδικοποίηση; Δηλαδή αυτή τη στιγμή δημιουργεί αρχείο ως UTF-8. Θα ήθελα να το αλλάξω σε windows-1253.

Δημοσ.

Πώς μπορεί να ορισθεί η κωδικοποίηση; Δηλαδή αυτή τη στιγμή δημιουργεί αρχείο ως 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"))

 

 

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

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...