1. #1
    Candidat au Club
    Homme Profil pro
    Collaborateur comtpable
    Inscrit en
    août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Collaborateur comtpable

    Informations forums :
    Inscription : août 2017
    Messages : 6
    Points : 2
    Points
    2

    Par défaut Calcul de solde cumul et de numéro d'écriture (compta)

    Bonjour,

    J'ai une base .mdb dans laquelle se trouve la table Ecr correspondant aux écritures comptables dont les champs sont les suivants :
    DosQua, CodeJournal, Folio, PeriodeEcriture, JourEcriture, LigneFolio, Lib, Montant, NumUniq

    Afin de pouvoir calculer un solde cumulé et un numéro d'écriture, j'exporte NumUniq et Montant dans un fichier Excel par requete, le travail sous Access se révélant difficile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT NumUniq, Montant INTO [Excel 8.0;Database=FichierExcelSurBureau].[NumEcr] FROM Mvm ORDER BY DosQua, CodeJournal, Folio, PeriodeEcriture, JourEcriture, LigneFolio, Lib
    J'obtiens ainsi ce tableau (extrait de 15 lignes) pouvant contenir 95'000 lignes en fin d'exercice :
    NumUniq Montant
    20384 2392178,69
    20386 -2392178,69
    20388 9770,89
    20390 765,98
    20392 1188,2
    20394 -11725,07
    20396 8922,17
    20398 765,98
    20400 1018,45
    20402 -10706,6
    20404 8922,17
    20406 765,98
    20408 1018,45
    20410 -10706,6

    Je calcul ensuite le cumul et le numéro d'écriture, la première ligne portant le numéro 1, les lignes suivantes porteront ce numéro tant que le cumul de la ligne précédente est différent de 0.
    Lorsque la ligne précédente est égale à 0, la ligne actuelle correspond à une nouvelle écriture, le numéro est alors incrémenté. Nous obtenons ce résultat :
    NumUniq Montant Cumul Ecr
    20384 2392178,69 2392178,69 1
    20386 -2392178,69 0 1
    20388 9770,89 9770,89 2
    20390 765,98 10536,87 2
    20392 1188,2 11725,07 2
    20394 -11725,07 0 2
    20396 8922,17 8922,17 3
    20398 765,98 9688,15 3
    20400 1018,45 10706,6 3
    20402 -10706,6 0 3
    20404 8922,17 8922,17 4
    20406 765,98 9688,15 4
    20408 1018,45 10706,6 4
    20410 -10706,6 0 4

    Le problème est que la durée d'exécution est énorme, j'ai comparé la durée en lançant le traitement par VB.NET et par VBA et je suis choqué:
    Pour 27'626 lignes : VB.NET=3 min 36 / VBA= 1 sec
    Pour 58'220 lignes : VB.NET=9 min 20 / VBA= 5 sec

    Le code est le même :

    VB.NET
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    xlApp = New Excel.Application
    xlApp.DisplayAlerts = False
     
    OdbCnn.Close()
    wrbSrc = xlApp.Workbooks.Open(Filename:=strDsk & "\crn." & LCase(strDos) & "." & LCase(strAAA) & ".cpt.mvm.xls", UpdateLinks:=False)
    wrs = wrbSrc.Worksheets("NumEcr")
    wrs.Cells(1, 3).Value = "Cumul"
    wrs.Cells(1, 4).Value = "Ecr"
    ecr = 1
    For i = 2 To wrs.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row
        If i = 2 Then
            wrs.Cells(i, 3).Value = Math.Round(wrs.Cells(i, 2).Value, 2)
        Else
            wrs.Cells(i, 3).Value = Math.Round(wrs.Cells(i, 2).Value + wrs.Cells(i - 1, 3).Value, 2)
        End If
        If i > 2 Then
            If wrs.Cells(i - 1, 3).Value = 0 Then
                ecr = ecr + 1
            End If
        End If
        wrs.Cells(i, 4).Value = ecr
    Next
    wrbSrc.Close(SaveChanges:=True)
    xlApp.DisplayAlerts = True

    VBA
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    Set wrsVba = Worksheets("VBA")
    Set wrsCpr = Worksheets("Compar")
    datDeb = Time
    wrsVba.Cells(1, 3) = "Cumul"
    wrsVba.Cells(1, 4) = "NumEcr"
    ecr = 1
    For i = 2 To wrsVba.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row
        If i = 2 Then
            wrsVba.Cells(i, 3) = Round(wrsVba.Cells(i, 2), 2)
        Else
            wrsVba.Cells(i, 3) = Round(wrsVba.Cells(i, 2) + wrsVba.Cells(i - 1, 3), 2)
    End If
    If i > 2 And wrsVba.Cells(i - 1, 3) = 0 Then
        ecr = ecr + 1
    End If
    wrsVba.Cells(i, 4) = ecr
    Next i
    datFin = Time
    i = wrsCpr.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row + 1
    wrsCpr.Cells(i, 1) = "VBA"
    wrsCpr.Cells(i, 2) = Format(Now, "MM/dd/yyyy")
    wrsCpr.Cells(i, 3) = Format(datDeb, "HH:mm:ss")
    wrsCpr.Cells(i, 4) = Format(datFin, "HH:mm:ss")
    wrsCpr.Cells(i, 5) = Format(datFin - datDeb, "HH:mm:ss")
    Avez-vous une solution pour que la durée d'exécution sous VB.NET se rapproche sensiblement de celle sous VBA ?

    Je joins un fichier contenant les deux exemples avec le module VBA au cas où.

    Vous remerciant pour votre aide.
    Fichiers attachés Fichiers attachés

  2. #2
    Membre averti Avatar de joKED
    Profil pro
    dfgh
    Inscrit en
    février 2006
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : dfgh

    Informations forums :
    Inscription : février 2006
    Messages : 291
    Points : 346
    Points
    346

    Par défaut

    Salut,

    L'utilisation d'excel automation via .net est super lente comparativement à vba. C'est plus ou moins normal en fait. Pour simplifier, en vba, ton code et tes appels sont gérés directement par le moteur d'excel. Par contre, via .net, tu passes par des objets COM pour dialoguer avec excel, et ça a un coût assez lourd.
    Donc, il faut minimiser les appels à excel autant que possible, que ce soit en lecture ou écriture.

    Dans ton cas, as tu réellement besoin d'excel ? Tu indiques charger les données depuis une base Access pour remplir un fichier excel, relu par ton appli .net. Pourquoi ne pas charger tes données directement en mémoire dans ton appli .net ? Tu te passerais alors de tous les appels en lecture.
    Se pose ensuite la question de l'écriture. As tu besoin d'écrire dans un fichier excel ? Si oui, écrire dans un fichier csv (lisible par excel) pourrait il convenir ? Si un fichier excel est indispensable, je te conseille de te tourner vers des composants tiers (genre aspose.cells, ou autre) qui sont bien plus rapides pour l'écriture dans un fichier au format excel que de passer par de l'automation excel.

    TL;DR : passer par de l'automation excel sera toujours plus lent que d'utiliser vba. Essaye d'éliminer excel de l'équation.
    Tant va la cruche à l'eau qu'à la fin y'a plus d'eau.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 508
    Points : 1 352
    Points
    1 352

    Par défaut

    Bonjour,

    Citation Envoyé par joKED Voir le message
    . Essaye d'éliminer excel de l'équation.
    en passant par une bibliothèque externe, tel EPPlus, pas sur que tu reviennes au temps de vba, mais je serais surpris que tu depasses la minute....

    J@ck.
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  4. #4
    Candidat au Club
    Homme Profil pro
    Collaborateur comtpable
    Inscrit en
    août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Collaborateur comtpable

    Informations forums :
    Inscription : août 2017
    Messages : 6
    Points : 2
    Points
    2

    Par défaut

    Salut,

    Excel n'est en réalité nécessaire que pour l'export final des écritures après traitement dans requête OleDB, sans calcul de numéro de d'écriture, pour les 27 K lignes, le traitement dure 10 à 15 sec ce qui est correct.

    Je me suis tourné vers Excel pour la numérotation car j'avais tenté de le faire par requête et je n'y arrivais pas, je butais sur un SELECT INTO qui ne fonctionnais pas pour le calcul du solde cumulé, la requête sans INTO fonctionne mais la table n'est pas enregistrée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT NumUniq, (SELECT ROUND(SUM(f.Montant),2) FROM Ecr f WHERE f.NumUniq<=Ecr.NumUniq) AS Cumul
    FROM Ecr
    ORDER BY NumUniq;
    Je me suis donc tourné vers DataSet mais la durée de traitement fut de 5 min pour faire les 27 K updates
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    strSql = "SELECT NumUniq, Montant, Lib, Pièce FROM Mvm ORDER BY DosQua, CodeJournal, Folio, PeriodeEcriture, JourEcriture, LigneFolio, Lib"
    OdbDtA = New OleDbDataAdapter(strSql, OdbCnn)
    dSt = New DataSet()
    OdbDtA.Fill(dSt)
    OdbDtA.Dispose()
    dSt.Tables(0).Columns.Add("Cml", Type.GetType("System.Decimal"))
    dSt.Tables(0).Columns.Add("NumEcr", Type.GetType("System.Int64"))
    cml = 0
    Ecr = 1
    str = String.Empty
    For i = 0 To dSt.Tables(0).Rows.Count - 1
        cml += Math.Round(CDec(dSt.Tables(0).Rows(i).Item("Montant").ToString), 2)
        dSt.Tables(0).Rows(i).Item("Cml") = cml
        If i > 0 Then
            If CDec(dSt.Tables(0).Rows(i - 1).Item("Cml").ToString) = 0 Then
                Ecr += 1
            End If
        End If
        dSt.Tables(0).Rows(i).Item("NumEcr") = Ecr
        strSql = "UPDATE Mvm SET NumEcr=" & Ecr & " WHERE NumUniq=" & dSt.Tables(0).Rows(i).Item("NumUniq").ToString & ""
        OdbCmd = New OleDbCommand(strSql, OdbCnn)
        OdbCmd.ExecuteNonQuery()
    Next
    Là, je sèche

  5. #5
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 508
    Points : 1 352
    Points
    1 352

    Par défaut

    ah ok ! Je ferais mieux de lire les fils en entier avant de poster !

    Il faut que tu fasses de l'object . J'ai pas trop le temps là, mais dès que je trouve 15 minutes je te post un exemple.
    En gros tu pourrais partir sur 2 classes, une classe principale Ecritures (à changer à ta convenance) et une classe EcritureLigne.
    Ecritures serait composée d'un dictionnaire de lignes avec comme clé l'id de la ligne, d'une méthode Add de ligne et une méthode Process() qui parcoure ta liste ordonnée de ligne pour faire tes calculs de Ecr....

    Bon je sais si tu est familiarisé avec l'object ? si c'est le cas on va avancer plus vite

    J@ck.
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  6. #6
    Candidat au Club
    Homme Profil pro
    Collaborateur comtpable
    Inscrit en
    août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Collaborateur comtpable

    Informations forums :
    Inscription : août 2017
    Messages : 6
    Points : 2
    Points
    2

    Par défaut

    Je te dirai si je suis familiarisé avec l'object une fois après avoir pris connaissance de ce que tu proposes, étant comptable et n'ayant aucune formation en programmation

    Avec vos invitations à regarder les bibliothèques externes, je suis intéressé de passer par ExcelLibrary qui enregistre le DataSet dans un fichier .xls, ainsi je pourrai réimporter mes NumEcr dans la base .mdb et faire un update sur la table Mvm.
    Le calcul via DataSet ne prend qu'une sec pour les 27 K lignes.

    J'attends ta proposition, si cela me permet d'apprendre des méthodes, ce sera parfait !

  7. #7
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 508
    Points : 1 352
    Points
    1 352

    Par défaut

    oui enfin l'object s'apprend pas en un clin d'oeil, c'est plus un façon de penser qu'une solution technique.

    Je vais faire un truc que j'aime pas faire, je vais te livrer un bout de code qui marche tout seul =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
     
        public class Ligne
        {
            public int Id { get; private set; }
     
     
            public double Montant { get; private set; }
     
     
            public Ligne(int id, double value)
            {
                this.Id = id;
                this.Montant = value;
            }
        }
     
        public class Cumul
        {
            private SortedDictionary<int, Ligne> _dicLignes;
            private readonly int _idEcr;
     
     
            public IEnumerable<Ligne> Lignes
            {
                get { return this._dicLignes.Values; }
            }
     
     
            public int IdEcr
            {
                get { return this._idEcr; }
            }
     
     
            public double Montant
            {
                get
                {
                    return this._dicLignes.Values.Sum(l => l.Montant);
                }
            }
     
     
            public Cumul(int idEcr)
            {
                this._idEcr = idEcr;
                _dicLignes = new SortedDictionary<int, Ligne>();
            }
     
     
            public void Add(Ligne ligne)
            {
                if (this._dicLignes.ContainsKey(ligne.Id))
                    throw new Exception("Ligne déjà présente");
     
     
                _dicLignes.Add(ligne.Id, ligne);
            }
     
     
        }
     
     
        public class Ecritures
        {
            SortedDictionary<int, Ligne> _sdicLignes = new SortedDictionary<int, Ligne>();
     
     
            public double Montant
            {
                get
                {
                    return this._sdicLignes.Values.Sum(l => l.Montant);
                }
            }
     
     
            public void Add(Ligne ligne)
            {
                if (this._sdicLignes.ContainsKey(ligne.Id))
                    throw new Exception("Déja présente");
     
     
                this._sdicLignes.Add(ligne.Id, ligne);
            }
     
     
            public List<Cumul> GenererCumul()
            {
                List<Cumul> _lstCumul = new List<Cumul>();
                int iCumul = 1;
                Cumul cumulCurrent = null;
                foreach (Ligne l in this._sdicLignes.Values)
                {
                    if (cumulCurrent == null || cumulCurrent.Montant == 0)
                    {
                        //soit c'est le premier soit on doit changer de cumul
                        cumulCurrent = new Cumul(iCumul);
                        _lstCumul.Add(cumulCurrent);
                        iCumul++;
                    }
                    cumulCurrent.Add(l);
                }
                return _lstCumul;
            }
        }
     
    class Program
        {
            static void Main(string[] args)
            {
                Dictionary<int, double> _dico = new Dictionary<int, double>()
                {
                          {20384 , 2392178.69 },
                          {20386  , -2392178.69 },
                          {20388 ,  9770.89},
                          {20390  , 765.98},
                          {20392 ,  1188.2},
                          {20394 ,  -11725.07},
                          {20396  , 8922.17},
                          {20398  , 765.98},
                          {20400  , 1018.45},
                          {20402 ,  -10706.6},
                          {20404 ,  8922.17},
                          {20406  , 765.98},
                          {20408  , 1018.45},
                          {20410  , -10706.6}
                };
                //On affiche
                foreach (KeyValuePair<int, double> kvp in _dico)
                {
                    Console.WriteLine(kvp.Key + " -> " + kvp.Value);
                }
                //Pause
                Console.ReadKey();
                //On construit nos objects.
                Ecritures ecritures = new Ecritures();
                foreach (KeyValuePair<int, double> kvp in _dico)
                {
                    Ligne l = new Ligne(kvp.Key, kvp.Value);
                    ecritures.Add(l);
                }
                //Toutes les lignes sont dans Ecritures.
                //je vais générer les cumuls
                var lstCumul = ecritures.GenererCumul();
                foreach (Cumul c in lstCumul.OrderBy(c => c.IdEcr))
                {
                    foreach (Ligne l in c.Lignes)
                    {
                        Console.WriteLine(l.Id + " -> " + l.Montant + " -> " + c.IdEcr);
                    }
                }
                Console.ReadKey();
            }
        }
    Si tu exécute ça, alors tu verras en console que tu as bien tes numéros Ecr

    J'ai placé l'exemple des données que tu as fournit dans un dictionary, mais on pourrait les faire venir d'une bdd... l'exécution de ce genre de code est très très rapide, je serais surpris qu'on dépasse la seconde pour quelques dizaines de milliers d'objets lignes.... à tester donc !
    Par manque te temps je te livre ça en C# mais tu peux le convertir en VB.net avec ce genre d'outils
    C'est loin très loin d'être parfait et optimisé, donc tu calmes les puristes , mais ça a le mérite de te montrer la puissance de l'object

    je te livre ça un peu brutalement, hésite pas si tu as des questions,
    J@ck.
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  8. #8
    Candidat au Club
    Homme Profil pro
    Collaborateur comtpable
    Inscrit en
    août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Collaborateur comtpable

    Informations forums :
    Inscription : août 2017
    Messages : 6
    Points : 2
    Points
    2

    Par défaut

    C'est du costaud, je n'ai jamais touché les Class, que du Module Sub.

    J'enregistre le projet pour m'inciter à regarder de plus près cette approche mais là, c'est complexe pour mon niveau. Je te remercie pour cette découverte.

    Je vais me contenter du DataSet suivi d'un export au format xls et aspirer cet xls dans la mdb pour mettre à jour les numéro d'écriture.

    Par contre, curiosité oblige, une fois que tu as fait tourné Main() et que tu as les numéro dans c.IdEcr, comment les réinjecter dans la mdb ?

    Encore merci pour l'exemple, ca ne laisse pas indifférent comme approche d'écriture !

    Laurent.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 508
    Points : 1 352
    Points
    1 352

    Par défaut

    Citation Envoyé par laurentbql Voir le message
    Par contre, curiosité oblige, une fois que tu as fait tourné Main() et que tu as les numéro dans c.IdEcr, comment les réinjecter dans la mdb ?
    Pour le coup, si je devais le faire, j'aurais codé une couché d'accès aux données, qui à partir de paramètre (bon toi t'en a pas apparemment, ce serait le where de ta requête select) me fournis ma liste d'objet de départ, pour schématiser, ça revient à prendre ton bout de code avec ton Select, et au lieu de parcourir les lignes obtenues pour faire tes calculs, je remplirais une liste d'object, comme je le fais dans cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
                //On construit nos objects.
                Ecritures ecritures = new Ecritures();
                foreach (KeyValuePair<int, double> kvp in _dico) // en remplacant par quelques chose comme foreach(DataRow r in dataset.Tables[0].Rows)
                {
                    Ligne l = new Ligne(kvp.Key, kvp.Value);
                    ecritures.Add(l);
                }
    puis tu fais ce que tu as a faire avec tes objects ainsi créés.

    Puis je bouclerais à nouveau sur mes objets, pour les mettre à jour en bdd, par exemple avec des ordres insert ou udpate, avec la logique inverse au select, cad que là je lui fournit l'object, et la méthode réalise l'ordre sql.
    Dans ton cas il faudrait optimiser un peu, par exemple si tu as 20000 lignes à inserté on pourrait les regrouper...


    J@ck.
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  10. #10
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    novembre 2006
    Messages
    1 719
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : novembre 2006
    Messages : 1 719
    Points : 3 905
    Points
    3 905

    Par défaut

    Hello à vous tous,

    je ne reviens pas sur le bien fondé de se passer de l'automation Excel ou d'essayer d'améliorer le process, j'ai d'ailleurs lu la discussion complètement en diagonal car il y a déjà de très bonnes interventions mais si vous voulez exporter un nombre important de données dans Excel absolument par automation, passez par un tableau. Ce qui ralentit énormément Excel est le changement de cellule.

    Donc ça fait quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
                Dim arrObj(products.Count + 1, 3) As Object
     
                arrObj(0, 0) = "EAN"
                arrObj(0, 1) = "Demo"
                arrObj(0, 2) = "Percentage"
     
                For i = 0 To products.Count - 1
                   arrObj(i + 1, 0) =  products(i).EAN
                   arrObj(i + 1, 1) =  products(i).Demo
                   arrObj(i + 1, 2) =  products(i).Percent
                Next
     
                Dim rangeValue As Excel.Range = sheet.Range(sheet.Cells(1, 1), sheet.Cells(products.Count + 1, 3))
                rangeValue.NumberFormat = "@"
                rangeValue.Value = arrObj
    Vous passez ainsi de 8 minutes à quelques secondes.

  11. #11
    Candidat au Club
    Homme Profil pro
    Collaborateur comtpable
    Inscrit en
    août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Collaborateur comtpable

    Informations forums :
    Inscription : août 2017
    Messages : 6
    Points : 2
    Points
    2

    Par défaut

    Salut à tous,

    Je vais voir ce que je vais faire et je repasserai pour vous informer de la méthode mise en application.

    Laurent.

  12. #12
    Candidat au Club
    Homme Profil pro
    Collaborateur comtpable
    Inscrit en
    août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Collaborateur comtpable

    Informations forums :
    Inscription : août 2017
    Messages : 6
    Points : 2
    Points
    2

    Par défaut

    Salut, je suis arrivé à faire ce que je voulais même si la méthode ne sera pas top pour vous, il ne me reste plus qu'à faire un update pour affecter le numéro d'écriture dans mes mouvements.

    J'ai fait les calcul des numéro d'écriture dans le dataset comme décrit plus ahut en retravaillant les condition d'incrémentation de numéro, j'ai retranscris les résultats dans un csv pour enfin importer le csv dans la mdb.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    csv = New IO.StreamWriter(strDsk & "\tmp.csv", True, Text.Encoding.Default)
    csv.Write(dSt.Tables(0).Columns("NumUniq").ColumnName & "," & dSt.Tables(0).Columns("NumEcr").ColumnName)
    For Each row As DataRow In dSt.Tables(0).Rows
    csv.Write(csv.NewLine)
    csv.Write(row.Item("NumUniq").ToString & "," & row.Item("NumEcr").ToString)
    Next
    csv.Close()
     
    strSql = "SELECT * INTO [NumEcr] IN '" & strDsk & "\" & strTmp & "' FROM [Text;HDR=Yes;FMT=Delimited;DATABASE=" & strDsk & "\].[tmp.csv]"
    OdbCmd = New OleDbCommand(strSql, OdbCnn)
    OdbCmd.ExecuteNonQuery()
    If IO.File.Exists(strDsk & "\tmp.csv") Then IO.File.Delete(strDsk & "\tmp.csv")
    En tout cas, je vous remercie pour vos retours et votre aide !

    Laurent.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [v9][crystal] Calcul Du Total Cumule Avec La Variable Shared
    Par BOMBARDIER dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 31/07/2007, 20h47
  2. Calcul du solde de tout compte après la démission.
    Par Elvina dans le forum Démission
    Réponses: 2
    Dernier message: 05/06/2007, 20h41
  3. [8.5] formule solde cumul progressif
    Par speed0013 dans le forum Formules
    Réponses: 2
    Dernier message: 24/05/2007, 11h41
  4. Calcul de soldes provenant de données d'un bdd access
    Par ShortcutZ dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 16/08/2006, 20h23
  5. Requete SQl, calcul du solde d'un compte
    Par nerick dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 02/02/2006, 23h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo