1
votes

Bouclage avec un ensemble de données infini

J'essaye de créer un VBA mais je reste bloqué, si quelqu'un peut aider cela serait apprécié. Donc, sur la base de l'image, je voudrais que chaque animal soit copié dans chaque ensemble / # (et que le résultat soit sur la feuille 2). Le problème est que ce ne sera pas toujours un ensemble de 14, cela peut varier en fonction des données, mais les animaux resteraient les mêmes (pas plus de 4). Voici ce que j'ai actuellement dit qu'il n'est pas basé sur l'image. ce n'est qu'un exemple.

Exemple d'objectif pour VBA

exemple VBA mis à jour

Sub DowithIf()

rw = 5
cl = 2
rw = 1000

Do While rw < erw
If Cells(rw, cl) <> Cells(rw - 1, cl) Then
Cells(rw, cl + 1) = Cells(rw, cl)

Range("A5:B5").Select
Selection.Copy
Sheets("Sheet2").Select
Range("A2").Select
ActiveSheet.Paste
Range("A2:B4").Select
Application.CutCopyMode = False
Selection.FillDown
Sheets("Data").Select
Range("E3:J5").Select
Selection.Copy
Sheets("Sheet2").Select
Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
    :=False, Transpose:=False
ElseIf Cells(rw, cl) = "" Then
    Exit Do
End If
   rw = rw + 1
Loop

End Sub


0 commentaires

3 Réponses :


0
votes

Je pense donc que cela vous permettra de choisir dynamiquement la taille de votre ensemble de données. Je suppose que les en-têtes de colonne seront toujours à la ligne 5, comme illustré. Il parcourt chaque colonne d'entrée et fournit une sortie unique en H, I et J. Avis de non-responsabilité: Je n'ai pas pu tester cela car je ne suis pas sur mon PC de travail.

Sub MixTheStuff()

'sets size of data in A (Set).  -5 for the header row as noted
x = ThisWorkbook.Sheets("Data").Cells(Rows.Count, 1).End(xlUp).Row - 5  
 
'sets size of data in B (#)
y = ThisWorkbook.Sheets("Data").Cells(Rows.Count, 2).End(xlUp).Row - 5

'sets size of data in E (Animal)
z = ThisWorkbook.Sheets("Data").Cells(Rows.Count, 5).End(xlUp).Row - 5   

i=6 'First row after the headers

For sThing = 1 to x    'set thing
For nThing = 1 to y    'number thing
For aThing = 1 to z    'animal thing

    'Pastes the value of the stuff (Set, #, and Animal respectively)
    ThisWorkbook.Sheets("Data").cell(i,10) = ThisWorkbook.Sheets("Data").cell(x,1).value
    ThisWorkbook.Sheets("Data").cell(i,11) = ThisWorkbook.Sheets("Data").cell(y,2).value
    ThisWorkbook.Sheets("Data").cell(i,12) = ThisWorkbook.Sheets("Data").cell(z,5).value

i = i + 1 'Go to the next output row

Next sThing
Next nThing
Next aThing

End Sub


0 commentaires

0
votes

Sorte de non pivot
  • Cela vous permettra de gérer au maximum 1023 animaux.

Le code

Option Explicit

Sub SortOfUnpivot()
    
    Const FirstRow As Long = 6
    Const LastRowCol As String = "E"
    Const dstFirstCell As String = "H6"
    Dim srcCols As Variant
    srcCols = VBA.Array("A", "B", "E")
    
    Dim LB As Long
    LB = LBound(srcCols)
    Dim UB As Long
    UB = UBound(srcCols)
    Dim srcCount As Long
    srcCount = UB - LB + 1
    
    Dim LastRow As Long
    LastRow = Cells(Rows.Count, LastRowCol).End(xlUp).Row
    Dim rng As Range
    Set rng = Cells(FirstRow, LastRowCol).Resize(LastRow - FirstRow + 1)
    Dim Source As Variant
    ReDim Source(LB To UB)
    
    Dim j As Long
    For j = LB To UB
        Source(j) = rng.Offset(, Columns(srcCols(j)).Column - rng.Column).Value
    Next j
    
    Dim UBS As Long
    UBS = UBound(Source(UB))
    
    Dim Dest As Variant
    ReDim Dest(1 To UBS ^ 2, 1 To srcCount)
    Dim i As Long
    Dim k As Long
    
    For j = 1 To UBS
        k = k + 1
        For i = 1 + (j - 1) * UBS To UBS + (j - 1) * UBS
            Dest(i, 1) = Source(0)(k, 1)
            Dest(i, 2) = Source(1)(k, 1)
            Dest(i, 3) = Source(2)(i - (j - 1) * UBS, 1)
        Next i
    Next j
    
    Range(dstFirstCell).Resize(UBound(Dest), srcCount).Value = Dest
    
    
