Définir fonction VBA vectorielle utilisable dans formules

Bonjour à tous,

Je cherche à définir une fonction VBA de nature vectorielle, que je puisse ensuite utiliser normalement dans des formules excel vectorielles.

Un peu à la manière de fonction excel DROITEREG qui à partir des données nécessaires à la régression, donne tout un ensemble de résultat sous la forme d'une matrice. On note de plus que la matrice résultats n'est pas complète ou rectangulaire selon le point de vue. C'est idéalement le même type de fonction que j'aimerais créer.

Ci-joint ma tentative qui ne fonctionne pas.

J'ai donné à la fonction le type Range. Mais l'affectation des résultats de sortie ne fonctionne pas.

Merci de votre airde

JPC

Donne lui le type variant et dans ton variant tu fous un tableau qui lui contiendra un range ...

Salut,

J'ai essayé de faire ce que tu m'as dit.

Je dois mal m'y prendre, car cela ne fonctionne toujours pas.

J'ai donné le type Variant à la fonction ("bruit_bilin").

J'ai déclarer un objet "Res" de type variant (mais je ne sait pas préciser qu'il s'agit de 6 cellules en ligne)

J'affecte les résultats sous la forme:

Res.Cells(1, 1).Value = m

Res.Cells(1, 6).Value = ...

et finalement:

bruit_bilin = Res

J'ai mis le fichier joint de mon essai, en calcul sur ordre pour faciliter le débug.

En debug, le programme s'arrête sur la première affectation de Res, sans aucun message d'erreur.

Merci de vos aides

JPC

Tu fais n'importe quoi oui.

Function bruit_bilin(Temp As Range) As Variant
'
'
'
    Dim Res(0 To 6)
    Dim T(25), Ti, dx As Double
    Dim dTA, VarA, dTB, VarB, Var As Double
    Dim STAr, dTAr, VarAr, STBr, dTBr, VarBr As Double
    Dim ST2, ST2A, ST2B, SiTA, SiTB, STA, STB As Double
    Dim Mm, Smm, mMp, Spp As Double
    Dim i, im, m, n, p, mr As Integer

    dx = Range("pas").Value / 60    ' pas de temps des donnés en minutes
    n = Temp.Count
    m = 3
    Mm = (m + 1) / 2
    Smm = (m - 1) * m * Mm / 6
    p = n - 3
    mMp = m + (p + 1) / 2
    Spp = (p - 1) * p * (p + 1) / 12

    STA = 0
    SiTA = 0
    ST2A = 0
    For i = 1 To m
        Ti = Temp.Cells(i, 1).Value
        T(i) = Ti
        STA = STA + Ti
        SiTA = SiTA + i * Ti
        ST2A = ST2A + Ti * Ti
    Next i
    STB = 0
    SiTB = 0
    ST2B = 0
    For i = m + 1 To n
        Ti = Temp.Cells(i, 1).Value
        T(i) = Ti
        STB = STB + Ti
        SiTB = SiTB + i * Ti
        ST2B = ST2B + Ti * Ti
    Next i

    mr = m
    STAr = STA                                          ' somme des Ti sur 1..m
    dTAr = SiTA - Mm * STA
    VarAr = ST2A - STA * STA / m - dTAr * dTAr / Smm
    STBr = STB                                          ' somme des Ti sur m+1..n
    dTBr = SiTB - mMp * STB
    VarBr = ST2B - STB * STB / p - dTBr * dTBr / Spp
    Var = VarAr + VarBr

    For m = 4 To n - 3
        Ti = T(m)
        STA = STA + Ti
        SiTA = SiTA + m * Ti
        ST2A = ST2A + Ti * Ti
        Mm = Mm + 0.5
        Smm = Smm + (m - 1) * m / 4
        dTA = SiTA - Mm * STA
        VarA = ST2A - STA * STA / m - dTA * dTA / Smm
        STB = STB - Ti
        SiTB = SiTB - m * Ti
        ST2B = ST2B - Ti * Ti
        mMp = mMp + 0.5
        Spp = Spp - (p - 1) * p / 4
        p = p - 1
        dTB = SiTB - mMp * STB
        VarB = ST2B - STB * STB / p - dTB * dTB / Spp
        If VarA + VarB < Var Then
            mr = m
            Var = VarA + VarB
            STAr = STA
            dTAr = dTA
            VarAr = VarA
            STBr = STB
            dTBr = dTB
            VarBr = VarB
        End If
    Next m

    m = mr
    Smm = (m - 1) * m * (m + 1) / 12
    Res(0) = m
    Res(1) = dTAr / Smm / dx
    Res(2) = Sqr(VarAr / (m - 2))
    p = n - m
    Spp = (p - 1) * p * (p + 1) / 12
    Res(3) = dTBr / Spp / dx
    Res(4) = Sqr(VarBr / (p - 2))

    Res(5) = 10 * Sqr(Var / (n - 2))

    bruit_bilin = Res

