在我的数据库中,列数相当大。因此,我试图消除任何仅包含 0 个条目的列。
列数和列键都是预先知道的。因此,我遍历数据库并生成要省略的列的列表。当我这样做时,提供的省略列表似乎被忽略了。下面我省略了确定哪些列是
以下情况没有问题:
手动指定的省略列表:因此
\DTLdisplaydb[A,C]{myDB}
工作正常。省略具有固定内容的宏指定的列表:所以
\def\ListOfColumnsToOmit{A,C} \DTLdisplaydb[\ListOfColumnsToOmit]{myDB}
也工作正常。
仅当我计算要省略的列的列表并\ListOfColumnsToOmit
通过\AddToCommaSeparateList
宏添加它们时,事情才会中断。
因此,正确的结果是最后一张表与中间两张表相同。
参考:
代码:
\documentclass{article}
\usepackage{xstring}
\usepackage{datatool}
% Make csv for question
\usepackage{filecontents}
\begin{filecontents*}{MyData.csv}
A, B, C, D, E
0, 1, 0, 2, 3
0, 0, 0, 4, 4
0, 2, 0, 0, 5
\end{filecontents*}
\makeatletter
% https://tex.stackexchange.com/questions/83595/expansion-issue-when-adding-to-csv-list-from-within-a-foreach/
\newcommand*{\AddToCommaSeparateList}[3][,\space]{%
% #1 = separator
% #2 = listname
% #3 = content to add to CSV list
\IfStrEq{#2}{}{}{\g@addto@macro#2{#1}}% Don't add a leading comma in list
%
% Extra brace group in case #3 contains a comma
\begingroup\edef\x{\endgroup%
\noexpand\g@addto@macro\noexpand#2{{#3}}}\x%
}%
\makeatother
\begin{document}
\DTLloaddb{myDB}{MyData.csv}
With \emph{no} omit list provided:\par
\noindent\DTLdisplaydb{myDB}%
With manually specified omit list:\par
\noindent\DTLdisplaydb[A,C]{myDB}%
\def\ListOfColumnsToOmit{A,C}
With fixed macro omit list:\par
\noindent\DTLdisplaydb[\ListOfColumnsToOmit]{myDB}%
\def\ListOfColumnsToOmit{}
\AddToCommaSeparateList{\ListOfColumnsToOmit}{A}%
\AddToCommaSeparateList{\ListOfColumnsToOmit}{C}%
With generated macro omit list:\par
\noindent\DTLdisplaydb[\ListOfColumnsToOmit]{myDB}%
The omit list was: \ListOfColumnsToOmit
\end{document}
答案1
\ListOfColumnsToOmit
最后一种情况下的展开式为
{A},\space {C}
这显然是错误的。即使省略了\space
没有任何用处的 ,额外的括号也无法datatool
识别列名。
如果我使用
\newcommand*{\AddToCommaSeparateList}[3][,]{%
% #1 = separator
% #2 = listname
% #3 = content to add to CSV list
\IfStrEq{#2}{}{}{\g@addto@macro#2{#1}}% Don't add a leading comma in list
%
\begingroup\edef\x{\endgroup
\noexpand\g@addto@macro\noexpand#2{#3}}\x
}
那么结果与“手动”示例相同。