valeur d'une cellule située n'importe où dans une colonne

GUGUSSE2

XLDnaute Occasionnel
Bonjour,

Je n'ai trouvé nulle part sur le net la solution entière à mon problème (recherche de la fraction approchée à un nombre) :
Ma feuille de calcul effectue une série d'opérations (6 dans l'exemple) (nombre indéterminé dépendant du nombre de ligne "programmées").
Une fois le calcul terminé (plus de lignes de calcul), il faut choisir le "point d'arrêt" (choisir une valeur à écrire dans la case rose colonne D en face du nombre écrit colonne B). 16 dans l'exemple donné en pièce jointe.
Il faut ensuite faire les calculs "en remontant" jusqu'au premier résultat du calcul (B5) pour trouver les fractions successives.
J'ai trouvé une formule (en F3) qui me donne le N° de ligne de la case que j'ai utilisée.
Je veux, en D5, utiliser la valeur de la cellule où j'ai écrit (D11 en l’occurrence).
Pour mettre au point le programme, j'avais écrit la valeur en E3.

Comment récupérer la valeur de cette cellule ?

Pour la suite, j'avais écrit le nombre de ligne nécessaire, mais il faut que les calculs écrits colonne E puissent "couvrir" tous les cas.
Ils doivent se poursuivre (D5, D7, .... dépendant de l'endroit où se trouve la cellule "d'arrêt" colonne D)
tant que l'on ne fait pas référence à la cellule B5.

Comment "programmer" cet arrêt du calcul ?

Merci pour l'aide que vous pourrez m'apporter.
Cordialement,
GUGUSSE2.
 

Pièces jointes

  • Fractions continues.xlsx
    11.2 KB · Affichages: 13
Dernière édition:

Dranreb

XLDnaute Barbatruc
Bonjour.
Je joins ce classeur non pour une des raisons ordinaires pour lesquelles je le joins, mais parce qu'il possède un module MFraction dédié aux calculs de fractions approchées.
De fait la colonne "Expression VBA remarquable", feuille "Valeurs Excel" contient souvent une fraction obtenue par inversions successives de parties fractionnaire jusqu'à obtenir une fraction approchée ne pouvant, sur 52 bits, se distinguer du nombre analysé.
Si ce que vous voulez c'est une fraction strictement égale à la valeur codée, cette fonction la calcule, mais peut ne pas toujours la restituer clairement pour l'instant, si le numérateur ou le dénominateur s'exprime en plus de 15 chiffres décimaux.
VB:
Option Explicit
Private Numé As Double, Déno As Double, Term() As Double
Public Function Fraction(ByVal Nombre As Double) As String
   DévelopFract Nombre, 1
   AssembleFract
   Fraction = Numé & " / " & Déno
   End Function
Private Sub DévelopFract(ByVal Dde As Double, ByVal Dsr As Double, Optional ByVal PMax As Long = 40)
   Dim P As Long, QR As Double
   ReDim Term(1 To PMax) As Double
   For P = 1 To PMax
      QR = Int(Dde / Dsr): Term(P) = QR: QR = Dde - QR * Dsr: If QR = 0 Then Exit For
      Dde = Dsr: Dsr = QR: Next P
   If P < PMax Then ReDim Preserve Term(1 To P)
   End Sub
Private Sub AssembleFract(Optional ByVal P As Long = 40)
   Dim NvNu As Double
   P = LMin(UBound(Term), P): Numé = Term(P): Déno = 1
   While P > 1: P = P - 1: NvNu = Term(P) * Numé + Déno: Déno = Numé: Numé = NvNu: Wend
   End Sub
Function LMin(ByVal L1 As Long, ByVal L2 As Long) As Long
   LMin = (L1 - Abs(L1 - L2) + L2) \ 2
   End Function
Dans une cellule :
Code:
=Fraction(B3)
Affiche
884279719003555 / 281474976710656
 

Pièces jointes

  • ValeursExcelVsVBA.xlsm
    87.5 KB · Affichages: 11
Dernière édition:

GUGUSSE2

XLDnaute Occasionnel
Bonjour Dranreb,

Merci pour ta réponse, mais :
- En essayant de lire ton fichier, Excel à trouvé une erreur de compilation (voir P.J.).
Je ne sais pas si cela à de l'importance pour ma compréhension !
- Je n'ai pas compris l'utilité de cette présentation car je demandais comment utiliser la valeur d'une cellule à des fins d'adressage, un problème de syntaxe en somme !
- VBA vous parait peut-être la solution la mieux adaptée à mon problème, mais je ne connait pas suffisamment ce langage pour m'y mettre à mon age !
L'utilisation des fonctions "de base" d'Excel me suffisent dans bien des cas et je voulais arriver à surmonter cette difficulté sans recourir à la programmation.

Y a-t'il une solution à mon problème ?

Je viens de trouver une solution au problème :
comment récupérer la valeur contenue dans la cellule "D, N° de ligne contenu dans la cellule F3" :
=INDIRECT("D"&F3) !


Cordialement,
GUGUSSE2
 

Pièces jointes

  • erreur compilation.jpg
    erreur compilation.jpg
    192.7 KB · Affichages: 21
  • Erreur Excel.jpg
    Erreur Excel.jpg
    39.5 KB · Affichages: 22
Dernière édition:

Dranreb

XLDnaute Barbatruc
Enlevez le mot clé PtrSafe simplement s'il n'est pas supporté sur votre machine. Il n'est nécessaire que sur certaines versions tournant sur architecture 64 bits. Chez moi, il n'est pas nécessaire mais supporté, pas d'erreur de compilation. Pas de contenu illisible non plus.
Je n'ai aucune idée comment faire ce calcul avec des formules. Utilisez ma fonction Fraction c'est plus simple.
VB:
Option Explicit
Private Numé As Double, Déno As Double, Term() As Double
Public Function Fraction(ByVal Nombre As Double, Optional ByVal P As Long = 0) As String
Rem Arguments à spécifier :
'  Nombre: Le nombre à analyser
'  P : Le numéro de la dernière partie fractionnaire inversée à appliquer.
'      Facultatf: 0 assumé.
'      Si spécifié <=0 ou non spécifié: la fraction calculée est celle de plus petit dénominateur
'         dont la division effectuée a le même code Double que le nombre à analyser.
'      Si spécifié > nombre de parties fractionnaires inversées trouvées, une chaine vide est renvoyée.
   DévelopFract Nombre, 1
   If P <= 0 Then
      P = 0
      Do: P = P + 1: If P > UBound(Term) Then Exit Do
         AssembleFract P: Loop Until Numé / Déno = Nombre
   ElseIf P > UBound(Term) Then
      Fraction = "": Exit Function
   Else: AssembleFract P: End If
   Fraction = Numé & " / " & Déno
   End Function
Private Sub DévelopFract(ByVal Dde As Double, ByVal Dsr As Double, Optional ByVal PMax As Long = 40)
   Dim P As Long, QR As Double
   ReDim Term(1 To PMax) As Double
   For P = 1 To PMax
      QR = Int(Dde / Dsr): Term(P) = QR: QR = Dde - QR * Dsr: If QR = 0 Then Exit For
      Dde = Dsr: Dsr = QR: Next P
   If P < PMax Then ReDim Preserve Term(1 To P)
   End Sub
Private Sub AssembleFract(Optional ByVal P As Long = 40)
   Dim NvNu As Double
   P = LMin(UBound(Term), P): Numé = Term(P): Déno = 1
   While P > 1: P = P - 1: NvNu = Term(P) * Numé + Déno: Déno = Numé: Numé = NvNu: Wend
   End Sub
Function LMin(ByVal L1 As Long, ByVal L2 As Long) As Long
   LMin = (L1 - Abs(L1 - L2) + L2) \ 2
   End Function
 

Pièces jointes

  • Temp.xlsm
    22.1 KB · Affichages: 11
Dernière édition:

GUGUSSE2

XLDnaute Occasionnel
Bonsoir,

Je vais étudier ton fichier, plus tard à tête reposée !

J'ai un peu avancé sur mon problème et "en principe", j'ai la solution.
Mais avec le forma Excel pour les fraction (3 chiffres maxi), cela ne "marche" que jusqu'à un certain point :
si je mets "16" en cellule D11, j'ai le bon résultat (113/355), mais si je mets 292 en cellule D19, j'ai la même chose alors que manuellement, je trouve 103682/33003 !

Je regarde comment utiliser ton programme.

Cordialement,
GUGUSSE2
 

Pièces jointes

  • Fractions continues.xlsx
    80.6 KB · Affichages: 2

GUGUSSE2

XLDnaute Occasionnel
Il n'y a rien à lancer: c'est une fonction personnalisée écrite dans un module standard. Il n'y a qu'à l'utiliser dans des formules de cellules comme j'ai fait.
Oui, mais le temps que je décode le Visual Basic pour savoir ce que fait la fonction, il va couler beaucoup d'eau sous les ponts !
Peux-tu me dire ce que représente la colonne "D" ?

Cordialement,
GUGUSSE2
 

Dranreb

XLDnaute Barbatruc
Transmise en tant que second argument à la fonction Fraction, elle représente donc :
' P : Le numéro de la dernière partie fractionnaire inversée à appliquer.
Dans la lige 3 il est à 0, la fonction calcule donc
… celle de plus petit dénominateur
' dont la division effectuée a le même code Double que le nombre à analyser.
C'est expliqué en tête de fa fonction juste derrière l'instruction Function, pas besoin de chercher à comprendre comment elle marche.
 

Dranreb

XLDnaute Barbatruc
Il faudrait joindre le fichier pour que je puisse voir. Celui que j'ai joint au #4 marche, non ?
Remarque: pour implanter un module autre que d'objet Excel depuis un autre projet il suffit de glisser/déplacer son nom dans l'explorateur de projets.
Édition: Ah, il se peut que vous ayez spécifié en 2nd paramètre un nombre supérieur à celui des parties fractionnaires inversées trouvées. Dans ce cas elle renvoie pour l'instant une chaine vide.
 
Dernière édition:

GUGUSSE2

XLDnaute Occasionnel
Il faudrait joindre le fichier pour que je puisse voir. Celui que j'ai joint au #4 marche, non ?
Remarque: pour implanter un module autre que d'objet Excel depuis un autre projet il suffit de glisser/déplacer son nom dans l'explorateur de projets.
Édition: Ah, il se peut que vous ayez spécifié en 2nd paramètre un nombre supérieur à celui des parties fractionnaires inversées trouvées. Dans ce cas elle renvoie pour l'instant une chaine vide.
Salut,

Je ne comprends pas tout ce que tu me dis :
Dans ton fichier, si le crée une formule en utilisant les arguments que toi, j'ai un résultat (voir cellules G3, G5), mais si je mets d'autres arguments (voir G7),cela ne "marche pas" !
Je me pose les questions suivantes :
- quels arguments mettre dans la formule ?
- comment "placer" cette formule dans un autre classeur ?

Cordialement,
GUGUSSE2
 

Pièces jointes

  • fractions EXCEL.xlsm
    19.3 KB · Affichages: 2

Dranreb

XLDnaute Barbatruc
Curieux: en ouvrant le classeur je trouve juste les numérateurs dans les cellules portant les formules. Mais en les revalidant elle donnent bien le texte qu'elle devraient, le numérateur, un slash et le dénominateur.
Où est ce qu'il y a une formule qui calcule une fraction de la cellule G7 ?
Un autre classeur devrait être équipé du module contenant la Function s'il veut l'utiliser dans ses formules.
Encore une fois: Argument 1 la cellule portant la valeur à analyser, argument 2 la profondeur souhaitée, cellule ou valeur constante.
L'argument 2 est facultatif: si on ne le spécifie pas il assume la plus faible profondeur telle que la troncature du résultat de la division aboutit au même nombre que celui de départ.
Mettez des formats standards. La fonction ne renvoie pas un Double pouvant s'afficher avec un format de fraction, mais un String, c'est à dire du texte.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
C'est le nombre d'inverses de parties fractionnaires à considérer.
Enfin … +1 plutôt puisque =Fraction(PI();1) donne "3 / 1" donc il n'en considère aucune puisqu'il restitue une fraction ne valant que la partie entière. =Fraction(PI();2) renvoie "22 / 7" parce qu'il considère l'inverse de la 1ère partie fractionnaire trouvée soit 1/0,14159265358979 = 7,06251331 dont il ne considère que le 7 entier (vu que sa propre partie fractionnaire est la 2nde à inverser trouvée et ainsi de suite), or 3 / 1 + 1 / 7 = 21 / 7 + 1 / 7 = 22 / 7. C'est le même calcul que celui que vous aviez fait, non ?
Et =Fraction(PI()) sans profondeur donne "245850922 / 78256779" parce que c'est la fraction de plus basse profondeur codée comme PI(). En effet la formule =245850922/78256779=PI() renvoie VRAI parce que les valeurs des deux expressions aboutissent au même code Double +&H1,921FB54442D18 × 2^+&H001, valant 884279719003555 / 2^48 soit 3,141592653589793115997963468544185161590576171875
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Bonjour.
Tien, on dirait qu'on a besoin de moins de termes en prenant plutôt les arrondis des inverses de parties fractionnaires.
Je documente aussi les procédure utilisées dans cette réécriture du module, au cas où vous souhaiteriez changer des détails dans la fonction :
VB:
Option Explicit
Rem. Des Double sont utilisés dans ce module pour des entiers pouvant dépasser la capacité d'un Long.
Function Fraction(ByVal Nombre As Double, Optional ByVal P As Long = 0) As String
Rem. Renvoie le texte d'une fraction approchée d'un nombre.
'  Argument à transmettre :
'     Nombre: Le nombre à analyser
'     P : Le nombre de termes à employer (partie entière puis arrondis d'inverses des parties fractionnaires successives).
'        Facultatf: 0 assumé.
'        Si spécifié <=0 ou non spécifié: la fraction calculée est celle de plus petit dénominateur
'           dont la division effectuée a le même code Double que le nombre analysé.
'        Si spécifié > nombre de termes trouvés, une chaine vide est renvoyée.
   Dim TIPF() As Double, Numé As Double, Déno As Double ' Bien qu'entiers peuvent dépasser la capacité d'un Long
   DévelopFract TIPF, Nombre
   If P <= 0 Then
      P = 0
      Do: P = P + 1: If P > UBound(TIPF) Then Exit Do
         AssembleFract Numé, Déno, TIPF, P: Loop Until CDbl(Numé) / CDbl(Déno) = Nombre
   ElseIf P > UBound(TIPF) Then
      Fraction = "": Exit Function
   Else: AssembleFract Numé, Déno, TIPF, P: End If
   Fraction = Numé & " / " & Déno
   End Function
