I have a counter and I want to create a table with as many rows as the counter automatically. Each row should be numbered.
Thanks
Use for example the forloop
package and a counter as loop variable.
I applied the counter numofrows
as threshold (here set to 25)
The length \fillinboxwidth
can be changed.
Although I am not fond of having to much lines in a table, I think, it's reasonable to have them if people fill in the table by hand.
\documentclass{article}
\newlength{\fillinboxwidth}
\setlength{\fillinboxwidth}{8cm}
\usepackage{forloop}
\newcounter{loopcounter}
\newcounter{numofrows}
\setcounter{numofrows}{25}
\begin{document}
\begingroup
\renewcommand{\arraystretch}{1.5}
\begin{tabular}{ |r|p{\fillinboxwidth}|}
\hline
\forloop{loopcounter}{1}{\value{loopcounter} < \numexpr\value{numofrows}}{%
\number\value{loopcounter} & \tabularnewline
\hline
}
\number\value{loopcounter} & \tabularnewline
\hline
\end{tabular}
\endgroup
\end{document}
A fancy solution with expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\filltheblanks}{om}
{% #1 = width, default fill; #2 = number of lines
\IfNoValueTF{ #1 }
{% no optional argument given, compute the available width
\jlanza_compute_width:n { #2 }
}
{% set the width of the column of blanks to the optional argument
\dim_set:Nn \l_tmpa_dim { #1 }
}
% build the table using the specified number of lines
\jlanza_build_table:n { #2 }
}
\cs_new_protected:Npn \jlanza_compute_width:n #1
{% #1 contains the number of rows, so we compute the width of the last number
\hbox_set:Nn \l_tmpa_box { #1 }
% set the width of the column of blanks to
% \columnwidth - (four intercolumn separators) - (width of the three rules)
% - the width of the last number
\dim_set:Nn \l_tmpa_dim
{
\columnwidth-4\tabcolsep-3\arrayrulewidth-\box_wd:N \l_tmpa_box
}
}
\cs_new_protected:Npn \jlanza_build_table:n #1
{
% set the temporary register to zero; we need a global one because we'll
% increment it inside a column cell, which forms a group
\int_gzero:N \g_tmpa_int
% start printing the table; issue \noindent to start at the left margin
\noindent
% the tabular specification: a right aligned column and a p column
% with the width established before
\begin{tabular}{|r|p{\l_tmpa_dim}|}
% top rule
\hline
% do as many times as stated (#1 is the number of rows)
\prg_replicate:nn { #1 }
{
% increment the counter
\int_gincr:N \g_tmpa_int
% print the counter's value
\int_to_arabic:n { \g_tmpa_int }
% advance to the next cell, finish it and draw a rule
& \\ \hline
}
% finish off the tabular
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\filltheblanks{10}
\filltheblanks[5cm]{6}
\end{document}
If the optional argument is not given, the width of the blanks is computed from the current column width, so the table will fill the column width. Otherwise the optional argument sets the width of the blanks.
The table is built by repeating the instruction “number & \\ \hline
” as many times as needed with \prg_replicate:nn
.
If the number is stored in a counter, say \newcounter{rows}
, you can call the command with
\filltheblanks{\value{rows}}
\prg_replicate:nn
and the other commands is in interface3.pdf
; for \NewDocumentCommand
see the documentation of xparse
.
Here another method in LaTeX2e which defines a macro \blanklist[<width>]{<number>}
:
\documentclass{article}
\newcounter{tablinegen}
\newcounter{tabrow}
\newcommand{\nl}{\stepcounter{tabrow}\\ \hline}
\newcommand{\blankline}{\thetabrow & \nl}
\newcommand{\blanklist}[2][.8\textwidth]{%
\begingroup
\setcounter{tablinegen}{0}
\let\tablines\empty%
\loop\ifnum\thetablinegen<#2
\stepcounter{tablinegen}
\expandafter\def\expandafter\tablines\expandafter{%
\tablines
\blankline
}%
\repeat
\blanklistformat{#1}}
\newcommand{\blanklistformat}[1]{
\renewcommand{\arraystretch}{1.5}
\begin{tabular}{|c|p{#1}|}
\hline
\# & Name \nl
\tablines
\end{tabular}
\endgroup
\setcounter{tabrow}{0}}
\begin{document}
\blanklist{10}
\end{document}
Note. All the features of @egreg's solution are preserved in this one.
The \xintiloop
from xinttools is an expandable loop, which provides an iteration index via the macro \xintiloopindex
, hence this provides a simple minded tool for generating rows inside a tabular (the code for \xintiloop
itself is only a few lines long, thus if one wished to not load any package, one could put it directly in the source file).
Customize as desired. No counter is used for the rows themselves, only for the total number of rows, as in the OP's question. The second example uses an explicit number rather than a counter also for the total number of generated rows.
The things could be put into a macro in one wished, in case one had to do many tables of the same type with small variations.
To be honest, although doing the job here, \xintiloopindex
has rather stringent limitations, one can not use it within braces such as \textbf{\xintiloopindex}
, and here one would have to do \expandafter\bfseries\xintiloopindex
. I thus can not really recommend my solution to the average LaTeX user, because making it work in more advanced contexts requires advanced understanding of how TeX
builds alignments.
I thus have now included another way using \xintloop
, not \xintiloop
, but then some counter is used for indexing the rows.
Update: if you don't want to use any package, here is the code for \xintloop
which is used in the third table. I have renamed the thing \xloop
. Package xinttools
adds some extras (\xintbreakloop
, \xintbreakloopanddo
, \xintloopskiptonext
) which I don't translate here.
% code for an expandable loop, allowing nesting. See third table below for
% use example, with the original denomination \xintloop from package xinttools.
% the code is built in this way to allow extra structure (break, breakanddo, skip)
% which is not included here.
\makeatletter
\long\def\xloop #1#2\repeat {#1#2\xloop@again\fi\@gobble {#1#2}}%
\long\def\xloop@again\fi\@gobble #1{\fi #1\xloop@again\fi\@gobble {#1}}%
\makeatother
\documentclass[a4paper]{article}
\usepackage{geometry}
\usepackage{xinttools}
\newcounter{nbofrows}
\begin{document}
\setcounter{nbofrows}{7}
\begin{table}[htbp]
\centering
\begin{tabular}{c|c|c|c|c|}
\#&Last name&First name&Age&Citizenship\\
\hline
\xintiloop [1+1]
\xintiloopindex&&&&\\\hline
\unless
\ifnum\xintiloopindex=\value{nbofrows}%
\repeat
\end{tabular}
\caption{First table}
\end{table}
% we don't *have* to use a counter for the number of rows.
\begin{table}[htbp]
\centering
\begin{tabular}{c|c|c|c|c|}
\#&\makebox[.2\columnwidth]{Last name}&
\makebox[.2\columnwidth]{First name}&
\makebox[.2\columnwidth]{Age}&
\makebox[.2\columnwidth]{Citizenship}\\
\hline
\xintiloop [1+1]
\xintiloopindex &&&&\\\hline
\unless\ifnum \xintiloopindex=13 % leave a space after explicit number
\repeat
\end{tabular}
\caption{Second table}
\end{table}
\begin{table}[htbp]
\centering
\begin{tabular}{c|c|c|c|c|}
\#&\makebox[.2\columnwidth]{Last name}&
\makebox[.2\columnwidth]{First name}&
\makebox[.2\columnwidth]{Age}&
\makebox[.2\columnwidth]{Citizenship}\\
\hline
\setcounter{nbofrows}{0}%
\xintloop % braces are needed to hide the tabulation and \\ (technical reason)
{\stepcounter{nbofrows}\textbf{\arabic{nbofrows}}&&&&\\\hline }%
\unless\ifnum \value{nbofrows}=17 % leave a space after explicit number
\repeat
\end{tabular}
\caption{Third table}
\end{table}
\end{document}
\documentclass{...}
and ending with\end{document}
.