Comparaison des valeurs d'un tableau entre elles

Bonjour tt le monde,

Quelqu'un connaîtrait une astuce pour comparer les valeurs d'un même tableau entre elles ?

Dans le fichier ci-joint par exemple, je voudrais définir le nombre de noms différents qu'il y'a dans le tableau

14test.xlsx (8.76 Ko)

Merci d'avance

Bonjour,

Essayez avec la formule suivante :

=SOMMEPROD(1/NB.SI(A1:A52;A1:A52))

Voici le fichier

13test.xlsx (10.99 Ko)

Et joyeux Noel !!!

Cdlt,

Bonjour 3GB,

Merci bcp mais enfaite c'est pour VBA et pas pour Excel j'ai oublié de le mentionner :p

bonne journée

Bonjour,

Oui, comme vous avez joint un fichier xlsx en plus, j'ai pensé que c'était un problème de formule excel.

Mais que voulez-vous ? Une fonction personnalisée ? Un autre essai :

Function NBUNIQUE(Plage As Range)

Set dico = CreateObject("Scripting.Dictionary")

For Each cell In Plage.Value
    If cell <> "" Then dico(cell) = ""
Next cell

NBUNIQUE = dico.count

End Function

Cdlt,

bonjour

en cadeau de Noel , au cas zou malencontreusement ,il y ait des vides

=SOMMEPROD(SIERREUR(1/NB.SI(A1:A52;A1:A52);""))
matricielle à valider avec les 3 doigts de rigueur 

cordialement

Bonjour tulipe_4,

Merci mais enfaite j'ai oublié de mentionner que c'était pour VBA et pas pour EXCEL

bonne soirée

Bonsoir 3GB,

Merci pour la réponse, est-ce que se serait possible de le faire sans forcément créer une fonction, j'utilise en classe que la procédure SUB

Merci d'avance

Bonjour usanas,

J'aimerais bien vous aider davantage mais si je fais une nouvelle proposition, vous me répondrez "Merci mais en fait, c'est pas vraiment ça qu'il me faut parce que...". J'aime bien jouer aux devinettes, mais si vous exprimez clairement votre besoin plutôt que ce qui ne vous convient pas, je pense que ce sera plus simple.

