Enough history, now to the present.
I will prepare a diagram showing the plan view of the mat in a spread foundation.
For the layperson:
In ACI (American Concrete Institute) terminology, “nominal” refers to the standard or intended size of a rebar, often based on its diameter. For example, #8 rebar has a nominal diameter of 8/8 inches, or 1 inch. Rebar sizes are designated by numbers, with each number representing the nominal diameter in eighths of an inch (e.g., #3 rebar is 3/8 inch diameter).
Typically, two grids of rebar are required: a top grid layer and a bottom grid layer. The bottom grid layer is designed for positive moment, the top grid layer is designed for negative moment. In my macro, I illustrate only one of the two grids. A full engineering spreadsheet would, of course, show both grids.
The foundation is specified by length and width. Rebar is specified by nominal size and maximum spacing. In an engineering drawing the number of rebar is also called out, for clarity.
I do not address the design procedure, only the drawing of the finished design.
Below, I offer a static image illustrating a typical rebar layout drawing. Note that this one is entirely sufficient; it’s not to scale and that’s okay, even preferable; it’s driven by Excel cell values; it was handmade using Excel; and it is easily modified for each new foundation design.

Here is a short video illustrating use of the macro.
Note that I simplify and shorten the input dialog, using only two prompts.
The first prompt asks for 3 parameters; the user responds with a space delimited entry of ‘Cover Xdim YDim’. The second prompt asks for 4 parameters; the user responds with a space delimited entry of ‘VBar Xspace HBar YSpace’. Obviously the macro parses the input thereby obtaining the parameter values.
## FOR EXAMPLE
# ===========
Cover, Xdim, Ydim = [float(e) for e in rebarparameters.split()]
I mentioned having to update my code; here are snippets to explain.
##
## code updates from 2018 to 2025
##
## previous macro
horzbars = xl.Selection.Group()
horzbars.Name = "horz_bars"
vertbars = xl.Selection.Group()
vertbars.Name = "vert_bars"
allbars = xl.Selection.Group()
allbars.Name = "all_bars"
##
## current macro
horzbars = xl.Selection.ShapeRange.Group()
horzbars.Name = "horz_bars"
vertbars = xl.Selection.ShapeRange.Group()
vertbars.Name = "vert_bars"
allbars = xl.Selection.ShapeRange.Group()
allbars.Name = "all_bars"
@xl_macro()
def vba_example():
"""
[PyXLL] Draw rebar arrangement and callout from quick dialog box
"""
xl = pyxll.xl_app()
try:
# access existing worksheet tab, if it exists
myDocument = xl.Worksheets("draw")
except:
# add a new worksheet tab with the name "draw"
myDocument = xl.workbook.addWorksheet("draw")
what_scale = 3
xoff = 150
yoff = 150
try:
# delete previous foundation drawing shape
# clean slate
myDocument.Shapes("FoundationDrawing").Delete()
except:
pass
## INPUT FROM USER
# ===============
# DRAWING params from user
drawing_parameters = xl.InputBox("Drawing Parameters: Scale, Xoff, Yoff", Type=2)
if drawing_parameters != "":
what_scale, xoff, yoff = [float(e) for e in drawing_parameters.split()]
# CONCRETE params from user
rebarparameters = xl.InputBox("Foundation Parameters: Cover Xdim YDim", Type=2)
strmylist = [e for e in rebarparameters.split()]
# string variables
strCover, strXdim, strYdim = strmylist
# float variables
mylist = [float(e) for e in rebarparameters.split()]
Cover, Xdim, Ydim = mylist
# REBAR params from user
rebarparameters = xl.InputBox("Rebar Parameters: VBar Xspace HBar YSpace", Type=2)
# string variables
strmylist = [e for e in rebarparameters.split()]
strVbar, strXspace, strHbar, strYspace = strmylist
# float variables
mylist = [float(e) for e in rebarparameters.split()]
Vbar, Xspace, Hbar, Yspace = mylist
## HORIZONTAL BARS
# ===============
# initialize list of line used in rebar drawing later
mylines = []
# initialize list of shapes used in selecting later
myselection = []
xstart = Cover
xend = Xdim * 12 - Cover
ystart = Cover
yend = Ydim * 12 - Cover
xstart_rebar = what_scale * (xstart) + xoff
xend_rebar = what_scale * (xend) + xoff
xstart_foundation = what_scale * (xstart - Cover) + xoff
xend_foundation = what_scale * (xend + Cover) + xoff
xdiff_foundation = xend_foundation - xstart_foundation
# draw horz rebar
ycount = rebarcount(ystart, yend, Yspace)
# build line coordinates
for n in rebarrange(ystart, yend, ycount):
nq = what_scale * n + yoff
mylines.append([xstart_rebar, nq, xend_rebar, nq])
# draw lines
for e in mylines:
aaa = msxl.AddConnector(myDocument, e[0], e[1], e[2], e[3])
msxl.SetLineProperties(aaa,
visible=True,
weight=0.75 * what_scale,
forecolor=(0xFF0000))
myselection.append(aaa)
# gather horz bars, put them in a shape group,
# name the shape group
selectreplaceflag = 0
for e in myselection:
if selectreplaceflag == 0:
e.Select(Replace=True)
else:
e.Select(Replace=False)
selectreplaceflag = 1
horzbars = xl.Selection.ShapeRange.Group()
horzbars.Name = "horz_bars"
## VERTICAL BARS
# =============
mylines = []
myselection = []
ystart_rebar = what_scale * (ystart) + yoff
yend_rebar = what_scale * (yend) + yoff
ystart_foundation = what_scale * (ystart - Cover) + yoff
yend_foundation = what_scale * (yend + Cover) + yoff
ydiff_foundation = yend_foundation - ystart_foundation
# draw vert rebar
xcount = rebarcount(xstart, xend, Xspace)
# build line coordinates
for n in rebarrange(xstart, xend, xcount):
nq = what_scale * n + xoff
mylines.append([nq, ystart_rebar, nq, yend_rebar])
# draw lines
for e in mylines:
aaa = msxl.AddConnector(myDocument, e[0], e[1], e[2], e[3])
msxl.SetLineProperties(aaa,
visible=True,
weight=0.75 * what_scale,
forecolor=(0xFF0000))
myselection.append(aaa)
# gather vert bars, put them in a shape group,
# name the shape group
selectreplaceflag = 0
for e in myselection:
if selectreplaceflag == 0:
e.Select(Replace=True)
else:
e.Select(Replace=False)
selectreplaceflag = 1
vertbars = xl.Selection.ShapeRange.Group()
vertbars.Name = "vert_bars"
## ALL BARS
# =============
# gather all bars, put them in a shape group,
# name the shape group
horzbars.Select(Replace=True)
vertbars.Select(Replace=False)
allbars = xl.Selection.ShapeRange.Group()
allbars.Name = "all_bars"
# https://learn.microsoft.com/en-us/office/vba/api/excel.xlplacement
msxl.SetObjectProperties(allbars, placement="free")
allbars.LockAspectRatio = -1 # msoTrue=-1
## CONCRETE
# ========
# depict the foundation rectangle,
# name the shape group
fnd_concrete = msxl.AddShape(myDocument,
1,
xstart_foundation,
ystart_foundation,
xdiff_foundation,
ydiff_foundation)
fnd_concrete.Name = "foundation_concrete"
fnd_concrete.LockAspectRatio = -1 # msoTrue=-1
msxl.SetObjectFill(fnd_concrete,
fillvisible=False,
fillforecolor=(0xFFFFFF))
fnd_concrete.ZOrder(1) # msoSendToBack
## FOUNDATION
# ==========
xl.Range("A1").Select
xl.CutCopyMode = False # UNselecting everything
# gather all foundation aspects, put them in a shape group,
# name the shape group
allbars.Select(Replace=True)
fnd_concrete.Select(Replace=False)
allfoundation = xl.Selection.ShapeRange.Group()
allfoundation.LockAspectRatio = -1 # msoTrue=-1
allfoundation.Name = "all_foundation"
## TEXT BOX
# ========
# determine placement of rebar spec textbox
ulcornerx, ulcornery = xstart_rebar, yend_foundation + 10
txt_box = msxl.AddTextbox(expr=myDocument,
Orient=1,
Left=ulcornerx,
Top=ulcornery,
Width=50,
Height=12)
txt_box.TextFrame2.TextRange.Characters.Text = "".join(
[
"[X (horz): ",
strXdim,
" feet] #",
strVbar,
" @ ",
strXspace,
" (",
str(xcount),
" bars)",
"\r",
"[Y (vert): ",
strYdim,
" feet] #",
strHbar,
" @ ",
strYspace,
" (",
str(ycount),
" bars)",
"\r",
"Cover: ",
strCover,
" inches",
]
)
msxl.SetTextFrame2Properties(txt_box,
fontsize=15,
fontbold=True,
vertanchor="middle",
horzanchor="left",
wordwrap=False,
autosize=True)
msxl.SetObjectFill(txt_box, fillvisible=True, fillforecolor=(0xFFFF99))
msxl.SetObjectProperties(txt_box, placement="free")
txt_box.LockAspectRatio = -1 # msoTrue=-1
txt_box.Name = "foundation_text"
## WRAP-UP
# =============
# gather all drawing aspects, put them in a shape group,
# name the shape group
allfoundation.Select(Replace=True)
txt_box.Select(Replace=False)
allfoundationandlabel = xl.Selection.ShapeRange.Group()
allfoundationandlabel.LockAspectRatio = -1 # msoTrue=-1
allfoundationandlabel.Name = "FoundationDrawing"
# https://learn.microsoft.com/en-us/office/vba/api/excel.xlplacement
msxl.SetObjectProperties(allfoundationandlabel, placement="free")
## END OF PROGRAM