One thing that is missing in Visio, is the ability to stack shapes. You can align shapes on the top, bottom, left or right edges, but you can not stack.
To stack two shapes, you have to drag a guideline from the top ruler and then place the bottom edge of one shape on the guideline and the top shape of the other on the guideline.
If you want to stack several shapes, it means grouping what you have and then repeating the process.
Luckily, Visio has a workaround, use a List Container.

The green square is my List Container. As I add the squares and ellipses to the container, the shapes are stacked. If I mess up the order, I can simply select the shape and use the up or down arrow keys to change the order.
To get the list aligned on the center set msvSDListAlignment to 1.
So, once I have the shapes stacked, it is just a matter of selecting the shapes without selecting the container. msvSDContainerMargin is set to .5 so there should be no problem using a rectangular selection.
You can look up the meaning of the other user cells to change the orientation or the space between the shapes.
One issue with the Distribute command is it is based on the first and last shape. With the List Container, you can distribute the shapes with a given spacing, Just make msvSDListSpacing non zero.
Public Sub CreateListContainer()
'Create a List Container shape
Dim i As Integer, shp As Visio.Shape
Set shp = ActiveWindow.Page.DrawRectangle(0, 0, 1, 1)
shp.Cells("FillForegnd").FormulaU = "RGB(146,208,80)" ' green
'User cells - Visio needs special User cells to make the shape a List Container
shp.AddNamedRow visSectionUser, "msvStructureType", visTagDefault
shp.AddNamedRow visSectionUser, "msvSDContainerMargin", visTagDefault
shp.AddNamedRow visSectionUser, "msvSDListAlignment", visTagDefault
shp.AddNamedRow visSectionUser, "msvSDListDirection", visTagDefault
shp.AddNamedRow visSectionUser, "msvSDListSpacing", visTagDefault
shp.Cells("User.msvStructureType").FormulaU = Chr(34) & "List" & Chr(34)
shp.Cells("User.msvSDContainerMargin").FormulaU = 0.5
shp.Cells("User.msvSDListAlignment").FormulaU = 0
shp.Cells("User.msvSDListDirection").FormulaU = 2
shp.Cells("User.msvSDListSpacing").FormulaU = 0
shp.Cells("DisplayLevel").FormulaU = -3000 ' and push it to the back
End Sub