1

from topic: position newcommand with variable from excel and error missing begin{document}

How can i use newcommand with text variable list to change number list?

Example:

AX - 1, AY - 0.5, AZ-2.0, AA - 4

BY - 1, BB - 2, BZ - 2.4, BX -1

Minimal code:

   \RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
AX,BY,1
AY,BB,2
AZ,BX,3
AX,BB,4
AZ,BZ,5
\end{filecontents*}

\documentclass{article}
\usepackage{datatool}
\usepackage[absolute,overlay]{textpos}
\DTLloaddb{mydata}{test.csv}
\newcommand{\A}[1]{\ifcase#1
\or1\or2\or4\or2.5\or0.5\fi}
\newcommand{\B}[1]{\ifcase#1
\or2\or3\or1\or3.5\or7\fi}

\begin{document}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}%
{%
\begin{textblock*}{5cm}(\A cm,\B cm)
\No
\end{textblock*}A
\pagebreak
\newpage
}%

\end{document}

Thank so much

latexforti
  • 2,091

1 Answers1

1

There are various ways to do that. Since you already load datatool, it may make sense to use it for this. I am relying a bit on this post, which explains how to create an associative array with this tool. So you add another database, which I store in distances.csv, and you can read the distance for a given value with

\getDist{<macro>}{<key>}%

where <macro> is the macro in which you store the result, and <key> is the identifier, i.e. something like AX or BY, say. This can be built in your loop.

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
AX,BY,1
AY,BB,2
AZ,BX,3
AX,BB,4
AZ,BZ,5
\end{filecontents*}

\begin{filecontents*}{distances.csv}
ID,dist
Ax,1
AY,0.5
AZ,2.0
AA,4
BY,1
BB,2
BZ,2.4
BX,1
\end{filecontents*}

\documentclass{article}
\usepackage{datatool}
\usepackage[absolute,overlay]{textpos}
\DTLloaddb{mydata}{test.csv}
\DTLloaddb{distdata}{distances.csv}

\begin{document}
\newcommand*{\getDist}[2]{%
\DTLgetvalueforkey{#1}{dist}{distdata}{ID}{#2}%
}
% 
\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}%
{%
\getDist{\tmpA}{\A}%
\getDist{\tmpB}{\B}%
\begin{textblock*}{5cm}(\tmpA cm,\tmpB cm)
\No
\end{textblock*}A
\pagebreak
\newpage
}%
% 
\end{document}

Notice that this is by no means the only way. I add something that does the same but does not rely on any packages, and in which case the result is expandable. You get the values "in" with

  \AssignValues{{AX,1},{AY,0.5},{AZ,2.0},{AA,4},{BY,1},{BB,2},{BZ,2.4},{BX,1}}

and read them out with \getpftnum{<key>}. This works, too (by more or less copying what for instance pgf keys do).

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
AX,BY,1
AY,BB,2
AZ,BX,3
AX,BB,4
AZ,BZ,5
\end{filecontents*}
\documentclass{article}
\usepackage{datatool}
\usepackage[absolute,overlay]{textpos}
\DTLloaddb{mydata}{test.csv}
\makeatletter
\def\assign@value#1,#2;{\expandafter\edef\csname pft@num#1\endcsname{#2}}
\newcommand{\AssignValues}[1]{\@for\next:=#1\do{\expandafter\assign@value\next;}}
\newcommand{\getpftnum}[1]{\csname pft@num#1\endcsname}
\makeatother
\begin{document}
\AssignValues{{AX,1},{AY,0.5},{AZ,2.0},{AA,4},{BY,1},{BB,2},{BZ,2.4},{BX,1}}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}%
{%
\begin{textblock*}{5cm}(\getpftnum{\A}cm,\getpftnum{\B}cm)
\No
\end{textblock*}A
\pagebreak
\newpage
}%
% 
\end{document}