Probleme temps d'acces - C#/.NET managed - Programmation
Marsh Posté le 06-07-2005 à 16:34:08
Tu as probablement une boucle infinie.
Tu es sûr du test (r.Value2 != null) ?
Je pencherais pour Null avec un N majuscule.
Tu devrais afficher le nombre de lignes et de colonnes dans la console pour être sûr qu'ils sont corrects.
Marsh Posté le 06-07-2005 à 18:10:09
Merci de répondre les gens mais la boucle n'est pas infini g fait le test je l'ai fais fonctionner mais ca dure 1min30.
Pour ce qui est de la taille du fichier Sihriel c'est un simple fichier excel de 1350ligne et une 50 de colonne rein d'énorme non plus mais en traitement c long!!!
Au début je faisais mes test avec un piti fichier excel ca marche tres bien.
Bref je suis toujours à ours d'idée la je suis parti dasn un truc d'importer le xls en csv poru essayer de le transformer plus rapidement mais g l'impression que ca seras moins propres que si j'arrrive à faire via excel direct 'fin bref je pense que mon pb viens de l'objet Cell car j'ai deja changé la boucle pour le nombre de ligne et c'est plus rapide en utilisant méthode get_Range si vous voulez voir le code. Y a plus qu' a demander...
Marsh Posté le 06-07-2005 à 18:21:50
Tu peux essayer d'ouvrir le fichier en tant que source de données (si c'est possible <-> les données sont homogènes) et de passer ta proc sur le datatable correspondant ?
Marsh Posté le 06-07-2005 à 18:43:12
bon attends je t'envoie le code car je crois que y a des incompréhension
c mon premier prog en c# , j'ai quelque mois de prog dans les dents donc g encore tout a apprendre c pour ca que j'explique assez mal ce que je veux faire...
J'ai un fichier Excel que je veux importer dans une base Access : Au début j'ai voulu attaquer par OleDb mon fichier Excel masi comme j'attaque ma base de donnée acces en meme temps en OleDb je me suis dit que je pouvais peut etre pas le faire (pas test) donc g pris les truc msdn pour "piloter" excel je suis partie dasn cette direction et ca a donnée ca :
using System;
using System.Data;
using System.Data.OleDb;
using System.Collections;
using System.Reflection;
using System.Messaging;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.ComponentModel;
public class Base_classe
{
private string name = null; //Nom de la base (fichier)
private string path = null; //Path du fichier
private string Err = null; //Permet de gérer les erreurs
private OleDbConnection objConnex; //permet de se connecter à la base
private OleDbDataAdapter objReq;
private OleDbDataReader objLire;//permet de lire la base de donnée
private OleDbCommand objCmd;
// constructeur nécessitant le path du fichier base de donnée Access
public Base_classe(string name)
{
this.name = name;
this.path = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+name;
}
// établie une connexion sur la base Access
public bool Open()
{
try
{
this.objConnex = new OleDbConnection(this.path);
this.objConnex.Open();
}
catch
{
this.objConnex = null;
MessageBox.Show("Erreur de connexion à la base de donnée" );
MessageBox.Show("Fermeture du programme" );
Environment.Exit(0);
return false;
}
return true;
}
// ferme la connexion à la base Access
public bool Close()
{
try
{
this.objConnex.Close();
return true;
}
catch
{
return false;
}
}
//le main
static void Main ()
{
//Déclaration de l'objet Missing ( appli ne suportant pas les valeurs null )
object Missing = System.Reflection.Missing.Value;
//-- inclure une demande du nom de fichier --
string fileName = "Ctest.xls";
/***-- Deb EXCEL --***/
//--Principe-- : On sauvegarde le tableau Excel dans un tableau double dimension
Excel._Application xlApp;
Excel._Workbook xlClasseur;
Excel._Worksheet xlFeuill1;
//Acces à l'application
xlApp = new Excel.Application();
xlApp.Visible = false; //soit disant ne pas faire apparaitre la feuille
//Acces au classeur
xlClasseur = xlApp.Workbooks.Open(fileName,
Missing,Missing,Missing, Missing, Missing, Missing, Missing,Missing,
Missing, Missing,Missing,Missing,Missing,Missing);
//Acces à la feuille
Excel.Sheets xlFeuilles = xlClasseur.Sheets;
xlFeuill1 = (Excel._Worksheet)xlFeuilles["?blabla?"]; //changer blabla par le nom de ta feuille
//On lit la feuille Excel une premiere fois pour connaitre la taille du tableau
int nb_col=1;
int nb_lign=1;
int a=1;
//On récupère le nombre de ligne
Excel.Range r = xlFeuill1.get_Range("A"+(a).ToString(),Missing);
while(r.Value2!=null)
{
nb_lign++;a++;
r = xlFeuill1.get_Range("A"+(a).ToString(),Missing);
}
a=1;
//On récupère le nombre de colonne
r = xlFeuill1.get_Range("A"+(a).ToString(),Missing);
while(r.Value2!=null)
{
nb_col++;
r = (Excel.Range)xlFeuill1.Cells[1,nb_col];
}
System.Console.WriteLine("testfini10, nb_ligne="+nb_lign +", nb_col"+nb_col );
System.Console.ReadLine();
//On créer le tableau qui contient la feuille Excel
object[,] info = new object[nb_lign,nb_col];
//r = xlFeuill1.get_Range("A"+(a).ToString(),Missing);
for (int i=1; i < nb_lign ; i++)
{ //ligne , colonne
for (int j=1; j < nb_col; j++)
{
r = (Excel.Range)xlFeuill1.Cells[i,j];
info[i,j] = r.Value2;
}
}
System.Console.WriteLine("testfini11" );
System.Console.ReadLine();
// Enregistre les modifs des cellules
xlClasseur.SaveAs("c:\\MyWorkbook.csv",
Excel.XlFileFormat.xlCSVWindows, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing);
// ferme le XLS
xlClasseur.Close(false, Missing, Missing) ;
// On met fin au pilotage
xlApp.Quit() ;
/***-- Fin EXCEL --***/
//Appel de la fonction Open()
Base_classe bas = new Base_classe("BaseBdm.mdb" );
bas.Open();
// Crée une instance dobjet DataAdapter.
OleDbDataAdapter objAdapt;
objAdapt = new OleDbDataAdapter("Select * From tDEf_Theme", bas.objConnex);
// Crée une instance dobjet DataSet et extrait
// les données à partir de la table voulu (ici tDEF_Theme).
DataSet DATA = new DataSet();
objAdapt.FillSchema(DATA, SchemaType.Source, "tDef_Theme" );
objAdapt.Fill(DATA,"tDef_Theme" );
// Crée une nouvelle instance dobjet DataTable.
DataTable tbl;
tbl = DATA.Tables["tDef_Theme"];
//Créer une instance d'objet DataRow
DataRow lign;
// Obtient un nouvel objet DataRow à partir de lobjet DataTable.
lign = tbl.NewRow();
// Définit les valeurs des champs de la ligne
lign["IDT_ThemeL1"] = "George";
lign["IDT_ThemeL2"] = "Johnson";
lign["IDT_ThemeL3"] = "Julie";
lign["IDT_ThemeL4"] = "Julie";
lign["boTheme1"] = 0;
// Place ce nouvel objet dans la méthode Add de l'objet DataTable.
tbl.Rows.Add(lign);
Console.WriteLine("Ajout terminé...\nAppuyez sur n'importe quelle touche pour continuer !\n" );
Console.ReadLine();
//Envoie des modification du DataSet
OleDbCommandBuilder objCommandBuilder = new OleDbCommandBuilder(objAdapt);
objAdapt.Update(DATA, "tDef_Theme" );
Console.WriteLine("Mise à jour de la base terminée...\nUtilisez l'explorateur pour voir les modifications" );
Console.ReadLine();
//Appel de la fonction Close()
bas.Close();
}
}
Marsh Posté le 06-07-2005 à 18:57:00
Anormal13 a écrit : bon attends je t'envoie le code car je crois que y a des incompréhension |
C'est comme ça que je l'avais compris (ou alors je comprends vraiment toujours pas ) ; je ne vois pas de problème à utiliser Ole pour Excel et Access (je viens de bosser sur ça moi aussi ). Essaie donc d'accéder à ton fichier excel de la même façon que tu accèdes à ta base access, ça devrait prendre moins de temps ...
Autre chose, je ne vois pas la partie import excel dans ton code, je l'ai ratée ou elle n'est pas encore là ?
A demain matin
Marsh Posté le 07-07-2005 à 09:57:13
Salut a toi mais la partie d'imlport de ma feuille excel dans mon tableau est la :
//On créer le tableau qui contient la feuille Excel
object[,] info = new object[nb_lign,nb_col];
//r = xlFeuill1.get_Range("A"+(a).ToString(),Missing);
for (int i=1; i < nb_lign ; i++)
{ //ligne , colonne
for (int j=1; j < nb_col; j++)
{
r = (Excel.Range)xlFeuill1.Cells[i,j];
info[i,j] = r.Value2;
}
}
System.Console.WriteLine("testfini11" );
System.Console.ReadLine();
Marsh Posté le 07-07-2005 à 09:57:37
ou alors je me trompe???
Marsh Posté le 07-07-2005 à 10:10:28
Là c'est moi qui me suis mal exprimé, c'est la partie migration des données vers Access que je ne trouvais pas. Une fois tes données importées tu ne les mets pas dans ta base, si ?
Tu as pu teste un import excel avec odbc/oledb sinon ?
Marsh Posté le 07-07-2005 à 11:50:12
Iop tout le monde,
heu ouais je test en ce moment la connection en OleDb de ma feuille Excel par contre g un big probleme comment je fais opour lire mon DataSet
je crois avoir fait l'importation de la feuille xls asn mon DataSet mais je vois pas commment on l'afffiche ou on récupere des valeurs...
DSN = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
FileName + ";Extended Properties=\"Excel 8.0;HDR=YES;ReadOnly=0;\"";
OleDbConnection cn = new OleDbConnection(DSN);
cn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [MAFEUILLE$]", cn);
cmd.CommandTimeout = 30;
OleDbDataAdapter myAdapter=new OleDbDataAdapter();
myAdapter.SelectCommand = cmd;
DataSet myDataSet= new DataSet();
myAdapter.Fill(myDataSet, "MAFEUILLE$" );
DataRow ligne = null ;
DataTable tbl;
tbl = myDataSet.Tables["EXPORTINEO$"];
int i = 0;
int nb_ligne_total ;
nb_ligne_total = 100;
Console.WriteLine(nb_ligne_total);
for(i=0;i<nb_ligne_total;i++)
{
ligne = myDataSet.Tables["EXPORTINEO$"].Rows[i];
Console.WriteLine(ligne.ToString());
Console.ReadLine();
}
Marsh Posté le 07-07-2005 à 11:50:45
Par contre g une erreur dans la boucle je comprend pas trop pourquoi ??
Marsh Posté le 07-07-2005 à 11:55:01
Première chose - est-ce que ton dataset est rempli ? Le code m'a l'air bon, si oui le plus dur est fait.
Pour la partie facile donc :
- nb_ligne_total = tbl.Rows.Count
- lire la datarow : propriété ItemArray de ta DataRow
Marsh Posté le 07-07-2005 à 11:57:28
Pour lire la table donc, méthode simple, tu crée une ArrayList et tu rajoutes l'ItemArray de chaque DataRow.
Si maintenant tu veux juste exporter dans Access, tu as les méthodes à ta disposition dans ADO.net pour envoyer un dataset directement dans une base.
Marsh Posté le 07-07-2005 à 12:10:27
J'avais sauté l'erreur de boucle : quelle exception tu as ?
Mets les 2 modifs que j'ai écrites et dis-moi si ça change quelque chose.
Marsh Posté le 07-07-2005 à 12:16:06
J'ai ca comme exception :
Une exception non gérée du type 'System.NullReferenceException' s'est produite dans Project1.exe
Informations supplémentaires : La référence d'objet n'est pas définie à une instance d'un objet.
Je te remercie pour la propriété , par copntre pour le remplissage du dataset il est normalement rempli vu que je tape sur un fichier excel et que je rempli mon dataset avec une feuille de mon classeur.
Piour ce qui est de importer dasn Aces le sfichiers xls sont assez mal foutu et ma base Acces est d'une certaine forme que je ne peux modifier c pourquoi je veux d'abord récuperer les valeur dans Excel avant de les implémenter dasn ACCESS
Marsh Posté le 07-07-2005 à 12:16:33
je vais test tes trucs
Marsh Posté le 07-07-2005 à 12:22:52
putin j'y arrrive pas arrrrrrgggggggh!!
je pete un cable en plus je suis malade ca me soule vener ce truc
Marsh Posté le 07-07-2005 à 12:29:15
j'ai plus d'erreu par contre ma ligne contient un objet que je n'arrive pas a afficher je sasi je m'exprime mal mais le voc en prog je l'ai pas du tout dsl pour mes explique de merde.
Mais si je fais ce code
for(int i=0; i<nb_ligne_total; i++)
{
ligne = tbl.Rows[i];
Console.WriteLine(ligne);
}
Marsh Posté le 07-07-2005 à 12:30:27
ca me revoit System.Data.Row sur la console pas cool.
J'ai pas compris le truc de l'Itemaray désolé masi un jour je pourais vraiment tenir une discution corect en programmation
Marsh Posté le 07-07-2005 à 12:31:14
Si tu es sûr que ton dataset est rempli et que les noms de tables sont exacts, fais un break/watch sur :
ligne = myDataSet.Tables["EXPORTINEO$"].Rows[i];
Regarde la valeur de myDataSet.Tables["EXPORTINEO$"].Rows.Count et dis ce qu'il renvoie.
Si ça plante avant, c'est que la table exportineo n'existe pas ; dans ce cas, fais un watch au niveau de myDataSet.Tables et regarde le nom des tables qui sont présentes.
Corrige le nom en fonction du résultat, si il n'y a aucune table c'est que l'import s'est mal déroule.
Marsh Posté le 07-07-2005 à 12:32:24
ok imerci je vasi test te dis ce que ca a donné
Marsh Posté le 07-07-2005 à 12:34:37
pour la valeur de myDataSet.Tables["EXPORTINEO"].Rows.Count ca renvoie 1328 c le nobre de ligne qui a contenu dasn le fichier donc c bon
Marsh Posté le 07-07-2005 à 12:34:45
au moin s juste pour ca
Marsh Posté le 07-07-2005 à 12:45:06
On a un attentat sur les lignes là, je reçois les messages 10 mins après que tu les ais postés ...
Remplace simplement :
Console.WriteLine(ligne);
par :
Console.WriteLine(ligne.ItemArray);
Si ça n'affiche que Array sur la console (je ne me souviens plus), tu devras afficher chaque élément séparément, et remplacer Console.WriteLine(ligne); par :
string contenuLigne = String.Empty;
for(int i = 0; i < ligne.ItemArray.Length; i++)
{
contenuLigne += ligne.ItemArray[i].ToString() + " ";
}
Console.WriteLine(contenuLigne);
Marsh Posté le 07-07-2005 à 14:32:08
Merci Sihriel la c'est bon par contre j'ai pas utilisé ta méthode mais si on fait
Console.WriteLine(ligne[a]) ou a représente le num de la colonne on a acces à la cellule qui s affiche corectement comme ca en plus g pas besoin de faire attention au format des cellules peut etre que je dis n'importe quoi mais est ce que tu es sur qu'avec ta méthode vu que contenueLigne c'est une string si tu met un format monétaire ou de nombre entier à l'interireur ca va donner quoi???
Marsh Posté le 07-07-2005 à 14:34:53
bref j'écris vraiment comme un sale gosse faut que je fasse attention pour ceux que ca interesse voici le code si par contre Sihriel t'as un truc contre le code je suis preneur pour toute remarque:
string FileName="test.xls"; //Nom du fichier
OleDbConnection cn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +FileName + ";Extended Properties=\"Excel 8.0;HDR=YES;ReadOnly=0;\"" );
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [EXPORTINEO$]", cn);
cmd.CommandTimeout = 30;
OleDbDataAdapter myAdapter=new OleDbDataAdapter();
myAdapter.SelectCommand = cmd;
DataSet myDataSet= new DataSet();
myAdapter.Fill(myDataSet, "EXPORTINEO" );
DataRow ligne = null ;
DataTable tbl = new DataTable();
tbl = myDataSet.Tables["EXPORTINEO"];
int nb_ligne_total ;
nb_ligne_total = tbl.Rows.Count;
Console.WriteLine(myDataSet.Table["EXPORTINEO"].Rows.Count);
Console.ReadLine();
for(int i=0; i<nb_ligne_total; i++)
{
ligne = tbl.Rows[i];
Console.WriteLine(ligne[0]);
}
Merci encore pour votre aide, de toute facon c'est loin d'etre terminé l'Anormal et ses questions connes!!!
Marsh Posté le 07-07-2005 à 14:53:21
Rien d'anormal pour moi, ça m'a l'air bon.
La raison pour laquelle j'ai créé contenuLigne était pour afficher l'ensemble des données contenu dans une ligne, et pas juste le premier élément. Tant que tu ne touches pas à des classes complexes, la fonction ToString() te renverras la valeur de ton objet sous forme d'une string, donc :
int i = 8; Console.WriteLine(i.ToString()); affichera "8"
Pareil pour les monétaires, pareil pour les date (attention aux dates sous excel, elles sont exposées sous forme de jours écoulés depuis 1900 ; si tu as besoin d'une fonction de conversion je t'envoie ça).
Le seul problème que tu risques de rencontrer se trouve au niveau des arrondis, mais tant que tu ne fais pas de calcul il n'y a aucun problème.
Content de voir que ça fonctionne en tout cas - ça donne quoi au niveau perf ?
Marsh Posté le 07-07-2005 à 15:06:51
niveau perf c 400 fois plus rapide un truc de ouf je m'attaque au traitement de l'importation mais pour etre encore plus fun g plein de doublon dans ma feuillle excel qui fo que je gere car ds ma base fo pas qu'y est de
doublon. Les base de données g commencé y a moinsd'une semaine et ca me soule deja
Marsh Posté le 07-07-2005 à 15:30:10
Les bases de données c'est le mal
Pour les doublons tu peux passer par une Hashtable, en mettant en clé la partie unique de chaque ligne et en vérifiant si la clé existe déjà avant d'insérer ta ligne dans la table.
Marsh Posté le 07-07-2005 à 15:33:51
le truc c que c pas un e ligne mais des cellules ou il y a des doublons un peu partout dasn le doc
Marsh Posté le 07-07-2005 à 16:06:17
En supposant que ta feuille excel soit comme ça :
1 X X X X X X X
2 X A X X X G X
3 X B X X X H X
4 X A X X X I X
5 X C X X X J X
6 X D X X X G X
Ce que tu veux dire, c'est que les lignes 4 et 6 sont invalides c'est ça ?
Marsh Posté le 07-07-2005 à 16:07:52
Non pire encore fo suposer que c'est comme ca :
1 XXXXXXXXX
2 SXXXXGXXX
3 DDDDDSCCC
4 HHHHHPMMM
en fait je dois mettre qu'un seul X , qu'un seul S
qu'un seul D etc....
Marsh Posté le 07-07-2005 à 17:43:12
nop pas moyen
je peux pas me permettre
j'avais pensé a exporter le fichieren csv eliminé les doublon spuis l'enregistrer sous xls et recommencer l'opération
Marsh Posté le 07-07-2005 à 17:57:56
Je voulais dire : à la main = codé mais sans pouvoir passer par une solution déjà faite.
Typiquement, dans la boucle, stocker les valeurs déjà présentes dans une table et vérifier que celle que tu lis n'est pas déjà présente.
Marsh Posté le 06-07-2005 à 15:12:44
Salut à tous v'la l'anormal et ses questions connes!!
Bon voila je developpe actuellement une petite application(peu mporte le but) pour mon appli j'ai besoin d'importer dans un tableaux deux dimensions une feuille Excel. Pour ce faire j'ai donc d'abbord une premirere phase qui compte le nombre de ligne ainsi de collonnes pour allouer mon tableau. Puis je rempli on tableau en fais ant une double boucle le probleme c'est que mon fichier Excel est assez gros et que cela met eu moins une minute pour que le tableau soit rempli, Hiiiiii pas bon du tout. Bref la question est de savoir si quelqu'un pourais regarder mon code et me dire si c'est çà cause de la taille du fichier que cela met autant de temps ou alors à cause des méthodes utilisés! Merci d'avance à tous ceux(ou toutes celles) qui pouront m'aider!!
Bref voici le code :
//--Principe-- : On sauvegarde le tableau Excel dans un tableau double dimension
Excel._Application xlApp;
Excel._Workbook xlClasseur;
Excel._Worksheet xlFeuill1;
//Acces à l'application
xlApp = new Excel.Application();
xlApp.Visible = false; //soit disant ne pas faire apparaitre la feuille
//Acces au classeur
xlClasseur = xlApp.Workbooks.Open(fileName,
Missing,Missing,Missing, Missing, Missing, Missing, Missing,Missing,
Missing, Missing,Missing,Missing,Missing,Missing);
//Acces à la feuille
Excel.Sheets xlFeuilles = xlClasseur.Sheets;
xlFeuill1 = (Excel._Worksheet)xlFeuilles["EXPORTINEO"];
//On lit la feuille Excel une premiere fois pour connaitre la taille du tableau
int nb_col=1;
int nb_lign=1;
//On récupère le nombre de ligne
Excel.Range r = (Excel.Range)xlFeuill1.Cells[1,1];
while(r.Value2!=null)
{
nb_lign++;
r = (Excel.Range)xlFeuill1.Cells[nb_lign,1];
}
//On récupère le nombre de colonne
r = (Excel.Range)xlFeuill1.Cells[1,1];
while(r.Value2!=null)
{
nb_col++;
r = (Excel.Range)xlFeuill1.Cells[1,nb_col];
}
//On créer le tableau qui contient la feuille Excel
object[,] info = new object[nb_lign,nb_col];
for (int i=1; i < nb_lign ; i++)
{ //ligne , colonne
for (int j=1; j < nb_col; j++)
{
r = (Excel.Range)xlFeuill1.Cells[i,j];
info[i,j] = r.Value2;
}
}
System.Console.WriteLine("testfini" );
System.Console.ReadLine();
---------------
Hihi j'suis là ou pas?