Range VS Function..

Résolu
Bonjour,

J'ai un petit soucis... J'ai écrit une fonction qui retourne une plage:

Function plage(nb As Double) As Range

If nb = 10 Then

Set plage = Range("Plage_10")

ElseIf nb = 15 Then

Set plage = Plage_15

ElseIf nb = 20 Then

Set plage = Plage_20

End If

End Function

Celle-ci fonctionne je crois.

Néanmoins, j'aimerais l'utiliser pour la mettre dans une variable puis l'utiliser:

Sub choix_pallier()

pallier = InputBox("Choississez votre pallier: 10 / 15 / 20") 'pour choisir la table max

Do While pallier <> 10 And pallier <> 15 And pallier <> 20 'si erreur

MsgBox ("Entrée incorrecte")
pallier = InputBox("Choississez votre pallier: 10 / 15 / 20")

Loop

Set plage_calcul = plage(pallier) 'défini la plage de calcul

Range("plage_calcul").Select

ligneMin = plage_calcul.End(xlUp).Row
ligneMax = plage_calcul.End(xlDown).Row

End Sub

Je n'arrive cependant pas à la sélectionner (erreur 1004: méthode range a échoué). J'ai du mal à voir le soucis (à noter que j'ai déclarer les variables en haut du module, puisque j'ai différentes procédures/fonctions)

De même, j'ai un soucis avec mes variables ligneMin/Max, qui ne selectionnent pas ce que je souhaite. Là encore, je suis perdu...

Merci d'avance!

