1

As a follow-up to several questions, I've come up with the following MWE, with the aim of filling an array (via arrayjobx) with values loaded from a CSV file.

The desired output is to print something like this:

---------------------------------------
|            |   John Doe (084754)    |
|  Students: |  Carl Sagan (458736)   |
|            | Peanut Butter (432756) |
---------------------------------------

The CSV:

Campo,Valor,Aux
alumno,"John Doe","084754"
alumno,"Carl Sagan","458736"
alumno,"Peanut Butter","432576"

The LaTeX document:

\documentclass{minimal}

\usepackage{arrayjobx,datatool,multirow,forloop}

\newcounter{numst}

% Offending line vvv
\newcommand{\addstudent}[2]{\expandafter\addstudentaux\expandafter{#1}\expandafter{#2}}

\newcommand{\addstudentaux}[2]{%
    \stepcounter{numst}%
    \ifthenelse{\equal{\value{numst}}{1}}{\newarray\Students\newarray\Boletas}{}
    \Students(\arabic{numst})={#1}%
    \Boletas(\arabic{numst})={#2}%
}

\newcommand{\IsEmptyElement}[2]{\ifthenelse{\boolean{emptydata}}{#1}{#2}}

\AtEndDocument{\ifthenelse{\value{numst} > 0}{\delarray\Students\delarray\Boletas}{}}

\begin{document}
    \DTLloaddb{Datos}{datos.csv}
    \DTLforeach{Datos}{\campo=Campo,\valor=Valor,\valorb=Aux}{%
        \ifthenelse{\equal{\campo}{alumno}}{%
            \addstudent{\valor}{\valorb}
        }{}
    }

    \begin{tabular}{cc}
        \ifthenelse{\value{numst} > 0}{%
            \ifthenelse{\value{numst} = 1}{%
                \textbf{Student:} & \Students(1) \\
                \textbf{ID:} & \Boletas(1) \\
            }{%
                \multirow{\value{numst}}{*}{\textbf{Students:}}%
                \newcounter{st}%
                \forloop{st}{1}{\not{\value{st} > \value{numst}}}{%
                    \checkBoletas(\arabic{st})%
                    & \Students(\arabic{st}) \IsEmptyElement{}{(\Boletas(\arabic{st}))} \\%
                }%
            }
        }{}
    \end{tabular}
\end{document}

Output:

enter image description here

How can I retrieve these values correctly? \expandafter only helps on retrieving, at most, one value successfully. Thanks in advance!

EDIT: I'm doing it this way as there'll be other data appended at the end of the table.

1

Your use of expansion was passing the wrong items to \addstudentaux. Instead, I've used a \begingroup\edef\x{\endgroup <stuff>}\x trick to expand content in <stuff>:

enter image description here

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{datos.csv}
Campo,Valor,Aux
alumno,"John Doe","084754"
alumno,"Carl Sagan","458736"
alumno,"Peanut Butter","432576"
\end{filecontents*}

\usepackage{arrayjobx,datatool,multirow,forloop}

\newcounter{numst}

\newcommand{\addstudent}[2]{%
    \stepcounter{numst}%
    \ifthenelse{\equal{\value{numst}}{1}}{\newarray\Students\newarray\Boletas}{}
    \Students(\arabic{numst})={#1}%
    \Boletas(\arabic{numst})={#2}%
}

\newcommand{\IsEmptyElement}[2]{\ifthenelse{\boolean{emptydata}}{#1}{#2}}

\AtEndDocument{\ifthenelse{\value{numst} > 0}{\delarray\Students\delarray\Boletas}{}}

\begin{document}
\DTLloaddb{Datos}{datos.csv}
\DTLforeach{Datos}{\campo=Campo,\valor=Valor,\valorb=Aux}{%
  \ifthenelse{\equal{\campo}{alumno}}{%
    \begingroup\edef\x{\endgroup\noexpand\addstudent{\valor}{\valorb}}\x
  }{}
}

\begin{tabular}{cc}
  \ifthenelse{\value{numst} > 0}{%
    \ifthenelse{\value{numst} = 1}{%
      \textbf{Student:} & \Students(1) \\
      \textbf{ID:} & \Boletas(1) \\
    }{%
      \multirow{\value{numst}}{*}{\textbf{Students:}}%
      \newcounter{st}%
      \forloop{st}{1}{\not{\value{st} > \value{numst}}}{%
        \checkBoletas(\arabic{st})%
        & \Students(\arabic{st}) \IsEmptyElement{}{(\Boletas(\arabic{st}))} \\%
      }%
    }
  }{}
\end{tabular}
\end{document}

Without the bigger picture, there's not much one can do in terms of code suggestion and/or improvement(s).


Here is just a simple implementation that achieves the same output without using arrayjobx:

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{datos.csv}
Campo,Valor,Aux
alumno,"John Doe","084754"
alumno,"Carl Sagan","458736"
alumno,"Peanut Butter","432576"
\end{filecontents*}

\usepackage{datatool}

\begin{document}
\DTLloaddb{Datos}{datos.csv}

\begin{tabular}{cc}
  \textbf{Students:} &
  \begin{tabular}{@{}c@{}}
    \DTLforeach{Datos}{\campo=Campo,\valor=Valor,\valorb=Aux}{%
      \ifthenelse{\equal{\campo}{alumno}}{%
        \valor~(\valorb) \\
      }{}
    }
    \\[-\normalbaselineskip]
  \end{tabular}
\end{tabular}

\end{document}
  • Thanks for the response! What I wanted to do was a titlepage template, with data separated in a CSV file. The idea is to edit the CSV file, recompile and getting the document with all the fields updated. I'll try what you've put here. – logo_writer Sep 21 '15 at 18:23
  • Wonderful!!! It works flawlessly! Thank you! – logo_writer Sep 21 '15 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.