End Sub


0 commentaires

0
votes

Je pense que vous trouveriez cela plus facile si vous considérez VBA comme plus un langage de programmation qu'un enregistreur de macros. Dans votre exemple, la tâche consiste simplement à créer un tableau dont le nombre de lignes est:

nombre de noms de set * nombre d'éléments de set

Tout ce que vous avez à faire est de remplir ce tableau en suivant un certain modèle. Dans votre exemple, ce serait:

définir le numéro n avec tous les éléments définis, définir le numéro n + 1 avec tous les éléments définis, etc.

Le code squelette ressemblerait à ceci:

Const SET_NAMES_ROW_START As Long = 6
Const SET_ITEMS_ROW_START As Long = 6
Const SET_NAMES_COL As String = "A"
Const SET_ITEMS_COL As String = "E"
Const OUTPUT_ROW_START As Long = 6
Const OUTPUT_COL As String = "G"

Dim names() As Variant, items() As Variant, output() As Variant
Dim namesCount As Long, itemsCount As Long
Dim idx As Long, nameIdx As Long, itemIdx As Long

'Read the set values.
With Sheet1
    names = .Range( _
                .Cells(SET_NAMES_ROW_START, SET_NAMES_COL), _
                .Cells(.Rows.Count, SET_NAMES_COL).End(xlUp)) _
               .Resize(, 2).Value2
    items = .Range( _
                .Cells(SET_ITEMS_ROW_START, SET_ITEMS_COL), _
                .Cells(.Rows.Count, SET_ITEMS_COL).End(xlUp)) _
               .Value2
End With

'Dimension the output array.
namesCount = UBound(names, 1)
itemsCount = UBound(items, 1)

ReDim output(1 To namesCount * itemsCount, 1 To 3)

'Populate the output array.
nameIdx = 1
itemIdx = 1
For idx = 1 To namesCount * itemsCount
    output(idx, 1) = names(nameIdx, 1)
    output(idx, 2) = names(nameIdx, 2)
    output(idx, 3) = items(itemIdx, 1)
    itemIdx = itemIdx + 1
    If itemIdx > itemsCount Then
        'Increment the name index by 1.
        nameIdx = nameIdx + 1
        'Reset the item index to 1.
        itemIdx = 1
    End If
Next

'Write array to the output sheet.
Sheet1.Cells(OUTPUT_ROW_START, OUTPUT_COL).Resize(UBound(output, 1), UBound(output, 2)).Value = output


3 commentaires

Merci beaucoup, cela a été très utile! J'ai 1 question de suivi en supposant qu'il y aurait une autre colonne ajoutée à côté de "Animal" et je veux toujours garder la sortie la même (voir l'image de sortie VBA mise à jour) qu'est-ce qui serait ajouté / modifié dans le code?


Développez simplement le tableau des items d'une colonne, puis lisez la deuxième colonne dans le tableau de output(idx, 4) = items(itemIdx, 2) : output(idx, 4) = items(itemIdx, 2)


J'ai essayé d'étendre le tableau des éléments de 1 colonne + sortie ajoutée (idx, 4) = items (itemIdx, 2) dans le tableau de sortie. Mais j'obtiens toujours une erreur de débogage. juste pour m'assurer que j'augmente correctement le tableau des éléments, pourriez-vous coller la partie que je suis censée augmenter. Je pense que je pourrais me tromper mais je ne suis pas sûr à 100%. Merci encore!