End Function

Salut,

Ca marche parfaitement. Super

Et c'est vrai que c'est infiniment plus logique.

En fait je faisais cela, car quand j'avais essayé de la même manière que ta solution de transmettre l'argument vectoriel de la fonction, cela ne fonctionnait pas, et j'ai réussi seulement en transmettant un objet Range.

En fait dans ma fonction je voulais récupérer le tableau T() directement comme argument de la fonction, et ensuite calculer sa taille pour l'affecté à n.

A savoir:

Function bruit_bilin(T() As Variant) As Variant

Mais l'appel de la fonction échoue. Je dois encore m'y prendre de travers.

Si tu as encore un peu de temps pour tes conseil avisée, merci.

JPC

Note: A titre d'infos, qui peut être serait utile à d'autres, la fonction que je développe effectue une sorte de double régression linéaire: Elle ajuste simultanément 2 droites de régression au mieux sur une jeu de donné à pas constant. L'approche est correcte statistiquement, et totalement généralisable. Elle donne:

cell 1: m le nombre de points optimum (au sens des moindre carrés pour la régression globale) pour la première droite de régression. (au mini 3)

cell 2: la pente de cette première droite

cell 3: erreur type de régression linéaire sur les m premier points

cell 4: la pente de la deuxième droite sur le reste des points

cell 5: erreur type de régression linéaire sur le reste des points

cell 6: erreur type de la régression globale (c'est à dire par une sorte de secteur angulaire)

Et que fais tu avec tes deux pentes ?

Tu projettes et donnes un intervalle ?

Généralement tes droites de régression formeront un angle, si cet angle est aigu il aurait mieux valu faire une droite régressive, si il est obtus ton intervalle sera de plus en plus grand.

J'ai un grand intérêt pour la question, dis m'en plus.

Je ne comprends pas comment fais tu une erreur type globale.

Pour répondre à ta question il suffit de mettre T as range

X as variant

x prend T

puis calculer ubound(x)

Voici quelques compléments

D'un point de vue statistique je considère les variables x comme précises et non entaché d'incertitudes. D'où une approche en moindre carré selon Y seulement.

Dans mon cas il s'agit d'un échantillonnage temporel à pas régulier (10s) dans le fichier.

Je construit un estimateur ou modèle constitué de 2 segments linéaire de réponse.

Je cherche le couple de segment qui minimise la somme des carrés entre la valeur mesuré et la valeur estimé par le modèle sur l'ensemble de l'intervalle.

Cet estimateur est un estimateur comme un autre (malgré une dimension discrète). Et on définit donc la plupart des grandeurs statistiques en remontant à leur définition, par exemple le coefficient de corrélation r² de la régression globale.

J'ai du faire tous les calculs théorique à la main (ce n'a pas été facile, il faut remonter aux concepts/définitions générales), car je n'ai rien trouvé de tel sur le net, et j'ai longuement cherché.

Pour l'estimation de l'erreur globale, il reste une question que je n'ai pas tranché, faut il diviser par n-2 ou n-4 la somme des carrés des résidus totaux avant de prendre la racine carré? Cela n'a que peu d'importance pour mon application. Intuitivement je penche pour n-4 (dans le prog il reste n-2), mais je n'ai pas pris le temps de faire la démonstration.

je me sert de cela pour analyser des signaux thermiques, avec deux objectifs:

1) Détecter des ruptures de pente révélateur d'un événement thermique (autre qu'une exponentielle croissante de chauffe ou décroissante de refroidissement, note un passage en log, supprimé dans le fichier, converti les exponentielle en droites). Il s'agit de détecter des changements de dynamique thermique.