Sub DévelopFract(TIPF() As Double, ByVal Dde As Double, Optional ByVal Dsr As Double = 1, Optional ByVal PMax As Long = 40)
Rem. Calcule une liste de valeurs arrondies d'inverses de parties fractionnaires d'un nombre ou d'un rapport de nombres.
'  Argument à transmettre :
'     TIPF: La liste à initialiser des Inverses de Parties Fractionnaires (ou plutôt de leurs valeurs arrondies).
'     Dde: Le nombre ou le dividende du rapport.
'     Dsr: Le diviseur. Facultatif: 1 assumé.
'     PMax: Le nombre maximum d'IPF souhaitées. Facultatif: 40 assumé.
'  Remarque: Au final la liste TIPF ne sera au plus dimensionnée qu'au nombre d'IPF effectivement trouvées.
   Dim P As Long, QR As Double
   ReDim TIPF(1 To PMax) As Double
   For P = 1 To PMax
      QR = Int(Dde / Dsr + 0.5): TIPF(P) = QR: QR = Dde - QR * Dsr: If QR = 0 Then Exit For
      Dde = Dsr: Dsr = QR: Next P
   If P < PMax Then ReDim Preserve TIPF(1 To P)
   End Sub
Sub AssembleFract(ByRef Numé As Double, ByRef Déno As Double, TIPF() As Double, Optional ByVal P As Long = 40)
Rem. Calcule un numérateur et un dénominateur à partir d'une liste de valeur arrondies d'inverses de parties fractionnaires.
'  Argument à transmettre :
'     Numé: Numérateur à calculer
'     Déno: Dénominateur à calculer
'     TIPF: Liste des inverses des arrondis d'inverses de parties fractionnaires à appliquer.
'     P: Indice maximum de la dernière IPF à employer (en premier). Ramené à la dimension du tableau si spécifié supérieur.
   Dim Nu As Double, Dé As Double, NNu As Double
   If P > UBound(TIPF) Then P = UBound(TIPF)
   Nu = TIPF(P): Dé = 1
   While P > 1: P = P - 1: NNu = TIPF(P) * Nu + Dé: Dé = Nu: Nu = NNu: Wend
   Numé = Nu * Sgn(Dé): Déno = Abs(Dé)
   End Sub
 

Discussions similaires