# DTLminforcolumn not working with empty rows

I use datatool to parse a CSV file. I want to use the makro \DTLminforcolumn to calculate the minimum value of a column. This works fine if every row has a value, but not so much, if there are empty rows. How can I tell datatool to ignore empty rows?

MWE:

\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{;}%
\DTLminforcolumn{a}{value}{\minValueFirstExample}

\DTLsetseparator{;}%
\DTLminforcolumn{b}{value}{\minValueSecondExample}

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


Add the following lines after loading the datatool package.

\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{;}%
\DTLminforcolumn{a}{value}{\minValueFirstExample}

\DTLsetseparator{;}%
\DTLminforcolumn{b}{value}{\minValueSecondExample}

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


Explanation. \DTLminforcolumn is defined in datatool.sty as follows:

\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 returns 'empty' if any of the two numbers is empty. So, when \DTLthisval happens to be empty (because the field in the column is empty), the minimum computed so far in #3 will be reset to 'empty', as it was before the loop started.

To change this behavior we have to make sure that the minimum is only computed for non-empty fields. Therefore we use \patchcmd from the package xpatch to replace in \DTLminforcolumn the line

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


by

\ifdefempty\DTLthisval{%          if DTLthisval == "":
}{%                               else:
\DTLmin{#3}{#3}{\DTLthisval}%     #3 := min(#3,DTLthisval)
}%
`
• Thanks for the help. Can you explain me what this does? Btw, I found out, that \DTLminforkeys also works correctly. – SCM Jan 19 at 20:30
• @SCM I have added an explanation. – gernot Jan 19 at 21:27
• Thanks a lot @gernot – SCM Jan 21 at 23:33