2

This question extends the solution from Generate rows in table using \multido (or something similar). Based on the solution to the linked question, I understand how to use a \foreach loop to build rows for a tabular table. My question is how can I include a horizontal line (border) between each row? In a static tabular I would include \hline but that doesn't seem to work when using the \foreach loop.

Edit 1 ---

MWE below.

\documentclass{article}
\usepackage{pgffor}

\makeatletter \newcommand{\Buildtable}{% \def\tableData{}% empty table \foreach \n in {1,...,5}{% \protected@xdef\tableData{\tableData \n & A\n & B\n & C\n \} % < adding \hline here causes error } \begin{tabular}{|l|l|l|l|} \hline \textbf{Num} & \textbf{Col A} & \textbf{Col B} & \textbf{Col C} \ \hline \tableData \hline \end{tabular} } \makeatother

\begin{document} \Buildtable \end{document}

Which results in

enter image description here

I'm looking to achieve the equivalent of "all borders" in Excel (shown below).

enter image description here

Adding \hline within the braces, but after \\, on the indicated line results in the error

Missing control sequence inserted.
<inserted text> 
                \inaccessible 
l.19     \Buildtable

I do not understand why adding this causes an error.

  • 1
    please always show a small but complete example. if by \foreach you mean the loop from pgf that adds a tex group around each iteration so is usually unsuitable for generating table rows. you may have worked around that but then whether or not \hline works depends on code you have not shown. – David Carlisle Mar 20 '22 at 10:36

1 Answers1

1

The problem is that \hline won't survive multiple \protected@xdef instructions. You can \let it to \relax in the loop cycles, it will have its standard meaning when doing \Buildtable.

\documentclass{article}
\usepackage{pgffor}

\makeatletter \newcommand{\Buildtable}{% \def\tableData{}% empty table \foreach \n in {1,...,5}{% \let\hline\relax \protected@xdef\tableData{\tableData \n & A\n & B\n & C\n \ \hline} } \begin{tabular}{|l|l|l|l|} \hline \textbf{Num} & \textbf{Col A} & \textbf{Col B} & \textbf{Col C} \ \hline \tableData \end{tabular} } \makeatother

\begin{document} \Buildtable \end{document}

picture

Here's a generic command for generating such tables by giving the number of columns and rows.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\Buildtable}{mm} {% #1 = number of columns, #2 = number of rows \doomedjupiter_buildtable:nn { #1 } { #2 } }

\tl_new:N \l__doomedjupiter_buildtable_body_tl

\cs_new_protected:Nn \doomedjupiter_buildtable:nn { % header \tl_set:Nn \l__doomedjupiter_buildtable_body_tl { \hline \textbf{Num} } \int_step_inline:nn { #1 } { \tl_put_right:Nn \l__doomedjupiter_buildtable_body_tl { & \textbf{Col ~ \int_to_Alph:n { ##1 }} } } \tl_put_right:Nn \l__doomedjupiter_buildtable_body_tl { \ \hline } % make rows \int_step_inline:nn { #2 } { \tl_put_right:Nn \l__doomedjupiter_buildtable_body_tl { ##1 } \int_step_inline:nn { #1 } { \tl_put_right:Nn \l__doomedjupiter_buildtable_body_tl { & \int_to_Alph:n { ####1 } ##1 } } \tl_put_right:Nn \l__doomedjupiter_buildtable_body_tl { \ \hline } } % make the table \begin{tabular}{|l|*{#1}{l|}} \tl_use:N \l__doomedjupiter_buildtable_body_tl \end{tabular} }

\ExplSyntaxOff

\begin{document}

\Buildtable{3}{5}

\bigskip

\Buildtable{6}{4}

\end{document}

enter image description here

egreg
  • 1,121,712