Ça ne va pas arriver souvent, vu que je prône l'utilisation de logiciels libres, mais voici un script VBA pour Excel que j'ai du faire au boulot.
La tâche : j'ai une feuille contenant un tas de rapport de ventes, les uns à la suite des autres, séparés par une ligne vide à chaque fois.
Il fallait splitter chaque rapport dans une nouvelle feuille.
Vu que j'ai du écrire 3 lignes de VBA dans ma vie, il y a plus de 15 ans, j'étais passablement rouillé.
Tellement rouillé qu'en fait j'ai juste été pomper des bouts de codes à droite à gauche pour les mélanger ensemble et espérer que ça marche.
Et ça marche !
Par contre pour le style, on repassera. J'ai tenté de nettoyer le code après coup mais il reste probablement des horreurs qui feront bondir les puristes.
Fichier source
Résultat final
Algorithme en 2 mots
Je duplique la feuille de base, je cherche la 1ère ligne vide, je copie la plage jusqu'à la ligne vide dans une nouvelle feuille au nom du client, je supprime la plage sélectionnée et je recommence.
A la fin je supprime la feuille dupliquée.
Code source
Sub split() Dim firstPage As Worksheet Set firstPage = Sheets(1) ' La page de référence, à parser et spliter ' https://msdn.microsoft.com/en-us/library/office/ff837784.aspx firstPage.Copy After:=firstPage ' On copie la page de base Dim copyPage As Worksheet Set copyPage = Sheets(2) ' La page copiée, qu'on peut modifier copyPage.Name = "temp" Dim nextBlankRow As Long nextBlankRow = firstBlankRow(copyPage) While (nextBlankRow > 0) Dim clientName As String clientName = findClientName(copyPage.Range("A:A")) Sheets.Add After:=Sheets(Sheets.Count) ' crée une nouvelle feuille et l'ajoute à la fin du classeur Dim newPage As Worksheet Set newPage = Sheets(Sheets.Count) ' On récupère la feuille nouvellement créée newPage.Name = clientName ' renome la nouvelle feuille Dim nbCol As Long nbCol = copyPage.UsedRange.Columns.Count Dim currentRange As Range Set currentRange = copyPage.Range("A1", copyPage.Cells(nextBlankRow, nbCol)) ' http://stackoverflow.com/questions/21648122/excel-vba-copy-range-and-paste-values-in-another-sheets-specific-range currentRange.Copy ' Copie des valeurs de la 1ère page newPage.Range("A1").PasteSpecial xlPasteValues ' on colle dans la nouvelle feuille newPage.Columns.AutoFit ' ajuster la taille des colones : http://www.extendoffice.com/documents/excel/1174-excel-split-data-into-multiple-worksheets-based-on-column.html newPage.Range("A1").Select ' lâche la sélection currentRange.Delete ' Supprime la plage pour pouvoir recommencer avec la suivante nextBlankRow = firstBlankRow(copyPage) Wend Application.DisplayAlerts = False copyPage.Delete Application.DisplayAlerts = True firstPage.Select firstPage.Range("A1").Select End Sub Function findClientName(fullCol As Range) As String For Each cell In fullCol.Cells If cell.Value <> "" Then findClientName = cell.Value Exit For End If Next End Function Function firstBlankRow(ws As Worksheet) As Long 'returns the row # of the row after the last used row 'Or the first row with no data in it 'http://stackoverflow.com/questions/12497804/finding-first-blank-row-then-writing-to-it Dim rngSearch As Range, cel As Range With ws Set rngSearch = .UsedRange.Columns(1).Find("") '-> does blank exist in the first column of usedRange If Not rngSearch Is Nothing Then Set rngSearch = .UsedRange.Columns(1).SpecialCells(xlCellTypeBlanks) For Each cel In rngSearch If Application.WorksheetFunction.CountA(cel.EntireRow) = 0 Then firstBlankRow = cel.Row Exit For End If Next Else '-> no blanks in first column of used range If Application.WorksheetFunction.CountA(Cells(.Rows.Count, 1).EntireRow) = 0 Then '-> is the last row of the sheet blank? '-> yeap!, then no blank rows! firstBlankRow = -1 'MsgBox "Whoa! All rows in sheet are used. No blank rows exist!" Else '-> okay, blank row exists firstBlankRow = .UsedRange.SpecialCells(xlCellTypeBlanks).Row + 1 End If End If End With End Function
Le fichier qui contient tout
Fichier
Créer une macro VBA
Menu Outils, Macro, Visual Basic Editor
Lancer une macro VBA
Menu Outils, Macro, Macros, sélectionner Feuil1.split (nom de la feuille original + nom de la méthode Sub)
Notez que, par défaut, si vous ouvrez un fichier avec une macro le programme vous avertira des problèmes de sécurité et les désactivera.
Pour les autoriser, rendez-vous dans le menu Outils, Options, onglet Sécurité, bouton Sécurité des macros et sélectionnez Moyen ou Faible.
Sources
Copier une plage de valeurs
Trouver la prochaine ligne vide
Ajuster la taille des colones
Dupliquer une feuille
Versions
Microsoft Excel 2002 (10.2614.2625)
Microsoft Visual Basic 6.3