DTLminforcolumn 不适用于空行

DTLminforcolumn 不适用于空行

我使用 datatool 解析 CSV 文件。我想使用 makro \DTLminforcolumn 来计算列的最小值。如果每行都有一个值,则此方法有效,但如果有空行,则效果不佳。我如何告诉 datatool 忽略空行?

梅威瑟:

\documentclass{article}
\usepackage{filecontents}
\usepackage{datatool}

\begin{filecontents*}{example1.csv}
title;value
test1;1
test2;
test3;3
test4;2
\end{filecontents*}
\begin{filecontents*}{example2.csv}
title;value
test1;1
test2;2
test3;3
test4;4
\end{filecontents*}

\begin{document}
    \DTLsetseparator{;}%
    \DTLloaddb{a}{example1.csv}
    \DTLminforcolumn{a}{value}{\minValueFirstExample}
    
    \DTLsetseparator{;}%
    \DTLloaddb{b}{example2.csv}
    \DTLminforcolumn{b}{value}{\minValueSecondExample}
    
    Min Value1: \minValueFirstExample\\ %Should be 1 and not 2
    Min Value2: \minValueSecondExample %Is correct
\end{document}

答案1

加载包后添加以下几行datatool

\usepackage{xpatch}
\patchcmd\DTLminforcolumn{%
  \DTLmin{#3}{#3}{\DTLthisval}%
}{%
  \ifdefempty\DTLthisval{}{\DTLmin{#3}{#3}{\DTLthisval}}%
}{}{}

在此处输入图片描述

\documentclass{article}
\usepackage{datatool}
\usepackage{xpatch}
\patchcmd\DTLminforcolumn{%
  \DTLmin{#3}{#3}{\DTLthisval}%
}{%
  \ifdefempty\DTLthisval{}{\DTLmin{#3}{#3}{\DTLthisval}}%
}{}{}
\begin{document}
    \DTLlistskipemptytrue
    \DTLsetseparator{;}%
    \DTLloaddb{a}{example1.csv}
    \DTLminforcolumn{a}{value}{\minValueFirstExample}
    
    \DTLsetseparator{;}%
    \DTLloaddb{b}{example2.csv}
    \DTLminforcolumn{b}{value}{\minValueSecondExample}

    \noindent
    Min Value1: \minValueFirstExample\\ %Should be 1 and not 2
    Min Value2: \minValueSecondExample %Is correct
\end{document}

解释。 \DTLminforcolumn定义datatool.sty如下:

\newcommand*{\DTLminforcolumn}[3]{% #1 database, #2 col name, #3 return value
  \def#3{}%                                   #3 := ""
  \DTLifdbexists{#1}{%                        if database #1 exists:
     \@sDTLifhaskey{#1}{#2}{%                   if column #2 exists in db #1:
       \@sdtlforcolumn{\DTLthisval}{#1}{#2}{%     for DTLthisval in column #2:
         \ifdefempty{#3}{%                          if #3 == "":
           \let#3\DTLthisval%                         #3 := DTLthisval
         }{%                                        else:
           \DTLmin{#3}{#3}{\DTLthisval}%              #3 := min(#3,DTLthisval)
         }%                                     
       }% 
     }{%                                        else:
       \PackageError{datatool}{Key `#2' %         raise exception
       doesn't exist in database `#1'}{}%
     }%
  }{%                                         else:
    \PackageError{datatool}{Data base %         raise exception
    `#1' doesn't exist}{}%
  }%
}

\DTLmin如果两个数字中任何一个为空,则返回“空”。因此,当\DTLthisval恰好为空时(因为列中的字段为空),到目前为止计算出的最小值#3将重置为“空”,就像循环开始之前一样。

为了改变这种行为,我们必须确保只计算非空字段的最小值。因此,我们使用\patchcmd包中的xpatch来替换\DTLminforcolumn行中的

\DTLmin{#3}{#3}{\DTLthisval}%     #3 := min(#3,DTLthisval)

经过

\ifdefempty\DTLthisval{%          if DTLthisval == "":
}{%                               else:
  \DTLmin{#3}{#3}{\DTLthisval}%     #3 := min(#3,DTLthisval)
}%

相关内容