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

Résolu
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011 - 9 déc. 2011 à 15:42
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011 - 9 déc. 2011 à 20:17
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

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 19:45
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
3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 16:16
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
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 16:19
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
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 16:30
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011
9 déc. 2011 à 16:33
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.
0
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011
9 déc. 2011 à 16:34
En effet, je suis fondamentalement confondu!
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 16:41
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
0
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011
9 déc. 2011 à 16:53
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?
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 16:57
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
0
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011
9 déc. 2011 à 17:04
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!
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 17:08
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
0
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011
9 déc. 2011 à 17:43
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.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 17:54
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
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 223
9 déc. 2011 à 18:19
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
0
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011
9 déc. 2011 à 19:09
Ç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?
0
lutincoquin Messages postés 8 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 9 décembre 2011
9 déc. 2011 à 20:17
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!
0
Rejoignez-nous