Datatool:不能在嵌套循环“foreach”中使用 \DTLreplaceentryforrow

Datatool:不能在嵌套循环“foreach”中使用 \DTLreplaceentryforrow

在以下 MWE(没有实际意义,但很简洁:))中,我有两个嵌套DTLforeach循环。行“ %for debugging”中显示的值显示了循环的预期行为DTLforeach:第一个循环在所有条目(4 行)上运行。对于这些行中的每一行,第二个循环在行上运行。但是命令应该用“ ”\DTLreplaceentryforrow{a}{xx}替换值,却没有这样做。请注意,如果您从内部循环移出,那么它将按预期工作。因此,这个命令在嵌套循环中似乎存在问题。(REM:根据 datatools-documentation,最多可以嵌套三次。)axx\DTLreplaceentryforrow{a}{xx}DTLforeach

\documentclass[12pt]{article}
\usepackage{datatool}
\begin{document}
\DTLnewdb{table}
\DTLrowcount{table}

\DTLnewrow{table}
\DTLnewdbentry{table}{a}{1}
\DTLnewdbentry{table}{b}{oui}
\DTLnewrow{table}
\DTLnewdbentry{table}{a}{2}
\DTLnewdbentry{table}{b}{oui}
\DTLnewrow{table}
\DTLnewdbentry{table}{a}{1}
\DTLnewdbentry{table}{b}{non}
\DTLnewrow{table}
\DTLnewdbentry{table}{a}{2}
\DTLnewdbentry{table}{b}{non}

\section{original table}

\DTLdisplaydb{table}

\section{modified table}

\DTLforeach{table}{\a=a,\b=b}{%
\DTLforeach{table}{\aa=a,\bb=b}{%
a= \a , b= \b , aa=\aa , bb=\bb % only for debugging

\DTLreplaceentryforrow{a}{xx}
}
}

\DTLdisplaydb{table}
\end{document}

答案1

问题可能是由于循环替换和分组的内部处理而引起的。
如果您的外循环从不处于写入位置(永远不会更改表的内容),则可以使用带星号的版本,它是只读的,不会保存表的状态。

IE

\DTLforeach*{table}{\a=a,\b=b}{%
    \DTLforeach{table}{\aa=a,\bb=b}{%
        a= \a , b= \b , aa=\aa , bb=\bb % only for debugging
        \DTLreplaceentryforrow{a}{xx}
    }
}

这将产生您想要的结果。我猜这是表循环的安全性,不能对同一个表进行双重 foreach。我建议采用上述策略。但是,如果您希望在两个循环中都进行更改,则必须采用其他方法。我不知道该怎么做。

答案2

虽然不是一个解决方案,但至少是来自 Nicola Talbot (的作者) 的解释datatool

数据库的内容存储在单个标记寄存器 ( toks) 中,标记指示行和单元格。编辑数据库时,标记的内容被分成三部分:需要替换的部分、之前的所有部分和之后的所有部分。然后,更新后的数据库由合并之前部分、替换部分和之后部分组成。为了提高效率,循环会复制 \DTLforeach当前行,并且只操作行副本而不是整个数据库。在迭代结束时,数据库中的当前行将被副本替换。在示例中的嵌套循环中,当两个循环都在编辑数据库的同一行时,该行有两个副本,一个由外循环操作,另一个由内循环操作。在内循环结束时,数据库将使用内副本更新,但当外循环到达迭代结束时,它会替换其行,从而覆盖内循环的效果。

相关内容