3

I am researching bird migration patterns and I am having trouble trying to figure out the best and easiest method of moving data around in excel. I am pretty good at excel, but I am terrible at macros and VBA coding, so I apologize in advance if my thinking of coding this looks completely wrong, and that there is nothing wrong with seeking expert advice. So far, I have used a pivot table to narrow out birds based on species count, location and dates.

pivot table

After that, I moved the data from the dates per species and stack them from a range to a single column.

single column

I did find a vba code that works (even though the output is actually moving the data sideways from left to right, it still is the same thing “moves B4:P4, B5:P5, B6:P6, etc..”), but this is only a single range at a time:

Sub main()
Dim i As Long
Dim cell As Range

For Each cell In Range("B4:P13")
    Range("S4").Offset(i).Value = cell.Value
    i = i + 1
Next cell
End Sub

My problem is that there are 56 species and 3 locations. So I would need to move the data 168 times, which is ridiculous. After I arrange them, I run a single factor analysis 56 times per species in each of the three locations. If anyone can help, that would be amazing and be very helpful for science.

My idea / hopes and dreams:

If I can repeat the code within the same VBA code module and change the values of the ranges and output locations for each species. All 3 locations have the same general format and location of the ranges (plus minus two extra dates), or if I can set the location to another sheet. Like so…

Sub main()
Dim i As Long
Dim cell As Range

For Each cell In Range("B4:P13")
    Range("S4").Offset(i).Value = cell.Value
    i = i + 1
For Each cell In Range("B15:P24")
    Range("U4").Offset(i).Value = cell.Value
    i = i + 1
For Each cell In Range("B26:P35")
    Range("W4").Offset(i).Value = cell.Value
    i = i + 1
For Each cell In Range("B37:P46")
    Range("Y4").Offset(i).Value = cell.Value
    i = i + 1
etc…
Next cell
End Sub

To look something like this:

single column

Or more preferably this:

more preferably

Again thank you for the help and contributions. :D

omegastripes
  • 12,351
  • 4
  • 45
  • 96
13ucci
  • 33
  • 3
  • 1
    If you already have the data normalized, you could use Power Query which is the best fit for this kind of transformations – Ricardo Diaz Feb 11 '20 at 20:19
  • What the source data for pivot table looks like? – omegastripes Feb 11 '20 at 20:38
  • Presumably the amount of data - species, locations etc - is all dynamic? – SJR Feb 11 '20 at 20:45
  • @omegastripes Current pivot table: https://imgur.com/a/o0B1F1X – 13ucci Feb 11 '20 at 20:53
  • @SJR In all the locations (sheets) the species are the same. Each species has the same amount of points (1-10). In location 1, there are 15 dates, In locations 2 -3, there are 17 dates. So presumably the Species, Locations, and Points are static. And the data (numbers within) are dynamic. – 13ucci Feb 11 '20 at 21:02
  • Do give my answer a try and let me know how you get on. – SJR Feb 11 '20 at 21:14
  • @13ucci What the source data for pivot table looks like? Not pivot table itself but source data. – omegastripes Feb 12 '20 at 01:42

1 Answers1

1

Bit more involved that it seemed at first glance. I've made a few assumptions so might need some tweaking if these are not tenable:

  • the starting workbook has only one sheet for each location, i.e. the number of sheets equals the number of locations
  • data starts in B4 on each sheet (and species names in A3, A14 etc)
  • each location sheet has the same number of species

Do use more meaningful procedure and variable names for your actual code.

Sub x()

Dim nSpec As Long, nLoc As Long, i As Long, vSpec(), j As Long, k As Long, wsOut As Worksheet, r As Range

nLoc = Worksheets.Count 'number of locations
Set r = Worksheets(1).Range("A3")
Do Until IsEmpty(r)
    i = i + 1
    ReDim Preserve vSpec(1 To i)
    vSpec(i) = r.Value
    Set r = r.Offset(11)
Loop
nSpec = UBound(vSpec) 'number of species

Set wsOut = Worksheets.Add(after:=Worksheets(Worksheets.Count)) 'add results sheet
wsOut.Name = "Results"

For i = 1 To nLoc 'headings for results sheet
    With Worksheets(i) 'for each location
        For j = 1 To nSpec 'for each species
            wsOut.Cells(1, (j - 1) * (nLoc + 1) + 1).Value = vSpec(j) 'species heading
            wsOut.Cells(2, (j - 1) * (nLoc + 1) + i).Value = .Name 'location heading
            Set r = .Range("B4").Offset((j - 1) * 11).Resize(10) 'assumes B4 is top left cell of data
            Do Until IsEmpty(r(1))
                wsOut.Cells(Rows.Count, (j - 1) * (nLoc + 1) + i).End(xlUp)(2).Resize(10).Value = r.Value 'transfer data
                k = k + 1 'move to next column
                Set r = .Range("B4").Offset((j - 1) * 11, k).Resize(10)
            Loop
            k = 0
        Next j
    End With
Next i

End Sub
SJR
  • 22,986
  • 6
  • 18
  • 26
  • I will try your code out, but I noticed that the output is a bit different than expected. The preferred output format: https://imgur.com/a/I53mQWO , again thank you :D – 13ucci Feb 11 '20 at 21:27
  • Sorry got mixed up will take a look later. – SJR Feb 11 '20 at 21:44
  • I appreciate it a bunch. – 13ucci Feb 11 '20 at 21:51
  • Would it be an option for the user to input the number of species and locations as part of the code? – SJR Feb 11 '20 at 22:41
  • Do you mean the code asking the user to input the number of species (ie: 36) and locations (ie: 3), then yes. Each species has 3 locations. – 13ucci Feb 11 '20 at 22:47
  • So far I am using this code from here: https://stackoverflow.com/questions/21648122/copy-range-and-paste-values-in-another-sheets-specific-range and editing the letters to represent my data after running your mockup code. – 13ucci Feb 12 '20 at 01:28
  • PERFECT, absolutely flawless -edit (had to remove end function, excel didn't like it.) -what did you mean by: "Do use more meaningful procedure and variable names for your actual code."? – 13ucci Feb 12 '20 at 19:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/207695/discussion-between-13ucci-and-sjr). – 13ucci Feb 12 '20 at 19:17