[Catégorie modifiée VB6 -> VBA] Calcul de distance minimum entre points avec coo [Résolu]

Signaler
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011
-
lutincoquin
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011
-
Bonjour,

Totalement novice sur VBA, j'ai besoin d'un peu aide pour développer une fonction relativement simple.
J'ai des coordonnées géographiques d'une ligne de chemin de fer dans les colonnes A et B (un point tous les 10 m). Dans les colonnes C et D, j'ai des coordonnées de points critiques. Je cherche à calculer la distance minimum entre chaque point critique et la ligne de chemin de fer. Pour cela le plus simple est d'utiliser Pythagore.
Voici ce que j'ai fait pour l'instant:

Sub Calcul_distance()
Dim i As Integer
Dim j As Integer

For i = 1 To LastRow
    For j = 1 To LastRow
    Cells(i, E) = Sqr((Cells(C, i) - Cells(A, j)) ^ 2 + (Cells(D, i) - Cells(B, j)) ^ 2)
    Next j
Next i
End Sub


2 problèmes:
- la macro ne fait strictement rien (mais il n'y a pas de message d'erreur)
- je veux la distance minimum, et je ne sais pas comment coder ça en VBA puisque la fonction min n'existe pas.

Si ume âme dévouée veut bien me donner un coup de pouce, je l'en remercie!

16 réponses

Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
Non !
pour moi, ou n'est pas toujours égale à j dans ton code, puisque tu y boucles deux fois avec i (ce qui m'as d'ailleurs interpellé, mais ... c'est toi qui sais pourquoi ! )

Je ne m'attendais pas à ce que ce soit "taupe" ! je connaissais les distances à vol d'oiseau, mais n'avais jamais entendu parler des souterraines

Mais : si c'est réglé, c'est réglé, alors ===>> un clic sur le tag "réponse acceptée" pour clore, donc.


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
Bonjour,

1) Avant toute autre chose : c'est sous VBA (le VBA de Excel) que tu développes et non sous VB6.
Nous te serions reconnaissant de bien vouloir en prendre bonne note et de faire dorénavant très attention au choix de la section dans laquelle tu "postes". Dans le cas présent, tu aurais du choisir la section Vivual Basic < langages dérivés > VBA

2) le bout de code que tu montres ne peut suffire à lui seul. Nous ne savons ni
- où et comment ont été déclarées puis initialisées les variables :
lastrow
C
E
- depuis où et par quelle instruction tu appelles cette macro


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
et j'ai oublié les variables A, B et D !


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
Et j'ajoute ceci avec force :
ou lastrow 0 dans ta macro (ce qui fait que les instructions dans ta boucle ne s'exécutant pas>> pas de message d'erreur)
ou lastrow est > 0, et là c'est pire si les variables A,B,C,D et E valent 0 dans ta boucle car là ===>> tu aurais un splendide message d'erreur

Mais je crains le pire et attends ton explication claire sur ces "variables" (il est probable que tu confondes les choses à un niveau fondamental ! )


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011

Merci pour ta réponse, ucfoutu!

1) Mille excuses pour cette confusion entre VBA et VB6, promis je le ferai plus.
Bon, pour rappel mes deux premiers mots étaient "totalement novice", ça veut bien dire ce que ça veut dire.

2) - Oublions Lastrow, je connais le numéro de la dernière ligne de ma colonne donc peu importe, je vais modifier ça. Quant à A, B, C, D et E ce ne sont pas des variables mais des numéros de colonne. J'ai certainement utilisé une syntaxe qui n'a rien à voir avec ce qu'il aurait fallu écrire.
- J'exécute cette macro directement depuis Excel

Vous allez certainement me dire de commencer par étudier VBA avant d'écrire des conneries, malheureusement je suis un peu pressé n'ai pas trop le temps (ni l'envie d'ailleurs) d'assimiler des centaines de notions qui me seront ensuite inutiles pour développer seulement une petite macro avec un algorithme très simple.
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011

En effet, je suis fondamentalement confondu!
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
Hé Bé !
Je m'en doutais

Lis mon dernier message !
Dès que tu donneras (dans la macro) une valeur > 0 ===>> tu les auras, tes erreurs !

Tels qu'écrits, A,B,C,D et E ne sauraient qu'être des variables et non des noms de colonnes !
voilà comment (différentes manières) tu peux te référer à la ligne x de la colonne C, par exemple :
ou x = un entier
Range("C" & x)
ou
Cells(x,"C")
ou encore
Cells(x,3)

ouvre ton aide VBA sur les mots Range et Cells ( surtout si tu es un débutant )

Autre chose : si tu ne précise pas la feuille concernées, ce sont les cellules de la feuille active, qui seront traitées.

____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011

Merci, ça marche déjà beaucoup mieux!
Je me retrouve donc avec cette macro:
Sub Calcul_distance()
Dim i As Integer
Dim j As Integer

For i = 1 To 10
    For j = 1 To 4
    Range("E" & i) = Sqr((Range("C" & j) - Range("A" & i)) ^ 2 + (Range("D" & j) -  Range("B" & i)) ^ 2)
    Next j
Next i
End Sub

