用于循环遍历单元格设置的 pgfplotstable 的宏

用于循环遍历单元格设置的 pgfplotstable 的宏

你好,接下来是以下问题使用 pgfplotstable 的多行标题,解决方案是单独设置每个受影响的单元格。我决定拼凑一个命令来做到这一点,但不断遇到错误Argument of \reserved@a has an extra }. <inserted text> \par

我正在使用的代码片段如下 -

\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\},}}   
}

这在环境之外生成文本很有效,pgfplotstabletypeset但在环境内部却失败了。

我已尝试过\newcommand\newcommand{\protect\pgfplotstableeach}{<macro>}但都没有用。

如果我用我想要输入的文本替换宏,例如,"every row 0 column 1/.style=..."它会失败并显示Missing \endcsname inserted. <to be read again> \protect。我实际上认为这会相当简单,但我对错误完全感到困惑。

我究竟做错了什么?

编辑以包括下面的 MWE

\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}

\pgfplotstableread[col sep=comma,header=false]{sample.csv}\mystuff

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

\end{document}

答案1

您的示例依赖于对 TeX/PGF 中扩展工作方式的非法假设。 在您的特定情况下,它存在两个问题:

  1. \foreach失去一切除非您明确将其声明为全局变量,否则该变量已在内部设置。对于您的情况,它会失去所有选项。

  2. 您不能直接在选项列表内执行自定义宏。

(1.) 的解决方案是将所有选项收集到一个巨大的(全局!)列表中,并在语句之后执行它\foreach

(2.) 的解决方案是在 之前设置所有这些选项\pgfplotstabletypeset。您可以用花括号将完整的语句括起来:这将限定效果(就像 内部一样\foreach)。

有趣的是,(1.) 的解决方案比听起来要复杂得多。这是因为 TeX 的扩展与你可能遇到的几乎所有其他扩展都不同。

这是一个解决方案。你可能想决定是否要学习扩展控制的细节(即“什么是\toks*?”或“什么是\expandafter?”之类的问题),方法是研究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}

\pgfplotstableread[col sep=comma,header=false]{sample.csv}\mystuff

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

\end{document}

请注意,该示例不完整;它会导致编译失败(因为只有选定的单元格才有string type)。

相关内容