13 réponses

  1. Sans le code complet (déclarations de variables compris) c'est difficile de répondre.

    « Celle-ci fonctionne je crois. » : Je crois pas !
    Ces lignes ne doivent probablement pas fonctionner :
    Set plage = Plage_15
    Set plage = Plage_20

    « j'ai déclaré les variables en haut du module, puisque j'ai différentes procédures/fonctions » : A mon avis ce n'est pas une raison valable : ce qui est important c'est de définir les variables selon leur portée, limitée au strict nécessaire : procédure ou fonction, module, projet (classeur) ou projets (tous les classeurs). Voir :
    https://support.microsoft.com/fr-fr/help/462333

    Patrice
    1. Bonjour, tout d'abord, merci pour votre réponse

      Il y avait effectivement un soucis pour les plages (il me semblait que non, ayant fait des tests précédemment, mais...).
      Pour la déclaration, j'ai mis les variables en private (pour être sûr qu'elles soient dans le module entier) mais je ne peux toujours pas faire: Range("plage_calcul").select sans erreur

      Le principe du programme est le suivant: j'ai une feuille excel avec l'ensemble des tables de multiplications de 1 à 20. Je souhaite envoyer des inputbox avec des calculs. Au démarrage, on peut choisir une plage de calcul (10, 15 ou 20), c'est d'ailleurs là que se situent mes soucis comme: les variables "ligneMin" et "ligneMax" correspondent aux bornes de la plage (donc ligne des multiples de 1 jusqu'à la ligne des multiples de 10/15/20). La var ligneMax se trouvent être égal à 20... Ce qui n'est absolument pas logique (pour les multiples de 10, la ligne est 41).
      Enfin, ce qui n'est actuellement pas encore dans le programme, je compte colorer les cases répondues en rouge/vert mais le soucis n'est pas là.

      Voici le module (j'ai bien sûr rajouté les traits/tirets pour faciliter la lisibilité sur le site):

      A noter que les différentes plages (Tables, Plage_10...) sont des plages présentes sur la feuille excel que je n'ai donc pas eu à définir dans VBA

      Option Explicit

      Private pallier As Byte
      Private plage_calcul As Range
      Private ligneMin, ligneMax

      Private answer As Variant
      Private multi As Double, txt_multi As String
      Private cellquest As Range, cellrep As Range
      Private quest As String

      Private colonne As Double, ligne As Double

      Private feuilMulti As Worksheet

      ---------------------------------------------------------------------

      Sub calcul()

      Dim nb_base As Double, nb_multi As Double

      ActiveWorkbook.Sheets("Multiplications").Visible = True

      Set feuilMulti = Sheets("Multiplications")

      Range("Tables").Font.ColorIndex = 33 'réinitialise la couleur des tables en bleu

      Call choix_pallier

      Do

      nb_base = calcul_nb(pallier) 'calcul le nb à partir du pallier
      nb_multi = calcul_nb(pallier) 'idem

      txt_multi = nb_base & " x " & nb_multi

      ligne = 1
      colonne = 1

      Set cellquest = feuilMulti.Cells(ligne, colonne)

      Do Until quest = txt_multi

      For colonne = 1 To 15 Step 3

      For ligne = 1 To ligneMax

      Set cellquest = feuilMulti.Cells(ligne, colonne)
      quest = cellquest.Value

      Next ligne

      Next colonne

      Loop

      answer = InputBox(quest)

      Loop While answer <> "escape"

      ActiveWorkbook.Sheets("Multiplications").Visible = True
      ActiveWorkbook.Sheets("Multiplications").Activate

      End Sub

      --------------------------------------------------------------------------------

      Sub choix_pallier()

      pallier = InputBox("Choississez votre pallier: 10 / 15 / 20") 'pour choisir la table max

      Do While pallier <> 10 And pallier <> 15 And pallier <> 20 'si erreur

      MsgBox ("Entrée incorrecte")
      pallier = InputBox("Choississez votre pallier: 10 / 15 / 20")

      Loop

      Set plage_calcul = plage(pallier) 'défini la plage de calcul

      'Range("plage_calcul").Select

      ligneMin = plage_calcul.End(xlUp).Row
      ligneMax = plage_calcul.End(xlDown).Row

      End Sub

      --------------------------------------------------------------------------------

      Function plage(nb As Byte) As Range

      If nb = 10 Then

      Set plage = Range("Plage_10")

      ElseIf nb = 15 Then

      Set plage = Range("Plage_15")

      ElseIf nb = 20 Then

      Set plage = Range("Plage_20")

      End If

      End Function

      -------------------------------------------------------------------------------

      Function calcul_nb(nb As Byte) As Double

      If nb = 10 Then

      calcul_nb = Int(1 + Rnd * 10)

      ElseIf nb = 15 Then

      calcul_nb = Int(1 + Rnd * 15)

      ElseIf nb = 20 Then

      calcul_nb = Int(1 + Rnd * 20)

      End If

      End Function

      Merci d'avance
      1. C'est un problème de syntaxe :
        Range("plage_calcul").select sélectionne la "plage nommée" (la plage dont le nom est) plage_calcul
        et
        plage_calcul.select sélectionne la plage correspondant à la variable (range) dont le nom est plage_calcul

        Patrice
        1. Effectivement

          Mais qu'en est-il des var ligneMin et Max? Je ne comprends pas
          1. ligneMin = plage_calcul.Row
            ligneMax = ligneMin + plage_calcul.Rows - 1
        2. Contributeur
          Bonjour,

          Ca vaut vraiment le coup de faire une fonction pour la plage ?

          Set plage_calcul= Range("Plage_" & pallier) ne marche pas ?

          Même remarque pour calcul_nb()

          eric

          Jamais tu ne répondras à un mp non sollicité...
          Bon, ça c'est fait.
          1. Ah oui, effectivement Eric, ça allège grandement le programme. Je n'avais pas du tout pensé ainsi.

            Et Patrice, il s'est avérait que mon soucis venait du fait qu'il y avait des sauts de lignes dans mon tableau (pour gagner en lisibilité) ce qui coupait les plages et faussait ma ligneMax
            Néanmoins, les espaces maintenant retirés, j'ai encore un soucis...

            Mais avant, je vais vous expliquer comment se présente ma feuille (ce sera plus simple à visualiser):

            Il y a donc 20 tables en tout, toutes les 5 tables, je met les suivantes en dessous (plutôt que les mettre chacune à la suite ce qui rendrait la visualisation un peu embêtante)
            Ainsi: la plage (A1:N20) regroupe les tables de 1 à 5, (A1:N40) celles de 1 à 10 et ainsi de suite.

            Mon soucis est le suivant: quand bien même je définis les différentes plages (10: A1:N40; 15: A1:N60 et 25: A1:N80), lorsque je fais l'instruction suivante: "ligneMax = plage_calcul.end(xldown).row, je me retrouve toujours avec 80 alors que la plage est censée être Plage_10... donc ligneMax devrait rendre 40.

            Encore une fois, merci beaucoup pour votre aide qui m'est précieuse.
            1. Re,

              Je voudrais comprendre ce que tu veux faire exactement.
              D'après ce que je comprends :
              * demander le résultats de multiplications tirées au hasard parmi celles dont la réponse n'est pas validée définitivement en vert.
              * lorsque le résultat est correct :
              - si la question n'a pas été posée ou si sa réponse était erronée, valider provisoirement cette réponse en vert clair ;
              - si la réponse était déjà validée provisoirement, la valider définitivement (vert)
              * sinon si le résultat est erroné, le mémoriser en rouge.

              Il y a 3 niveaux de difficulté que j'ai du mal à cerner :
              pallier 10 : multiplications de 1x1 à 10x10 ou peut-être à 10x20 mais c'est pas très logique
              pallier 15 : multiplications de 1x1 à 15x15 ou peut-être à 15x20 ?
              pallier 20 : multiplications de 1x1 à 20x20

              Je ne sais pas quand est-ce qu'on s'arrête.

              A la fin du test on affiche le résultat

              Patrice
              1. C'est à peu près ça...

                Dans l'idée, je souhaite m'entraîner au calcul mental. Donc en clair, il n'y a pas d'arrêt (sauf si on écrit "escape").

                L'idée c'est qu'il y a 2 niveaux de vert: au deuxième niveau (définitif donc, vert foncé), ce calcul n'est plus proposé. Autrement, si c'est faux, le calcul devient rouge. Cela permet de ne pas avoir sans cesse les mêmes, mais de voir si on a bien la bonne réponse quand même

                Pour la difficulté: ce sont les tables de 1 à 10, 1 à 15 et 1 à 20. Ce qui, je vous l'accorde, n'est pas du tout bien représenté dans la disposition de l'ensemble des tables. Mais le calcul dépend des plages, du coup même si la disposition laisse à désirer, ce que je souhaite établir est quand même là.

                Et pour l'affichage du test à la fin, c'est juste un petit détail. Il s'avère que quand la réponse est fausse, le calcul est rouge ==> msgbox; donc si on écrit "escape" ==> msgbox. Mais ce n'est pas vraiment important
                1. Bonjour!

                  C'est très intéressant comme manière de procédé, il me faut du temps pour bien comprendre le procédé, mais au test, cela reprend convenablement ce que j'ai essayé de mettre en place

                  Je vous remercie encore une fois beaucoup pour la grande aide que vous m'avez apporté

                  Il ne me reste plus qu'à cliquer sur le bouton "Résolu"!