Donc tout ce qu'il me reste à faire, c'est trouver le minimum de ce calcul. Si la fonction min() d'Excel existait ça serait déjà fini... J'ai vu plusieurs exemples sur des forums, mais j'avoue que ça ne m'aide pas trop. Existe-t-il une solution simples pour faire ça?
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
ouvre ton aide VBA (il va falloir que tu t'y habitues, hein ) sur le mot
WorkSheetFunction
et réfléchis à comment utiliser, dès lors, la fonction MIN de Excel depuis VBA.
Désolé, mais je ne veux pas (pas mon genre du tout) te livrer du tout-cuit. Le fait que tu "ne veux pas perdre de temps" n'est pas une considération valable à mes yeux.
Tu veux du poisson ? ===>> moi, je t'apprends les rudiments de la pêche, je ne te donne pas le poisson

____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011

héhé, j'apprécie le fait que tu veuilles pas me donner du tout cuit, c'est respectable et tout à ton honneur. Maintenant c'est pas que je ne Veux pas perdre mon temps, mais plutôt que je ne Peux pas! Promis quand je serai à la retraite j'achèterai un manuel de VBA, ça sera toujours plus intéressant que regarder des Chiffres et des Lettres.

Bref, je m'en vais fouiller dans l'aide. Si je trouve une solution qui marche je la posterai ici.

Encore merci pour ton aide!
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
Bien.
Reviens si difficulté (tu ne devrais pas en avoir, d'autant que tu y trouveras un exemple très clair, précisément avec Min).
Juste une piste : la plage (le Range) à passer en paramètre est la plage parcourue par ta boucle précédente, sur la seule colonne E. A ne calculer qu'une fois la boucle terminée


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011

Et ben je reviens, puisque je bloque...
Voici où j'en suis:
Sub Calcul_distance()
Dim i As Integer
Dim j As Integer
Dim distance As Object

Set distance = Worksheets("Plan1").Range("F1:F80")

For i = 1 To 2

    For j = 1 To 80
    distance = (Sqr((Range("C" & i) - Range("A" & j)) ^ 2 + (Range("D" & i) - Range("B" & j)) ^ 2))
    Next j
    
    Range("G" & i) = Application.WorksheetFunction.Min(distance) / 1000
    
Next i
End Sub


distance est ma "mémoire tampon" où sont calculées toutes les distances point critique - chemin de fer. Je peux les visualiser dans la colonne F pour controle. Ensuite je prends la plus petite de ces valeurs et la range dans la colonne G où elle va bien (ça marche nickel).
Un seul problème: toutes les distances de la colonne F sont identiques, alors qu'au vu de mes données d'entrée elles sont sensées être toutes différentes! Une idée?

ps: je teste avec de petites valeurs de i et j pour l'instant, mais j'ai des milliers de données à traiter, d'où l'intérêt de cette macro.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
Tu y étais auparavant, avec, déjà, toutes tes distances dans la colonne E !

pourquoi passer maintenant par un autre procédé qui, lui, ferait d'ailleurs appel à l'utilisation d'autres notions encore ? (au demeurant assez étonnantes !)


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
219
Et à ta place, je commencerais par vérifier que mes résultats sont ceux que j'attends (selon TES critères, que nous ne connaissons pas) !
et distance ne saurait être à la fois un objet et une valeur !
Sub Calcul_distance()
  Dim i As Integer
  Dim j As Integer
  dim distance as double
  dim ou as long
  ou = 1
  For i = 1 To 2

    For j = 1 To 80
      distance = (Sqr((Range("C" & i) - Range("A" & j)) ^ 2 + (Range("D" & i) - Range("B" & j)) ^ 2))
      range("F" & ou).value = distance
ou = ou + 1
    Next j
    
   
    
Next i
End Sub

sans préjudice de la justesse de tes calculs, qui ne regardent que toi et la connaissance que tu as de l'emplacement des données à "palper"
Voilà !
Le MIN est ensuite à calculer sur ta colonne F, de la ligne 1 à la ligne ou


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011

Ça marche parfaitement!
J'ai vérifié les distances sur Google Earth, c'est taupe.
Un grand merci! En plus de résoudre mon problème ça me donne envie d'approfondir le sujet.

Juste un doute: on peut très bien se passer de la variable 'ou' n'est-ce pas? Puisque 'ou' est toujours égal à 'j'. Je me suis d'ailleurs débrouillé pour la virer, ça fonctionne très bien. Quel est l'intérêt de cette variable?
Messages postés
8
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
9 décembre 2011

Je boucle i une fois par point critique pour lequel je veux évaluer la distance (je ne considérais que 2 points dans mon exemple, mais j'ai en fait 700 points pour lesquels je veux connaitre la distance minimale avec les 8000 points composant le tracé de la ligne de chemin de fer). Il y a sûrement un moyen d'optimiser tout ça parce que du coup ça fait 700 x 8000 = 5 600 000 itérations... environ 10 minutes de calcul. Mais bon, au moins ça marche!

Quant à "taupe" c'est évidemment une allusion à un sketch de Kad, Olivier et Gad. Après je sais pas si tu faisais référence à ça, mais j'ai pris soin de convertir toutes mes coordonnées en UTM qui est un système de projection (cad considérant la terre comme un plan et non un globe). Du coup les distances calculées sont de vraies distances à vol d'oiseau, si j'avais laissé les coordonnées en degrés ça aurait effectivement été des distance à "vol" de taupe...

Bref, merci encore!