De toute façon, vous avez tout ce que vous avez demandé. La différence entre une sub et une function, c'est que la function doit retourner une valeur. Or, ce que vous cherchez, c'est une valeur (celui du nombre de valeurs différentes d'une plage). A la place d'une fonction (qu'on peut tout à fait utiliser dans une procédure), vous renvoyez le résultat dans une variable ou dans une cellule et le tour est joué. N'ayant aucune informations précises, je ne peux qu'adapter le code, pour l'exemple :

Sub nbunique()

dim dico as object
dim plage as range
dim nbunique&

Set dico = CreateObject("Scripting.Dictionary")
set plage = sheets("nomfeuille").range("refplage") '<<< ADAPTER REFS (plage à examiner)

For Each cell In Plage
    If cell <> "" Then dico(cell) = ""
Next cell

'ex 1 - avec variable
nbunique = dico.count 'on passe par une variable
Sheets("nomfeuille").range("cellrenvoi").value = nbunique 'cellrenvoi affiche la valeur de nbunique
'ex 2 - directement sur feuille
Sheets("nomfeuille").range("cellrenvoi").value = dico.count

End sub

Cdlt,

Bonsoir 3GB,

Merci beaucoup, voici de quoi il s'agit, c'est la 4 ème question de cet exercice, le code ci joint est la correction de la prof, mais je n'ai pas compris le passage que j'ai décalé vers la droite ( if k=nbentre) lors du calcul du nombre d'entreprises différentes ( les entreprises sont rangées dans le tableau code_entreprise(i) et y'en a bcp qu'ont le mm noms, pour cela je voulais savoir si y'avait une méthode plus claire :

Dim date1(1000) As Integer
Dim code_entreprise(1000) As String
Dim code_camion(1000) As String
Dim poids(1000) As Integer
Dim i As Integer 'compteur
Dim nb1 As Integer 'nb d'enregistrements
Dim nbmartin As Integer 'compteur entreprise Martin
Dim nom_entreprise(2000) As String
Dim nbentre As Integer 'nombre d'entreprises
Dim j As Integer 'compteur d'entreprises
Dim k As Integer 'compteur

'instructions
'lecture du fichier
Open "D:\Cours M1 GC\VBA\données exam 2017.txt" For Input As #58
i = 0
nb1 = 0
While Not EOF(58)
    i = i + 1
    Input #58, code_entreprise(i), code_camion(i), date1(i), poids(i)
Wend
nb1 = i

Close #58

' autre possibilité de lecture  on sauvegarde sur une feuille excel
For i = 1 To nb1
    Sheets("2017").Cells(i, 1) = code_entreprise(i)
    Sheets("2017").Cells(i, 2) = code_camion(i)
    Sheets("2017").Cells(i, 3) = date1(i)
    Sheets("2017").Cells(i, 4) = poids(i)
Next i

'calcul du nombre de fois où un camion de l'entreprise Martin est entré ou sorti
nbmartin = 0
For i = 1 To nb1
    If code_entreprise(i) = "Martin" Then
        nbmartin = nbmartin + 1
    End If
Next i
MsgBox "il y a eu " & nbmartin & " entrées ou sorties d'un camion de l'entreprise Martin"

'détermination du nombre d'entreprises différentes
nom_entreprise(1) = code_entreprise(1)
nbentre = 1
For i = 2 To nb1
    k = 0
    For j = 1 To nbentre
        If code_entreprise(i) <> nom_entreprise(j) Then
            k = k + 1
        End If
    Next j
                                                                          If k = nbentre Then
                                                                              nbentre = nbentre + 1
                                                                              nom_entreprise(nbentre) = code_entreprise(i)
                                                                          End If
Next i

Open "D:\Cours M1 GC\VBA\résultat exam 2017.tkt" For Output As #10
For i = 1 To nbentre
    Write #10, nom_entreprise(i)
Next i
Close #10
ca36f42c 1000 4d65 9d29 e329d699db49

Bonjour usanas,

Voici la partie du code en question commentée :

nom_entreprise(1) = code_entreprise(1) 'initialisation nom_entreprise, affectation item 1
nbentre = 1 'init entrées singulières
For i = 2 To nb1 'pour chaque valeur (de la liste avec multiplons)
    k = 0 'initialisation du compteur à chaque item i
    For j = 1 To nbentre 'pour chaque entrée singulière (plus exactement pour chaque item de nom_entreprise affecté)
        If code_entreprise(i) <> nom_entreprise(j) Then 'si l'entrée en cours est différente de chaque code
            k = k + 1 'incrémentation du compteur de valeurs singulières
        End If
    Next j
    If k = nbentre Then 'si compteur = nombre d'entrées singulières, càd si l'item i de code_entreprise n'existe pas dans nom_entreprise (càd si sa valeur <> de toutes les valeurs de nom_entreprise)
        nbentre = nbentre + 1 'incrementation nbentre
        nom_entreprise(nbentre) = code_entreprise(i) 'nouvelle entrée singulière = item i de code_entreprise
    End If
Next i

Si le code est construit de cette manière, il y a sûrement une raison. Quand on fait un exercice, on est souvent contraint et on ne peut pas toujours utiliser tous les moyens à disposition.

En tout cas, la méthode la plus simple est d'utiliser un objet dictionary mais cette méthode ne fonctionne pas sur mac aux dernières nouvelles :

'dim dico as object 'au niveau des declarations de variables

Set dico = CreateObject("Scripting.Dictionary")

For i = LBound(code_entreprise) To UBound(code_entreprise) 'pour chaque valeur (de la liste avec multiplons)
    dico(code_entreprise(i)) = "" 'ajout d'une nouvelle clé unique
Next i

'nom_entreprise = Application.Transpose(Application.Transpose(dico.keys)) 'si on veut nom_entreprise en base 1
nom_entreprise = dico.keys 'en base 0

'set dico = nothing

Le dictionnaire permet de lier des données à des clés uniques et est très utile dans la gestion des doublons.

dico(clé) = donnée revient à définir que la key clé est associée à l'élément donnée. Si cette clé n'existe pas, elle est créée, sinon, la valeur de l'item préexistante est modifiée. Dans ce cas présent, les items associés ne nous intéressent pas, d'où la chaine vide (mais on aurait pu mettre n'importe quoi).

nom_entreprise = dico.keys permet l'affectation des clés dans notre variable tableau nom_entreprise.

Cdlt,

Bonjour 3GB,

Merci beaucoup je vais essayer de lire vos commentaires attentivement pour mieux comprendre.

Bonne journée à vous

bonsoir 3GB,

j'espère que vous allez bien, serait-il possible de m'expliquer 2 petits points qui m'a bloqué.

Voici l'exercice : Un nombre entier n>2 est dit parfait s'il est égal à la somme de tous ses diviseurs stricts ( c'est à dire une division dont le reste est nul),1 compris. Ecrire un programme qui teste si son argument est un nombre parfait.

ci-joint la correction, mais je n'ai pas compris pourquoi pour l'initialisation on a mis rest=10 et som=1 aussi et pas 0 pour les 2, et pour la boucle elle a mis comme valeur initiale i=2 et pas 1, et pourquoi le (int(n/2)) car la condition dans l'énoncé et que n soit tt simplement >2, or avec le (int(n/2)) on doit obligé commencer avec n=4

Merci d'avance

Sub exo202()

'déclaration des variables

Dim n As Integer 'nombre demandé
Dim som As Integer 'somme des diviseurs stricts de n
Dim i As Integer 'compteur et désigne le diviseur testé
Dim rest As Integer 'reste de la division entière de n par i

'instructions

'initialisation
som = 1
rest = 10

'recherche des diviseurs et calcul de la somme

n = InputBox(" donnez un entier ", "n")

For i = 2 To (Int(n / 2)) Step 1
    rest = n - (Int(n / i) * i)
    If rest = 0 Then
        som = som + i
    End If
Next i

    If som = n Then
        MsgBox n & " est parfait ", , "réponse"
    Else
        MsgBox n & " n'est pas parfait ", , "réponse"
    End If

End Sub

Bonjour usanas,

Je précise que je ne connaissais pas les nombres parfaits avant ton post et j'imagine que ton professeur est plus compétent pour te donner des explications sur le programme qu'il voit chaque année, sachant que ce sujet n'a plus rien à voir avec le sujet de départ (il aurait fallu créer un nouveau post ).

En tout cas, je vais essayer de répondre.

Ici, on int(n/2) car on boucle sur l'ensemble des diviseurs susceptibles d'être diviseurs propres ou stricts (par lesquels, le reste de la division euclidienne serait nul).

Ex : n = 36. Au-delà de 18 (sa moitié), on aura toujours une division "impropre". C'est donc soit une commodité qu'on s'accorde, soit une règle dans la détermination d'un nombre parfait où il serait établi qu'un diviseur ne peut être supérieur à la moitié du nombre à diviser.

En effet, l'initialisation de rest est étrange et ne sert à rien dans le code puisqu'elle est écrasée dès la première itération. Je pense que ton professeur a copié un code (pour ne pas avoir à réécrire) et a oublié de rectifier ça.

L'initialisation de som à 1 est également un choix (probablement pédagogique pour vous familiariser avec l'initialisation des variables) puisque de fait, 1 est toujours retenu parmi les diviseurs propres. Si on initialise à 1, on commence la boucle à 2. Sinon, on se passe de l'initialisation et on commence la boucle à 1.

Voici une autre possibilité avec une fonction qui renvoie VRAI ou FAUX et une boucle qui commence à 1 sans l'initialisation de rest

Function EstParfait(n as integer) as boolean

Dim i%, rest%, som%

For i = 1 To (Int(n / 2))
    rest = n - (Int(n / i) * i)
    If rest = 0 Then
        som = som + i
    End If
Next i

EstParfait = som = n

End Sub

Bonne année en tout cas !

Cdlt,

Bonnsoir 3GB,

Je vous remercie énormément pour votre aide, c'est très gentil :)

bonne soirée

Bonjour 3GB,

Je reviens vers vous au sujet des commentaires que vous m'aviez noté pour la 1ère partie, celle des entreprises, est-il possible de me dire à quoi sert l'entrée singulière, nbentre=1 et pourquoi on lui attribut la valeur 1, alors que justement on cherche la valeur de nbentre qui représente le nombre d'entreprises différentes.

merci d'avance

Salut usanas,

Je reprends le code ici :

nom_entreprise(1) = code_entreprise(1) 'initialisation nom_entreprise, affectation item 1
nbentre = 1 'init entrées singulières
For i = 2 To nb1 'pour chaque valeur (de la liste avec multiplons)
    k = 0 'initialisation du compteur à chaque item i
    For j = 1 To nbentre 'pour chaque entrée singulière (plus exactement pour chaque item de nom_entreprise affecté)
        If code_entreprise(i) <> nom_entreprise(j) Then 'si l'entrée en cours est différente de chaque code
            k = k + 1 'incrémentation du compteur de valeurs singulières
        End If
    Next j
    If k = nbentre Then 'si compteur = nombre d'entrées singulières, càd si l'item i de code_entreprise n'existe pas dans nom_entreprise (càd si sa valeur <> de toutes les valeurs de nom_entreprise)
        nbentre = nbentre + 1 'incrementation nbentre
        nom_entreprise(nbentre) = code_entreprise(i) 'nouvelle entrée singulière = item i de code_entreprise
    End If
Next i

nbentre = 1 est l'initialisation de nbentre. Elle fait directement suite à l'initialisation de nom_entreprise. Il y a bien 1 première entreprise dans notre tableau donc 1 entrée singulière.

Entrée singulière est un terme (que j'ai choisi sur l'instant) pour désigner une valeur unique. Dans votre tableau code, il y a des doublons. Dans le tableau nom_entreprise, il n'y a en a plus donc chaque valeur est singulière, unique. nbentre est donc le nombre de valeurs uniques (qui s'incrémente au cours de l'exécution).

Voici une alternative sinon, plus simple je trouve :

redim nom_entreprise(1 to ubound(code_entreprise)) 'tableau de même dimension que code entreprise (avec que des valeurs vides)

For i = 1 To ubound(code_entreprise)'pour chaque valeur (de la liste avec multiplons)
    doublon = false: j = 1 'initialisation variables
    do while j <= To ubound(nom_entreprise) and nom_entreprise(j) <> "" 'tant que j inferieur à limite nom_entr et item de nom_entr non vide
        If code_entreprise(i) = nom_entreprise(j) Then 'si code = nom
            doublon = true 'doublon !
            exit do 'sortie de boucle
        end if
    loop
    if doublon = false then 'si aucun doublon trouvé
        n = n + 1 'incrémentation nb valeurs uniques
        nom_entreprise(n) = code_entreprise(i) 'nouvelle valeur unique prend valeur de l'item en cours de code_entr
    end if
Next i

if n > 0 then
    redim preserve nom_entreprise(1 to n) 'redimension de nom_entreprise limitée au nb de valeurs uniques (avec préservation des valeurs)
end if

Bonjour 3GB,

Oui effectivement c'est plus clair, merci beaucoup à vous

cordialement

Rechercher des sujets similaires à "comparaison valeurs tableau entre"