# A macro for looping through a pgfplotstable set by cell

Hi following on from the following question on multi-line headers with pgfplotstable, the solution was to set each affected cell individually. I decided to throw together a command to do that but keep hitting an the error Argument of \reserved@a has an extra }. <inserted text> \par

The snippet I'm using is attached below -

\DeclareRobustCommand{\pgfplotstableeach}[4][1]{
\foreach \col in {#1,...,#2}
\foreach \ro in {0,...,#3}
{\ifthenelse{\col=#2 \AND \ro=#3}{every row \ro\  column \col/.style=\{#4\}}{every row \ro\  column \col/.style=\{#4\},}}
}


and this works fine to produce the text outside a pgfplotstabletypeset environment but fails inside one.


If I replace the macro with the text I want to input e.g. "every row 0 column 1/.style=..." it fails with a Missing \endcsname inserted. <to be read again> \protect. I actually thought this would be fairly straightforward but I'm completely bewildered by the error.

What am I doing wrong?

edited to include MWE below

\documentclass{article}
\usepackage{array,datatool,pgfplotstable}

\begin{filecontents}{sample.csv}
item,2008,2009,2010,2011
,Actual,Actual,Forecast,Forecast
,GBP,GBP,GBP,GBP
,('000),('000),('000),('000) rounded
Area 1 OP, 1000000,1500000,1750000,250000
Area 2 OP, 400000,500000, 450000,-50000
Area 51 OP, 300000,375000,390000,15000
No P, 1250000, 1000000, 950000, 50000
Residuals, 800000, 80000, 90000, 10000
\end{filecontents}

\DeclareRobustCommand{\pgfplotstableeach}[4][1]{
\foreach \col in {#1,...,#2}
\foreach \ro in {0,...,#3}
{\ifthenelse{\col=#2 \AND \ro=#3}
{every row \ro\  column \col/.style=\{#4\}}
{every row \ro\  column \col/.style=\{#4\},}}
}

\begin{document}

\pgfplotstabletypeset[fixed,
\pgfplotstableeach{4}{4}{string type}]\mystuff

\end{document}

-
\foreach takes the body of the loop in a {...} argument which you appear to be missing, apart from that it would be easier to understand the example if you posted a complete example from \documentclass to \end{document} showing the packages used and a test case for the construction. –  David Carlisle Oct 1 '12 at 11:51
hi @DavidCarlisle, MWE added. The \foreach loop works okay outside the pgfplotstabletypeset environment. I think its described in the Tikz/PGF Manual on loops as a special case where two \foreach commands are nested. (and I was being a bit lazy..) –  Tahnoon Pasha Oct 1 '12 at 13:52
oohh reading the manual: that's cheating:-) (sorry for the wrong comment in that case) –  David Carlisle Oct 1 '12 at 13:55

Your example relies on illegal assumptions on how expansion works in TeX/PGF. In your particular case, it suffers from two problems:

1. \foreach looses everything which has been set inside of it unless you explicitly declare it as global. In your case, it looses every option.

2. You cannot execute custom macros directly inside of option lists.

A solution for (1.) would be to collect all your options into one huge (global!) list and execute it after the \foreach statements.

A solution for (2.) is to set all these options before \pgfplotstabletypeset. You could surround the complete statements with curly braces: this would delimit the effect (just as inside of \foreach).

Interestingly, the solution for (1.) is much more involved than it sounds. This is because the expansion of TeX is different from almost anything else that you might have encountered.

Here is a solution. You may want to decide if you want to learn the details of expansion control (i.e. questions like "what is \toks*?" or "what is \expandafter?") by studying http://pgfplots.sourceforge.net/TeX-programming-notes.pdf

\documentclass{article}
\usepackage{array,datatool,pgfplotstable}

\begin{filecontents}{sample.csv}
item,2008,2009,2010,2011
,Actual,Actual,Forecast,Forecast
,GBP,GBP,GBP,GBP
,('000),('000),('000),('000) rounded
Area 1 OP, 1000000,1500000,1750000,250000
Area 2 OP, 400000,500000, 450000,-50000
Area 51 OP, 300000,375000,390000,15000
No P, 1250000, 1000000, 950000, 50000
Residuals, 800000, 80000, 90000, 10000
\end{filecontents}

\newcommand{\pgfplotstableeach}[4][1]{
\xdef\ACCUM{}%
\foreach \col in {#1,...,#2} {%
\foreach \ro in {0,...,#3}
{%
\toks0=\expandafter{\ACCUM}%
\edef\temp{every row \ro\space column \col/.style}%
\toks1={#4}%
\xdef\ACCUM{\the\toks0 \temp={\the\toks1},}%
}%
}%
\message{setting \meaning\ACCUM^^J}%
\expandafter\pgfplotstableset\expandafter{\ACCUM},
}

\begin{document}

\pgfplotstableeach{4}{4}{string type}
\pgfplotstabletypeset[fixed,]\mystuff

\end{document}


note that the example is incomplete; it results in compilation failures (because only selected cells have string type).

-
Thanks @ChristianFeuersanger for the detailed answer. Also a really useful package in pgfplotstable. I didn't understand your last point about selected cells however, would you mind elaborating a little bit? –  Tahnoon Pasha Oct 1 '12 at 21:16
Sorry scratch that query, I think you meant that col 0 also needed to be {string type}. A follow on question, when I compile this I get a , at the start of the row. Will an ifthenelse work to get rid of it or do I need to do something different? –  Tahnoon Pasha Oct 2 '12 at 8:52
I am sorry - the comma is in the line after \expandafter\pgfplotstableset\expandafter{\ACCUM} - simply replace it by %. commas inside of option lists can never hurt. –  Christian Feuersänger Oct 2 '12 at 17:43
A final question - sorry - when I add an option every head row/.style={after row={\caption{blah blah}\tabularnewline}} I get a \Generic error ... #4 \errhelp \@err@ which I don't without the macro. Any thoughts would be very gratefully received. –  Tahnoon Pasha Oct 3 '12 at 4:02
@TahnoonPasha Try to add the "debug" option to the option list. This will output the resulting tabular. Then: copy-paste this tabular environment into your normal document. This will reveal the problem (hopefully). –  Christian Feuersänger Oct 3 '12 at 6:19