Plage de données a partir d'un tableau VBA
Bonjour,
Pour des question de rapidité, je cherche une solution pour remplacer une plage dans une feuille de calcul Set PlageLatitude = .Range(.Cells(2, Colonne), .Cells(DerniereLigneCommune, Colonne)) par une plage extraite d'un tableau() vba contenant toute les données.
Je pense que ma question sera plus simple à comprendre en ouvrant le fichier joint.
Merci d'avance.
Patrick
Je ne comprends pas pourquoi vous voulez travailler avec un tableau. En ajoutant une couche (le tableau) vous allez ralentir le process, ce qui est le contraire de ce que vous voulez faire puisque votre but est d'augmenter la rapidité de traitement. Je me demande si ce n'était pas plutôt pour debugger l'outil.
J'ai apporté à votre code les modifications suivantes :
Fonction InRegion - ligne 21 : lire For t = 2 To L au lieu de t = 1 To L - 1 (la barre des titres provoque une erreur)
Programme RechercheCommuneCoordonnee :
Ligne 43 ajouter : FCommunes.Select : les plages ne peuvent pas être définies si leur feuille n'a pas le focus.
Ligne 55 ajouter : Sheets("RechercheCommune").Select : redonner le focus à la feuille initiale.
Sub RechercheCommuneCoordonnee()
Dim longitude() As Double, latitude() As Double
Dim derlig As Integer, i As Integer, J As Long
Dim Fin As Byte, virgule As Byte, nbpoint As Integer
Dim dept() As String, S As String
Dim tablo() As String
Dim tablo2() As String
Dim Victor As String
Dim sh As Shape
Dim a As Integer
Dim AA As Integer
Dim R1 As Integer, V1 As Integer, B1 As Integer
Dim R2 As Integer, V2 As Integer, B2 As Integer
Dim ligne As Long
Dim PlageLongitude As Range
Dim PlageLatitude As Range
Dim Ville As String
Dim diam As Integer
Dim DerniereLigneCommune As Long
Dim DerniereLigneCoordonnees As Long
Dim DansZone As Integer
Dim longitudePoint As Double, latitudePoint As Double
Dim lignePoint As Long
Dim Colonne As Long
Dim DerniereColonne As Integer
Sheets("RechercheCommune").Select
Application.ScreenUpdating = False
With FCommunes
DerniereColonne = .Cells(2, Columns.Count).End(xlToLeft).Column
'MsgBox "DerniereColonne = " & DerniereColonne
End With
DerniereLigneCoordonnees = Sheets("RechercheCommune").Range("A" & Rows.Count).End(xlUp).Row
'MsgBox "DerniereLigneCoordonnees = " & DerniereLigneCoordonnees
For lignePoint = 2 To DerniereLigneCoordonnees
latitudePoint = Replace(Cells(lignePoint, 1), ".", ",")
longitudePoint = Replace(Cells(lignePoint, 2), ".", ",")
For Colonne = 1 To DerniereColonne Step 2
'MsgBox Colonne
FCommunes.Select
With FCommunes
Ville = .Cells(1, Colonne)
DerniereLigneCommune = .Cells(Application.Rows.Count, Colonne).End(xlUp).Row
'MsgBox "DerniereLigneCommune = " & DerniereLigneCommune
Set PlageLatitude = .Range(.Cells(2, Colonne), .Cells(DerniereLigneCommune, Colonne))
Set PlageLongitude = .Range(.Cells(2, Colonne + 1), .Cells(DerniereLigneCommune, Colonne + 1))
End With
'Trouvé sur http://fordom.free.fr/
DansZone = InRegion(PlageLatitude, PlageLongitude, latitudePoint, longitudePoint)
Sheets("RechercheCommune").Select
If DansZone = 0 Then
Else
Cells(lignePoint, 3) = Ville
Exit For
End If
Next Colonne
Next lignePoint
Range("A1").Select
Application.ScreenUpdating = True
End Sub
Bonjour,
Merci Optimix pour ta réponse.
Je ne comprend pas pourquoi tu dit que la barre des titres provoque un bug car chez moi le fichier que j'ai joint fonctionne très bien ?
Il semble que ta correction apporte une erreur dans les résultats car sur ton fichier à la ligne 5 de la feuille "RechercheCommune" 45.26, 5.65 correspond a la commune de Voreppe, le résultat doit donc être vide puisque les coordonnées de Voreppe ne sont pas dans ma feuille "commune". Avec ta correction il me trouve Aoste ce qui est faux.
(J'ai limité le nombre de coordonnées des communes pour arriver à 1.5 Mo maxi comme le demande le forum)
Ensuite pourquoi venir sur la feuille Communes avec FCommunes.Select alors que je passe par un With FCommunes ?
Sachant que je peux avoir plus de 500 communes dans un département et plusieurs centaines de point GPS à traiter. j'ai besoin d'accélérer le code.
D'après https://www.excel-pratique.com/fr/vba/tableaux_vba lorsqu'on travail avec des tableaux() vba le traitement est 10 à 20 fois plus rapide. J'ai pu le vérifier dans d'autres applications.
Merci Optimix.
Bonjour à tous,
je dois partir mais si je peux me permettre, travailler avec un tableau en mémoire est considérablement plus rapide que de lire/écrire des cellules une par une.
Il faut lire d'un bloc, modifier dans le tableau et écrire en une fois toutes les données.
C'est souvent de l'ordre de x100
Merciiiii
Effectivement je voudrais travailler sur TabloCoordonneesCommunes() que je crée avec ce code mais je ne sais pas faire une plage de données dans un tableau() et je n'ai rien trouvé sur le net.
Sub TabloBDDCommunesVirtuel()
Dim adresse As String
Dim TabloCoordonneesCommunes()
Dim DerniereLigne As Integer
Dim DerniereColonne As Integer
Sheets("Communes").Select
adresse = Cells(Cells.Find("*", , , , xlByRows, xlPrevious).Row, Cells.Find("*", , , , xlByColumns, xlPrevious).Column).Address
Range(adresse).Activate
DerniereLigne = ActiveCell.Row
DerniereColonne = ActiveCell.Column
'Enregistrement des valeurs dans le tableau
TabloCoordonneesCommunes = Range(Cells(1, 1), Cells(DerniereLigne, DerniereColonne))
End Sub
A essayer :
Pour passer la plage de données dans un tableau, on peut mettre les 2 colonnes dans le tableau comme ceci :
tablo = .Range(.Cells(2, Colonne), .Cells(DerniereLigneCommune, Colonne + 1))
ensuite on passe le tableau dans les paramètre de la fonction avec :
DansZone = InRegion(tablo, latitudePoint, longitudePoint)
du coup la fonction devient :
Function InRegion(tablo, ByVal x As Double, ByVal y As Double)
merci Optimix. Je regarderai ta proposition demain.
Mon idée de départ était de partir d'un tableau() contenant l'ensemble des données des communes.
Mais est-ce possible ?
C'est tout à fait possible. Un petit exemple de mise en tableau :
Sub Macro1()
Dim tablo() As Variant, wS As Worksheet
Dim lignes As Integer, colonnes As Integer
Dim i As Integer, j As Integer
Set wS = Sheets("Communes")
lignes = wS.UsedRange.Rows.Count
colonnes = wS.UsedRange.Columns.Count
ReDim tablo(lignes, colonnes)
For i = 1 To lignes
For j = 1 To colonnes
tablo(i, j) = wS.Cells(i, j)
Next j
Next i
' Contrôle
MsgBox wS.Cells(110, 100)
MsgBox tablo(110, 100)
End Sub
Re,
Il faut lire tout en même temps pour un gain de temps
Choisi un nom un peu plus court pour ton tableau comme tCoord
Dim tCoord as Variant, ta_plage as Range, lig as Long
' j'ai mis As Variant que ce soit clair car c'est impératif. Ne pas typer le déclare variant et c'est ok
tCoord= ta_plage.value (est obligatoirement un tableau 2D même si une seule colonne)
que tu balaies avec For lig = 1 to ubound(tCoord)
Ecriture :
ta_plage.value = tCoord
ou bien si tu as dû utiliser un tableau result pour les résultats car tailles différentes ou besoin de préserver les datas jusqu'au bout :
[A2].resize(ubound(result,1), ubound(result,2)).value=result
Merci Optimix, merci Eriiic,
La solution Optimix de 13:09 divisive par 16 le temps de traitement.
On peut peut-être gagner encore, mais pour le moment cela me convient parfaitement.
Merci