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
Merci d'avance
Bonjour,
Essayez avec la formule suivante :
=SOMMEPROD(1/NB.SI(A1:A52;A1:A52))Voici le fichier
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 FunctionCdlt,
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 subCdlt,
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
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 iSi 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 = nothingLe 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 SubBonjour usanas,
Je précise que je ne connaissais pas les nombres parfaits avant ton 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 SubBonne 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 inbentre = 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 ifBonjour 3GB,
Oui effectivement c'est plus clair, merci beaucoup à vous
cordialement