5

With the datatool package there is a \DTLiffirstrow. I am looking for a similar command to detect the last row, \DTLiflastrow, but could not find one. I attempted to create my own but was not successful.

If the title row is separate form the data one can use

\DTLiffirstrow{\\\Midrule}{\\\cmidrule{1-2}}

to produce the horizontal lines as in:

enter image description here

But if the title is part of the data, I don't see how to do that without an equivalent of \DTLiflastrow. Without which I get an extra blank line at the bottom:

enter image description here

If you un-comment my attempt of \DTLifLastRow you get:

! Missing number, treated as zero. \dtlrows@

Code:

\documentclass{article}

\usepackage{datatool}
\usepackage{booktabs}
\def\Midrule{\midrule[\heavyrulewidth]}

% Make csv in question
\usepackage{filecontents}
\begin{filecontents*}{scientists2.csv}
name,surname,
First,Last
Albert,Einstein,
Marie,Curie,
Thomas,Edison,
\end{filecontents*}

\newcommand{\DTLifLastRow}[3]{%
    % #1 = db
    % #2 = code for last row
    % #3 = code for all other rows
        \dtlifnumeq
            {\DTLrowcount{#1}}
            {\DTLcurrentindex}% {\value{DTLrowi}}%
            {#2}{#3}%
}

\begin{document}

\DTLloaddb{myDB}{scientists2.csv}
%\DTLdisplaydb{myDB}% Useful for debugging.

\begin{tabular}{ll}\toprule
    \textbf{First Name} & \textbf{Last Name}%
    \DTLforeach*{myDB}{\Name=name,\Surname=surname}{%
        \DTLiffirstrow{\\\Midrule}{\\\cmidrule{1-2}}%
        \Name & \Surname
    }%
    \\\bottomrule
\end{tabular}

\bigskip\noindent
But what if the first row of the table was the header row.
How do I produce the above table format without the manual header.
\medskip

\begin{tabular}{ll}\toprule
    \DTLforeach*{myDB}{\Name=name,\Surname=surname}{%
        \Name & \Surname
        \DTLiffirstrow{\\\Midrule}{\\\cmidrule{1-2}}%
        %  I think I need to replace the above with something like this:
        %\DTLiffirstrow{\\\Midrule}{%
        %       \DTLifLastRow{}{myDB}{\\\cmidrule{1-2}}%
        %}%
    }%
    \\\bottomrule
\end{tabular}
\end{document} 

1 Answer 1

4

It seems to be one of the usual problems of doing things already inside a tabular. The best seems to be first populating a token register with the table contents and then delivering it inside the tabular:

\documentclass{article}

\usepackage{datatool}
\usepackage{booktabs}
\def\Midrule{\midrule[\heavyrulewidth]}

% Make csv in question
\usepackage{filecontents}
\begin{filecontents*}{scientists2.csv}
name,surname,
First,Last
Albert,Einstein,
Marie,Curie,
Thomas,Edison,
\end{filecontents*}

\newcommand{\DTLifLastRow}[3]{%
  % #1 = db
  % #2 = code for last row
  % #3 = code for all other rows
  \dtlifnumeq
    {\DTLrowcount{#1}}
    {\DTLcurrentindex}%
    {#2}{#3}%
}

\newtoks\grilltoks

\begin{document}

\DTLloaddb{myDB}{scientists2.csv}
%\DTLdisplaydb{myDB}% Useful for debugging.

\grilltoks={}
\DTLforeach*{myDB}{\Name=name,\Surname=surname}
 {%
  \edef\temp{\Name & \Surname}%
  \grilltoks=\expandafter{\the\expandafter\grilltoks\temp}%
  \DTLiffirstrow
   {\grilltoks=\expandafter{\the\grilltoks\\\Midrule}}
   {%
    \DTLifLastRow{myDB}{}{\grilltoks=\expandafter{\the\grilltoks\\\cmidrule{1-2}}}%
   }%
 }
\begin{tabular}{ll}\toprule
\the\grilltoks
    \\\bottomrule
\end{tabular}
\end{document}

enter image description here

Actually, datatool has a \DTLiflastrow command, which however doesn't work as expected: indeed

\DTLforeach*{myDB}{\Name=name,\Surname=surname}
  {\DTLiflastrow{LAST\endgraf}{NOT LAST\endgraf}}

prints

NOT LAST
NOT LAST
LAST
NOT LAST

2
  • I do not see \DTLiflastrow in the user documentation (dated 2012-09-25) of datatool, but does appear to exist. Nov 22, 2012 at 19:30
  • @PeterGrill It is in the code; I don't know why it isn't in the doc.
    – egreg
    Nov 22, 2012 at 20:36

You must log in to answer this question.

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