2) Analyse du bruit (estimé par l'erreur type), en ayant ôter le signal normal pouvant contenir des changement de dynamique thermique brusque. Dans mon cas l'apparition de bruit après un changement de dynamique thermique est révélateur du phénomène que je cherche à détecter. Cette méthode (prenant en compte une description physique simple des phénomènes) est capable de détecter des changement révélateur de bruit sur événement en 2 à 4 minutes, avec un échantillonnage de 10s seulement.

(je dois détecter les phénomènes en moins de 5 min, et il faut que je sois raisonnable en calculs car l'automate qui devra faire au final les traitements aura plus de 200 signaux thermique à traiter en parallèles et en continue)

Une analyse spectrale par FFT, demande à la fois bien plus de calcul, mais surtout une profondeur d'analyse d'au moins 30 minutes pour sortir quelque chose de valable (le signal n'est périodique), et donc un retard de réponse prohibitif.

Pour la question excel/VBA,

cela marche, mais je ne comprend pas.

Function bruit_bilin(Temp As Range) As Variant

Dim T As Variant

T = Temp

Ti = T(i, 1)

Pourquoi T qui reçoit un objet Range devient un tableau à deux dimension ? et ne reste pas un objet Range ? et pourquoi pas une seule dimension?

Je suis extrêmement gêné par le fait de ne pas pouvoir/devoir déclarer T comme tableau.

(Note suis en ancien programmeur Fortran et Pascal, mais amateur en VBA)

A noter également que j'ai de gros Pb de temps de calcul avec mon fichier Excel.

Je simule mon outil d'analyse (qui comporte plusieurs autres types d’événement à détecté) sur 15 jours (par feuille de 3 jours) et 4 thermocouples. Cela donne par ex plus de 600000 appels à la fonction.

J'ai l'impression que dès que l'on fait appel à une fonction VBA, les calculs deviennent très lents.

Salut

JPC

2 minutes = 12 observations ... Ton estimateur sera très mauvais.

4 minutes = 24 observations ... Presque aussi mauvais.

Je ne me suis pas trop plongé sur la question... Mais tes calculs de variances avec des sommes m'interpellent. La variance a des propriétés qu'il ne faut pas simplifier. Il se peut que tes variables temps et température ne soient pas corrélées mais ceci m'interpellerait puisque sinon aucun intérêt de faire l'analyse.

Je n'arrive toujours pas à saisir l'intérêt... Puisque intuitivement...

"Chercher deux droites qui minimisent la somme des écarts au carré."

Reviendrait à en trouver deux superposées dans le cas où l'on trouve en relation entre notre X et notre Y et deux droites séparées dans le cas où il y ait deux distributions. Il faudrait donc diviser notre échantillon en deux et faire passer un MCO sur chacun d'entre eux.

Je ne dévalorise en rien ta modélisation qui sort des chantiers battus mais ne comprenant pas je creuse.

Bonjour,

une réponse courte est difficile.

Mon challenge est effectivement d'effectuer une analyse et de prendre une décision sur une profondeur de temps courte et avec trop peu de donnée (selon les usage statistique classique). je ne peux pas en pratique densifier les données (En théorie c'est possible, mais la pratique sur une installation industrielle lourde c'est autre chose). Le temps maxi de décision m'est également strictement imposé.

Lorsque j'ai programmé la solution ci-dessus, je n'aurait pas parié sur ces chance de fonctionner.

L'essai fait sur 6 jours de mesures est jusqu’à présent très encourageant.

J’interprète son bon fonctionnement au fait que j’enlève au mieux par mon modèle "binlinéaire" (à prendre au sens imagé, et non formel, car le modèle n'est pas bilinéaire, il est constituer de deux segments de droites) la physique nominale du phénomène, il me reste donc que le "bruit", et 24 valeurs pour estimer une erreur type n'est pas si catastrophique.

L'approche théorique faite ne ce limite en rien au nombre de points. Un collègue qui s'intéresse au domaine, n'a rien trouver à redire. Mais d'autres avis sont toujours bon à prendre.

Pb: Etude d'une variable quantitative X (dite variable explicative ou exogène) sur une autre variable quantitative Y ( dite variable expliqué ou endogène)

On a une expérimentation: n couples de valeurs (xi,yi).

Lorsque X est donné, les valeurs de Y se dispersent autour d'une "ligne moyenne" de réponse. L'idée est de chercher à représenter cette ligne moyenne au mieux par un modèle f. Idéalement:

E(Y|X=x)=f(x),

l'espérance de Y sachant X=x est le modèle cherché f(x).

on note ui= yi - f(xi), l'erreur résiduelle du modèle sur le jeu de point expérimentaux. Défini une nouvelle variable aléatoire U.

Le modèle que j'utilise est constitué de 2 segments de droites:

Sur les m premier points: f(xi)= a1 * xi + b1

sur les n-m suivants: f(xi)= a2 * xi + b2

le modèle dépends donc des 5 paramètres; m, a1, b1, a2, b2.

Que j'obtient par le méthode des moindre carrés en minimisant la somme des ui².

je note: mx1 la moyenne des xi sur le premier intervalle, et de la même manière mx2, my1, my2,

mx et my les moyennes sur l'ensemble des n.

L'objectif est d'établir l'équation de l'analyse de la variance.

Je saute les démonstrations (qui passe par montrer que E(U)=0, my1=f(mx1), my2=f(mx2) entre autre), mais j'obtient bien:

SCT= SCE + SCR,

SCT est la somme des carrés totales: Σ (yi-my)²

SCE est la somme des carrés expliquée: Σ (yi-f(xi))²

SCR est la somme résiduelle (des carrées des erreur résiduelle): Σ ui²

le coefficient de corrélation r² est par définition egal à SCE/SCT

l'erreur type est je pense égal à racine(SCR/(n-4)) (ne pas oublier que E(U)=0).

Je ne suis pas sur du facteur de division n-4, je ne me suis pas lancer dans cette partie de la démonstration. Car sans intérêt dans mon cas.

Une approximation est lié au fait que je passe en log pour trouver des droites, je ne minimise pas les carrées dans l'espace réel (x,y), mais dans l'espace transformé (x, ln(y)).

Les autres approches testés, pour évaluer l'augmentation de bruit associé à un type d’événement thermique particulier.

  • FFT: résultats catastrophiques sur si peu de points.
  • bruit par écart type sur séries des différences: encourageant, mais les événements thermiques sans augmentation de bruit sont confondu avec du bruit
  • erreur type sur une régression parabolique: du mieux (un peu moins d'erreur d'analyses, et parfois capacité à corrigé l'erreur avant le délai de 5 min), mais globalement même constat que précédemment

L’intérêt de cette régression "bilinéaire"... et bien c'est que cela semble bien fonctionner.

Les rupture de pentes liées à un changement de dynamique thermique (que cela soit accélération ou ralentissement du refroidissement), ne sont pas prise pour un bruit parasite.

Reste à passer l'épreuve de plusieurs mois d'enregistrement, et l'impact de la variabilités d'implantation des thermocouples.

Voila pour quelques explications complémentaires.

Si je pouvais avoir un petit mots sur mes interrogations VBA finale du message précédent. Merci.

En particulier si tu as des conseils pour accélérer le tout.

Ce que j'essaye de faire actuellement c'est de faire un seul appel à la fonction en utilisant les deux dimension en sortie, et en introduisant une boucle globale supplémentaires sur les lignes de la feuille dans la fonction. J'ai supposé que c'était les appels de fonction qui était pénalisant.

Salut

JPC

Je reste sceptique.

Mon ordinateur a mis 1m21sec pour lancer 600 000 fois ta fonction.

Si tu évites les 600 000 updates du screen tu devrais mieux t'en sortir..

Option Explicit
Function bruit_bilin(Temp As Range) As Variant
'
'
'
   Dim Res(0 To 6)
    Dim T(25), Ti, dx As Double
    Dim dTA, VarA, dTB, VarB, Var As Double
    Dim STAr, dTAr, VarAr, STBr, dTBr, VarBr As Double
    Dim ST2, ST2A, ST2B, SiTA, SiTB, STA, STB As Double
    Dim Mm, Smm, mMp, Spp As Double
    Dim i, im, m, n, p, mr As Integer

    dx = Range("pas").Value / 60    ' pas de temps des donnés en minutes
   n = Temp.Count
    m = 3
    Mm = (m + 1) / 2
    Smm = (m - 1) * m * Mm / 6
    p = n - 3
    mMp = m + (p + 1) / 2
    Spp = (p - 1) * p * (p + 1) / 12

    STA = 0
    SiTA = 0
    ST2A = 0
    For i = 1 To m
        Ti = Temp.Cells(i, 1).Value
        T(i) = Ti
        STA = STA + Ti
        SiTA = SiTA + i * Ti
        ST2A = ST2A + Ti * Ti
    Next i
    STB = 0
    SiTB = 0
    ST2B = 0
    For i = m + 1 To n
        Ti = Temp.Cells(i, 1).Value
        T(i) = Ti
        STB = STB + Ti
        SiTB = SiTB + i * Ti
        ST2B = ST2B + Ti * Ti
    Next i

    mr = m
    STAr = STA                                          ' somme des Ti sur 1..m
   dTAr = SiTA - Mm * STA
    VarAr = ST2A - STA * STA / m - dTAr * dTAr / Smm
    STBr = STB                                          ' somme des Ti sur m+1..n
   dTBr = SiTB - mMp * STB
    VarBr = ST2B - STB * STB / p - dTBr * dTBr / Spp
    Var = VarAr + VarBr

    For m = 4 To n - 3
        Ti = T(m)
        STA = STA + Ti
        SiTA = SiTA + m * Ti
        ST2A = ST2A + Ti * Ti
        Mm = Mm + 0.5
        Smm = Smm + (m - 1) * m / 4
        dTA = SiTA - Mm * STA
        VarA = ST2A - STA * STA / m - dTA * dTA / Smm
        STB = STB - Ti
        SiTB = SiTB - m * Ti
        ST2B = ST2B - Ti * Ti
        mMp = mMp + 0.5
        Spp = Spp - (p - 1) * p / 4
        p = p - 1
        dTB = SiTB - mMp * STB
        VarB = ST2B - STB * STB / p - dTB * dTB / Spp
        If VarA + VarB < Var Then
            mr = m
            Var = VarA + VarB
            STAr = STA
            dTAr = dTA
            VarAr = VarA
            STBr = STB
            dTBr = dTB
            VarBr = VarB
        End If
    Next m

    m = mr
    Smm = (m - 1) * m * (m + 1) / 12
    Res(0) = m
    Res(1) = dTAr / Smm / dx
    Res(2) = Sqr(VarAr / (m - 2))
    p = n - m
    Spp = (p - 1) * p * (p + 1) / 12
    Res(3) = dTBr / Spp / dx
    Res(4) = Sqr(VarBr / (p - 2))

    Res(5) = 10 * Sqr(Var / (n - 2))

    bruit_bilin = Res

End Function

Sub toto()
    Dim debut As Date, temps As Date, fin As Date, i As Double
    debut = Time
    For i = 1 To 600000
        Call bruit_bilin(Range("B2:B20"))
    Next i
    fin = Time
    temps = fin - debut
    MsgBox ("C'est fini !" & Chr(10) & "temps de traitement " & temps)
End Sub

Bonjour,

Les difficultés de temps de calculs sont bien réelles.

En fait je n'ai pas pu étendre l'utilisation de la fonction créer à ne serais ce qu'une feuille de calcul (3 jour, 4 températures. soit 4+25621 appels)

Excel (version 2003) à refuser de copier la fonction au delà de 65600 occurences. La fonction copy s'arrête sans messsage d'erreur.

J'ai donc modifier la fonction comme suit:

'------------------------------------------------ Macro enregistrée le 21/01/2014 par jpcescutti
Function Bruit_bilin(Temp As Range, last As Double) As Variant
'
    Dim Res(0 To nblg, 0 To 5) As Double
    Dim T As Variant

    Dim Modecalc As XlCalculation
    Dim Ti, dx, ab As Double
    Dim dTA, VarA, dTB, VarB, Var As Double
    Dim STAr, dTAr, VarAr, STBr, dTBr, VarBr As Double
    Dim ST2, ST2A, ST2B, SiTA, SiTB, STA, STB As Double
    Dim Mm, Smm, mMp, Spp As Double
    Dim lg As Integer
    Dim i, im, m, n, p, mr As Integer

    Application.ScreenUpdating = False
    Modecalc = Application.Calculation
    Application.Calculation = xlCalculationManual

    dx = Range("pas").Value / 60    ' pas de temps des donnés en minutes
    ab = Range("ab")
    n = 19

    T = Temp

    For lg = 0 To nblg

        m = 3
        Mm = (m + 1) / 2
        Smm = (m - 1) * m * Mm / 6
        p = n - 3
        mMp = m + (p + 1) / 2
        Spp = (p - 1) * p * (p + 1) / 12

        STA = 0
        SiTA = 0
        ST2A = 0
        For i = 1 To m
            Ti = Log(T(i + lg, 1))
            STA = STA + Ti
            SiTA = SiTA + i * Ti
            ST2A = ST2A + Ti * Ti
        Next i
        STB = 0
        SiTB = 0
        ST2B = 0
        For i = m + 1 To n
            Ti = Log(T(i + lg, 1))
            STB = STB + Ti
            SiTB = SiTB + i * Ti
            ST2B = ST2B + Ti * Ti
        Next i

        mr = m
        STAr = STA                                          ' somme des Ti sur 1..m
        dTAr = SiTA - Mm * STA
        VarAr = ST2A - STA * STA / m - dTAr * dTAr / Smm
        STBr = STB                                          ' somme des Ti sur m+1..n
        dTBr = SiTB - mMp * STB
        VarBr = ST2B - STB * STB / p - dTBr * dTBr / Spp
        Var = VarAr + VarBr

        For m = 4 To n - 3
            Ti = Log(T(lg + m, 1))
            STA = STA + Ti
            SiTA = SiTA + m * Ti
            ST2A = ST2A + Ti * Ti
            Mm = Mm + 0.5
            Smm = Smm + (m - 1) * m / 4
            dTA = SiTA - Mm * STA
            VarA = ST2A - STA * STA / m - dTA * dTA / Smm
            STB = STB - Ti
            SiTB = SiTB - m * Ti
            ST2B = ST2B - Ti * Ti
            mMp = mMp + 0.5
            Spp = Spp - (p - 1) * p / 4
            p = p - 1
            dTB = SiTB - mMp * STB
            VarB = ST2B - STB * STB / p - dTB * dTB / Spp
            If VarA + VarB < Var Then
                mr = m
                Var = VarA + VarB
                STAr = STA
                dTAr = dTA
                VarAr = VarA
                STBr = STB
                dTBr = dTB
                VarBr = VarB
            End If
        Next m

' la variance peux devenir négative par manque de précision de calcul numérique (elle doit être alors très faible de <1E-13)
        m = mr
        Smm = (m - 1) * m * (m + 1) / 12
        Res(lg, 0) = m
'        moyA = dTBr / m
        Res(lg, 1) = dTAr / Smm / dx
        Res(lg, 2) = Sqr(Abs(VarAr) / (m - 2))
        p = n - m
        Spp = (p - 1) * p * (p + 1) / 12
'        moyB = dTBr / p
        Res(lg, 3) = dTBr / Spp / dx
        Res(lg, 4) = Sqr(Abs(VarBr) / (p - 2))

        last = ab * 5000 * Sqr(Abs(Var) / (n - 4)) + (1 - ab) * last         ' facteur 5000 pour échelle graphique
        Res(lg, 5) = last

    Next lg

    Bruit_bilin = Res

    Application.ScreenUpdating = True
    Application.Calculation = Modecalc

End Function

L’utilisation de cette fonction (avec la forme ci-dessus) pour évaluer le bruit (par rapport à l'évaluation par écart type sur la série des différences, calculés à l'aide de formules excel) à environs triplé le temps de calcul.

Le volume des calculs fait pour détecté d'autres types d’événements, à l'aide de formules sur l'ensemble des feuilles est pourtant au moins 20 fois supérieur à celui de cette simple fonction.

Je ne peux malheureusement transmettre le fichier qui fait plus de 500 Mo, pour 6 feuilles de 3 jours.

Le fichier avec une seule feuille de données de 3 jours (et les éléments de graphique associé) fait encore 150 Mo non compressé et

43 Mo comprimée.

La structure du fichier excel est la suivante:

1 feuille de paramètre controllant les divers critères de détection d'évènement.

2 feuille de synthèse graphique de 3 jours, prévu pour impression A0. 6 graphiques de 12 heures. Une macro permet de choisir la feuille de donné à visualiser.

3 feuille avec un seil graphique détaillé (pour observation au niveau du détail des points au pas de 10s). Une macro permet de choisir les 18 h à visualiser.

ensuite pour chaque jeu de données de 3 jours:

  • une feuille de données et de calcul (25940 lignes, 77 colonnes)
  • une feuille avec un graphique incorporé de ces 3 jours (12 courbes à 25920 points) pour observation à l'écran

Je fait toujours très attention au fait qu'il n'y ait aucune actualisation de l'écran durant les calculs. De toute façons si il y en a, c'est clair il faut les interrompre, sinon le temps de réponse s'exprime en heures.

C'est un problème récurent que j'ai avec VBA. Les calculs sont toujours infiniment plus lent que si on peut les faire par des formules, même si celle ci sont complexe et peu optimiser en nb d'opérations. Alors qu'au contraire on aurait toutes les raisons d'être plus rapide avec l'écriture d'un code précis.

Si tu as quelques conseil ou liens pour m'aider,

merci beaucoup de temps consacré qui m'a réellement aidé.

JPC

Appelle des milliers de fois ta fonction depuis un sub... avec un application.screenupdating=false et il ne devrait pas y avoir de problemes... en effet l'appel de 600000 fois ta fonction ne dure qu'une minute et demie.. sachant que chaque fonction va écrire 6 cases. L'écriture de 3 millions 600000 données devrait prendre peut être 1 minute et moins si tu passes un tableau à un range. C'est sur que le recalcul de tes milliers de fonctions prendra un temps fou puisqu'il réactualisera les 600000 formules une par une..

Si tu me donnes un exemple réduit de ton utilisation je peux t'aider.

Bonjour,

Tu n'as pas bien compris les dernières modifications que j'ai faits:

Au début j'avais un appel à la fonction par ligne et par voie de température.

Quand je développe une solution, j'avance progressivement. Je travaille sur un fichier réduit (200Mo pour 2 feuilles de 3jours de données et ~3s de temps de calcul , au lieu de ~15s sur le fichier complet à 6 feuille de données et 500Mo; temps de calcul avec l'évaluation du bruit par écart type sur la série des différence, calculé avec des formules excel)

J'ai d'abord appliquer la nouvelle méthode d'évaluation du bruit sur un seul thermocouples, et une seule feuille de traitement des données du fichier réduit.

soit 25920 appels (1 par ligne), et constaté déjà un net impact, temps de calcul (alors qu'en terme de volume de calculs par rapport à tous le reste, l'impact est faible, peut être +5%)

Je n'ai pu étendre la formule aux 4 températures de la feuille car excel à refuser de copier l'appel à la fonction plus de ~65600 fois.

Compte tenu de l'arborescence des calculs, il était possible de modifier la fonction pour faire le calcul de toutes les lignes en un seul appel. C'est ce que j'ai fait.

Je n'ai donc maintenant que 4 appels à la fonction par feuille de calculs (1 par thermocouples), le calcul sur les lignes est devenu interne à la fonction. Le temps d'appel ne peut plus être en cause.

Sur le fichier réduit je passe de ~3 s de temps de calcul à ~15s.

Sur le fichier complet de ~15s à ~1min30.

Cela peut paraître raisonnable, mais lorsque tu développe, et cherche à déterminer si il existe un jeu de paramètre conduisant à un fonctionnement fiable et robuste de l’analyse, ces temps sont vite très pénibles.

Autant les calculs sous excel sont d'une efficacité raisonnable compte tenu de toute la couche logicielle nécessaire pour les traiter (l'efficacité est meilleure que en VBA), autant en mode macro VBA je ne comprend pas les raisons du manque d'efficacité.

J'ai fait une évaluation de l"efficacité, j'ai une perte d'un rapport proche de 100 ! par rapport à la puissance de calcul du processeur. C'est absolument anormal pour du code compilé.

Je n'ai pas réussi à produire un fichier suffisamment réduit, il fait encore 470 ko. (Il ne reste qu'une heure de données qu'il faut recopier sur 3j, toutes les formules sont à recopier sur l'ensemble du fichier, l'appel à la fonction vectorielle est à re-entrer sur la totalité des lignes, les graphiques sont à mettre à jour avec macro prévu)

je peux le transmettre par mail si tu me donne une adresse.

Si joint le fichier du principe utilisé, mais pas représentatif en calculs.

Merci si tu trouve un peu de temps pour m'éclairer.

Je rappelle que c'est un soucis que j'ai toujours eu avec les macro VBA de excel, cela viens peut être de ma manière d'utiliser les macros ou de paramètres/options d'excel ?

A+

JPC

Rechercher des sujets similaires à "definir fonction vba vectorielle utilisable formules"