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
  • 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. Mar 20, 2022 at 10:36

1 Answer 1

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .