Toon posts:

[C#] OpenFileDialog zorgt voor fouten in DataAdapter.Update

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste Tweakers,

Ik heb een Klasse die een CSV File parsed . Dit gebeurd aan de hand van een OpenFileDialog die vervolgens het bestand opent. in een DataAdapter stopt en vervolgens een DataTable met de inhoud teruggeeft.

Het stuk waar hij de OpenFileDialog opent en in een DataAdapter stopt

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            string location = "";
            DialogResult dr = excelBrowser.ShowDialog();
            if (dr == DialogResult.OK)
            {
                location = excelBrowser.FileName;
            }
            else
            {
                return null;
            }

            string full = Path.GetFullPath(location);
            string file = Path.GetFileName(full);
            string dir = Path.GetDirectoryName(full);

            csvConnection.ConnectionString = "Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + dir + "; Extended Properties = \"Text;HDR=NO;FMT=Delimited(;)\"";

            csvConnection.Open();

            csvAdapter = new OleDbDataAdapter(new OleDbCommand("SELECT * FROM " + file, csvConnection));


Dit gaat goed. Hij laad deze ook in en bind deze aan een DataGridView.

Vervolgens stop ik een aantal van deze regels in mijn eigen DataBase (Access). Klasse InternalDB.
Hierin staan alle adapters , dataset enz al gedefinieerd. (En werkt ook zoals het moet werken)

Maar doordat de OpenFileDialog gebruikt is . Werkt de DataAdapter.Update niet meer goed. Hij mist ineens kolommen en krijg bij de insert foutmeldingen dat Kolommen in de source terwijl die er wel degelijk zijn.

Exception : De instructie INSERT INTO bevat de volgende onbekende veldnaam: ArtikelColumn. Zorg ervoor dat u de naam correct hebt getypt en probeer het nogmaals.

Als ik nu de OpenFileDialog weghaal. een vast pad op geef. en hetzelfde doe. Dan werkt het wel goed en doet hij alles ook goed in de DB.

Voorbeeld

C#:
1
2
3
4
5
6
7
8
9
10
            string location = "Locatie CSV";
            string full = Path.GetFullPath(location);
            string file = Path.GetFileName(full);
            string dir = Path.GetDirectoryName(full);

            csvConnection.ConnectionString = "Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + dir + "; Extended Properties = \"Text;HDR=NO;FMT=Delimited(;)\"";

            csvConnection.Open();

            csvAdapter = new OleDbDataAdapter(new OleDbCommand("SELECT * FROM " + file, csvConnection));


Heeft iemand een idee hoe het kan dat een OpenFileDialog ervoor zorgt dat dit fout gaat.

Acties:
  • 0 Henk 'm!

Verwijderd

Het open file dialog staat eigenlijk los van eventuele connecties met jou database/csv bestand. Ik zou gewoon eens de beide strings naast elkaar houden (ik bedoel hiermee de manueel getypte string en die wat de fileDialog terug geeft)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
In beide situaties laad hij de CSV goed in en is de DataSource van de DataGridView ook goed. .
Beide keren is hij netjes gevuld. daarnaast heb ik de manuele tekst gekopieerd van de Console (waar ik de Filename naartoe geprint had) Dus lijkt me zelf sterk dat het aan de Filename ligt die ik terug krijg van de OpenFileDialog.

Maar zal er morgen nog verder naar kijken

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Even terugkomend op de string controleren. Heb het nogmaals gecontroleerd maar zoals verwacht zijn die gelijk. En dat lijkt me ook niet echt het probleem aangezien beide keren de CSV wordt ingeladen en aan de datasource van de DataGridView gekoppeld.

Enigste wat er wel fout gaat is zodra ik die FileOpenDialog gebruikt en ik druk op Importeer (Die vervolgens bepaalde regels in de DB zet) Dan gaat het met de DataAdapter.Update fout .
Als ik de FileOpenDialog weghaal . dan gaat het goed.

En ik snap. die 2 zouden niks met elkaar te maken moeten hebben.(FileOpenDialog en DataAdapter) maar op een of andere manier is dit toch het geval.

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Misschien een rare vraag, maar weet je de bestandsnaam nog wel op het moment dat je de connectie weer opent om de resultaten op te slaan. Met andere woorden, sla je ergens de locatie van het geselecteerde bestand op zodat je hem later opnieuw kunt gebruiken?

Je toont namelijk alleen maar het gedeelte waarbij je de data adapter opent voor lezen en dat gaat zoals je zelf aangeeft ook gewoon goed. Ik ben eigenlijk meer geïnteresseerd in de code welke je gebruik voor het opslaan van de data, want daar gaat het fout..

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Is nu laat maar zal morgen ook het stuk voor het opslaan posten. Ik zal nu wel alvast wat meer info geven over wat hij precies doet en dan morgen het codevoorbeeld erbij doen.

Klassen:

GUI - MDI waarbinnen all Forms geopent worden
CSVParser - Static klasse voor parsen CSV
InternalDB - Static klasse voor alle Database handelingen (Bevat dataset , adapter , relaties etc)
CSVImport - (Form) met de DataGridView
FieldSetter - (Form) om kollomnummers te koppelen aan een CSV van deze leverancier (Dit wordt opgeslagen in de DB. en bij het opslaan in deze form gaat het fout

Uitleg acties :

als het scherm geopent wordt voor het importeren van de CSV file wordt hierbij de methode aangeroepen in CSVParser die een CSV File parsed. De CSVParser zelf laat dan de OpenFileDialog zien. Na het kiezen parsed de CSVParser het bestand en geeft een DataTable terug met de data van de CSV file.

Dit wordt als DataSource gezet voor de DataGridView in CSVImport.
Daarna wordt FieldSetter geopent met de kolomnamen van de DataGridView in CSVImport. hiermee worden de kolommen gekoppeld aan de CSV file van een bepaalde leverancier.
Zodra men de kolommen wil opslaan gaat het fout.
Als de OpenFileDialog niet gebruikt wordt zal hij de gegevens goed opslaan.

Ik snap dat dit nu nog niks helpt in het oplossen en zal daarom de code ervan morgen posten zodat de tekst ook wat duidelijker is . maar samen met de code geeft het misschien wel een idee wat het moet doen en waar het misschien fout gaat.

En als reactie op het eerst punt van Niemand_Anders. Ik sla niks op in de CSV zelf. de enige plaats waar de locatie van de CSV file gebruikt wordt is de CSVParser zelf. de klasse InternalDB (voor database) heeft zijn eigen verbinding en die connectie string wordt niet anders.

Acties:
  • 0 Henk 'm!

  • PoweRoy
  • Registratie: April 2002
  • Laatst online: 20:47

PoweRoy

funky!

Ik vermoed toch dat er iets met de paden fout gaat.
string full = Path.GetFullPath(location);
string file = Path.GetFileName(full);
string dir = Path.GetDirectoryName(full);
probeer dit eens:
FileInfo fi = new FileInfo(location);
file is dan fi.Name
dir is dan fi.Directory

[This space is for rent]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
FileInfo of Path maakt niet uit . hetzelfde probleem blijft.

Maar zoals beloofd gister hier nog de aanvullende code.

Code in CSVImport die DataTable als DataSource van de DataGridView zet en Fieldsettings opent. (Dit gebeurd in de Constructor van CSVImport

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
            debcred = new BindingSource(InternalDB.CompleteDataSet, "DebCred");
            importvelden = new BindingSource(debcred, "LeverancierBijImport");

            //importCSV is methode in static class CSVParser. Deze geeft de inhoud van de CSV terug als DataTable
            DataTable imported = CSVParser.importCSV();
            if(imported == null){
                this.Close();
                return;
            }
            //DataSource zettem
            csvViewer.DataSource = imported;

           //Headertext wordt van elke kolom opgehaald in de DataGridView en meegegeven aan Fieldsettings


Dan wordt het form geopent om kolommen te koppelen. In de Constructor vul ik de Comboboxes met de headernames.En krijg ook de BindingSources debcred en importvelden meegeleverd.
Als er een leverancier gekozen is , wordt deze opgezocht in de BindingSource debcred en door de relatie wijst hij automatisch naar de eerste leverancier in de Import tabel(gekoppeld m.b.v. een relatie)

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            //Gekozen debiteur opzoeken. id = int met index van de gekozen DebCred
            debcred.Position = debcred.Find("Id",id);
            //Als er nog geen importlijst is. maak dan een nieuwe aan en zet de current op de goede positie
            if (importvelden.List.Count == 0)
            {
                importvelden.AddNew();
                importvelden.MoveLast();
            }
            //De DataBindings
            txtLeverancier.DataBindings.Add("Text",debcred,"Bedrijfsnaam");
            cmbNummer.DataBindings.Add("Text", importvelden, "ArtikelColumn");
            cmbNaam.DataBindings.Add("Text", importvelden, "NaamColumn");
            cmbOmschrijving.DataBindings.Add("Text", importvelden, "BeschrijvingColumn");
            cmbInkoopExBTW.DataBindings.Add("Text", importvelden, "InkExclColumn");
            cmbInkoopInclBTW.DataBindings.Add("Text", importvelden, "InkInclColumn");


En als laatste het opslaan

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
        private void cmdSetFields_Click(object sender, EventArgs e)
        {
            importvelden.EndEdit();
            //Roept methode in Static class InternalDB aan die weet wat hij moet updaten.
            InternalDB.updateData(InternalDB.DEBCREDIMPORT);
            //Koppelt de juiste columns aan de DataGridView
            CSVImport.defineFields(((DataRowView)importvelden.Current).Row);
            this.Close();
        }

        //Blokje wat InternalDB.updateData doet
        public static void updateData(int adaptertype)
        {
            try
            {
                connection.Open();
                switch (adaptertype)
                {
                    case DEBCREDIMPORT:
                        debcredimportAdapter.Update(completeDB.Tables["DebCredImport"].Select(null, null, DataViewRowState.Deleted));
                        debcredimportAdapter.Update(completeDB.Tables["DebCredImport"].Select(null, null, DataViewRowState.ModifiedCurrent));
                        debcredimportAdapter.Update(completeDB.Tables["DebCredImport"].Select(null, null, DataViewRowState.Added));
                        break;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + " " + e.StackTrace);
                Console.WriteLine(e.Message + " " + e.StackTrace);
            }
            finally
            {
                connection.Close();
            }
        }       


Ik hoop dat dit de extra code is die je zocht Niemand_Anders.

[ Voor 9% gewijzigd door Verwijderd op 15-04-2009 10:54 . Reden: wat echt onnodige code weggeknipt. Is het niet een hele lap. ]

Pagina: 1