En algún momento hice algo parecido. Lo resolví así:
Antes del bucle de creación de los botones definí dos variables (el tipo de dato numérico hay que asignarlo de acuerdo a la cantidad de filas que vayas a utilizar, en mi caso con Byte me alcanzó): Fila y Columna. Y puse 1 como primer valor a ambas.
Luego, dentro del bucle puse lo siguiente (lo adapté a tu código):
Load boton(ind)
Set boton(ind).Container = frameContenedor 'Luego de crearlo lo ubico dentro de un frame.
boton(ind).Top = (60 + boton(ind).Height) * (Fila - 1) '60 es el espacio que le di entre filas
boton(ind).Left = (60 + boton(ind).Width) * (Columna - 1) '60 es el espacio que le di entre columnas
Columna = Columna + 1
If Columna = 6 Then 'En mi caso, la grilla tenía 5 columnas.
Fila = Fila + 1
Columna = 1
End If
...
Imagino que esta manera de hacerlo no es muy ortodoxa, pero me funcionó bien. Seguramente alguien ponga alguna manera mejor de hacerlo (en cuyo caso también aprenderé a hacerlo bien). Pero si no, tal vez te sirva para lo que necesitás.
Saludos.