Transformer une matrice (carrée et fermée) en une liste
Bonjour,
je dispose d'une matrice carrée et fermée, elle contient dans l'exemple 109 lignes et 109 colonnes. Elle correspond à une matrice Origine - Destination. La première colonne contient l'identifiant d'une origine, la première ligne contient l'identifiant d'une destination.
Les informations contenues dans les cellules représentent des flux entre mes objets géographiques. C'est à dire les flux entre une commune d'origine et une commune de destination, en simplifiant.
Je souhaite transformer cette matrice en une liste à trois colonnes, avec comme première colonne l'identifiant de l'objet géographique d'origine, comme seconde colonne l'identifiant de l'objet géographique de destination et en troisième colonne la valeur des flux entre l'origine et la destination.
Je vous joins un exemple avec deux feuilles où on retrouve l'organisation des données avant - après.
Cela fait bientôt 15 ans que je n'ai pas fait de VBA et je me demandais si quelqu'un pouvait m'aider car je dois répéter cette opération sur un cinquantaine de fichier exactement similaire.
Je vous serai très reconnaissant du coup de main, car cela trop longtemps que je me casse les dents sur cette difficulté.
Merci à vous
Bonjour, et bienvenue ...
Sub lister()
Sheets("Apres_Liste").Select
k = 2
Cells.Clear
With Sheets("Avant_Matrice")
For col = 2 To .Cells(1, Columns.Count).End(xlToLeft).Column
For lig = 2 To .Cells(Rows.Count, 1).End(xlUp).Row
Cells(k, 1) = .Cells(lig, 1)
Cells(k, 2) = .Cells(1, col)
Cells(k, 3) = .Cells(lig, col)
k = k + 1
Next lig
Next col
End With
End Sub
Bonjour,
je vous remercie infiniment pour cette macro. Vous venez de résoudre une difficulté que je contournais depuis une année !
Si je l'ai bien saisie, je dois pouvoir recopier cette macro pour toute tranformation de matrice en liste, peu importe le nombre de lignes et de colonnes qu'elle contient. C'est bien cela ?
Dire qu'il y a quinze ans on s'asseyait à côté de moi pour me copier pendant les examens de VBA
Merci encore,
M.
Bonjour,
Bonjour Steelson,
Une autre proposition, identique à celle de Steelson, avec les données mises sous forme de tableau (array).
Comme Steelson, le nombre de colonnes et de lignes variables est pris en compte.
Cdlt.
Public Sub Lister2()
Dim ws As Worksheet, ws2 As Worksheet
Dim lastCol As Long, lastRow As Long
Dim I As Long, J As Long, k As Long
Dim tbl, arr()
Set ws = Worksheets("Avant_matrice")
Set ws2 = Worksheets("Apres_Liste")
With ws
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
tbl = .Cells(1).Resize(lastRow, lastCol)
End With
For I = 2 To UBound(tbl)
For J = 2 To UBound(tbl, 2)
ReDim Preserve arr(3, k + 1)
arr(0, k) = tbl(I, 1)
arr(1, k) = tbl(1, J)
arr(2, k) = tbl(I, J)
k = k + 1
Next J
Next I
With ws2
.Cells.Clear
.Cells(1).Resize(k, 3).Value = WorksheetFunction.Transpose(arr)
End With
End SubBonjour à tous,
autre proposition avec un tableau redimensionné,
Sub Transpose_Tableau()
Dim tb()
Set sh = Sheets("Avant_Matrice")
plg = sh.Range("B2:DE109").Value
For i = 2 To 108
For j = 2 To 108
x = x + 1
ReDim Preserve tb(2, x)
tb(0, x) = sh.Cells(i, 1)
tb(1, x) = sh.Cells(1, j)
tb(2, x) = plg(i - 1, j - 1)
Next j
Next i
ActiveSheet.[A1].Resize(x, 3) = Application.Transpose(tb)
End Sub