# How to convert datatypes?

I am trying to use datatools \DTLfetch to grab a real number from a database loaded from a .csv file, and then pass this numeric argument to \FPeval.

Problem is that \DTLfetch always seems to return a string instead of a numeric, which gives an error because FP can't handle string datatypes.

\DTLgetvalue always returns the desired numeric datatype and everything works, however, I really need \DTLfetch.

I have spent the last two days trying to figure out how to convert a string to a numeric datatype in LaTeX, or alternatively, how to get \DTLfetch to return a numeric value instead of a string.

Is LaTeX seriously deficient in this capability? or am I missing something fundamental? Should I use Sagetex to do the conversion?

Many thanks!

TeX is a macro language, it does not have any other types than strings. (There are typed registers, but they are not relevant here) The problem is not that \DTLfetch "returns" a string, it is that \DTLfetch is not expandable.

Non-expandable macros like \DTLfetch do not expand to a value, but sometimes they insert some results in the current list. That is why you can use see the result from DTLfetch in your document, but it does not work inside \FPeval.

To fix this, you can use a variant \DTLfetchsave of \DTLfetch which egreg has written for retrieving substring of \DTLfetch. It saves the result in a new macro, which can then be expanded (similar to \FPeval itself):

\begin{filecontents*}{students.csv}
Joe Bloggs,2.7
Jane Doe,1.0
John Smith,3.0
\end{filecontents*}

\documentclass{article}
\usepackage{datatool,fp}

% From egreg at https://tex.stackexchange.com/questions/335483/retrieving-substring-of-dtlfetch
\newcommand{\DTLfetchsave}[5]{%
\edtlgetrowforvalue{#2}{\dtlcolumnindex{#2}{#3}}{#4}%
\dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{#2}{#5}}%
\let#1\dtlcurrentvalue
}

\begin{document}
\end{document}


I had the same issue when trying to use data from a (CSV) database for plotting single values with TikZ/PGFPlots or for printing values using siunitx.

With this post I found out how to store all values from the database as (expanded) LaTeX variable named after the respective key:

\documentclass[tikz]{standalone}
\usepackage{siunitx}
\usepackage{filecontents}
\begin{filecontents*}{mydb.csv}
key;value
mykey;1.0
\end{filecontents*}

% Relevant code below
\usepackage{datatool}
\DTLsetseparator{;}

\begin{document}
\DTLforeach{mydb}{\Key=key,\Value=value}
{%
\cslet{\Key}{\Value}%
}
\DTLfetch{mydb}{key}{mykey}{value} works\\
% while $\num{\DTLfetch{mydb}{key}{mykey}{value}}$ fails
\mykey prints the value for mykey, $\num{\mykey}$ also works
\end{document}


However, loading multiple databases with similar keys would re-assign the same variables.

As a quick fix, I made DTLFetch assign the values to variables named after a concatenation of database name and key and wrote a function to parse the latter:

\documentclass[tikz]{standalone}
\usepackage{siunitx}
\usepackage{filecontents}
\begin{filecontents*}{mydb.csv}
key;value
mykey;1.0
\end{filecontents*}

% Relevant code below
\usepackage{datatool}
\DTLsetseparator{;}

\newcommand{\getval}[2]{\csname#1#2\endcsname}

\begin{document}
\DTLforeach{mydb}{\Key=key,\Value=value}
{%
\cslet{mydb\Key}{\Value}%
}
\getval{mydb}{mykey} prints the value for mykey, $\num{\getval{mydb}{mykey}}$ also works
\end{document}


I also discovered \xDTLassignfirstmatch in datatool that seems to work the same as \DTLfetch, with expansion, and works great for me!

• Please provide details of how to use this and give an example. – Andrew Swann Apr 22 '18 at 15:10
• I found the basis for my solution here: [tex.stackexchange.com/questions/178904/…. '\xDTLassignfirstmatch' is like '\DTLassignfirstmatch' but performs a one-level expansion on {value} which is also something I needed. eg: '\xDTLassignfirstmatch{dbname}{col_key}{value}{assign_list}' – alex dinovitser Apr 23 '18 at 6:29
• Is someone assigned to add information to datatool documentation on CTAN? It would have been great to know which macros are expandable, and which aren't. – alex dinovitser Apr 23 '18 at 6:32