3

I think there's a bug in calling decimal numbers from CSV files. Have a look.

  1. Create a Folder.

  2. Add a CSV file called texDemo.CSV with the following in it.

    UniqueID,Name,DecimalPercentageComplete,PercentageComplete
    1,Task1,0.45,45
    2,Task2,0.95,95
    3,Task3,0.10,10
    4,Task4,1,100
    
  3. Create a .tex document in the same folder called CallFromCSV.tex and add the following code. Because of the automated formatting it looks like there's two lines separate. Make sure you add all the line to the CallFromCSV.tex file.

    \usepackage{datatool}
    \DTLloaddb{CHCplanDB}{texDemo.csv}
    \newcommand\GetUniqueIDCHC[1]{
    \DTLforeach*
    [\equal{\UniqueID}{#1}]% condition
    {CHCplanDB}% database
    {\UniqueID=UniqueID,\UniqueID=UniqueID}% assignments
    {\UniqueID }% body
    }
    \newcommand\GetUniqueIDCHC[1]{
    \DTLforeach*
    [\equal{\UniqueID}{#1}]% condition
    {CHCplanDB}% database
    {\UniqueID=UniqueID,\UniqueID=UniqueID}% assignments
    {\UniqueID }% body
    }
    \newcommand\GetTaskNameCHC[1]{
    \DTLforeach*
    [\equal{\UniqueID}{#1}]% condition
    {CHCplanDB}% database
    {\UniqueID=UniqueID,\Name=Name}% assignments
    {\Name }% body
    }
    \newcommand\GetPercentageCompleteCHC[1]{
    \DTLforeach*
    [\equal{\UniqueID}{#1}]% condition
    {CHCplanDB}% database
    {\UniqueID=UniqueID,\PercentageComplete=PercentageComplete}% assignments
    {\PercentageComplete }% body
    }
    \newcommand\GetDecimalPercentageCompleteCHC[1]{
    \DTLforeach*
    [\equal{\UniqueID}{#1}]% condition
    {CHCplanDB}% database
    {\UniqueID=UniqueID,\DecimalPercentageComplete=DecimalPercentageComplete}% assignments
    {\DecimalPercentageComplete }% body
    }
    
  4. Create another file called Report.tex and add the following:

    \documentclass{report}
    
    \RequirePackage[a4paper, portrait, top=20mm, bottom=20mm, left=17.5mm, right=17.5mm]{geometry}
    
    \usepackage{datatool}
    \input{CallFromCSV.tex}
    
    %used for making a progress bar
    
    \usepackage{progressbar}
    \usepackage{graphicx}
    
    \newcommand{\PerCompleteDecimal}{0.45}
    \newcommand{\PerCompleteInt}{45}
    \newcommand{\chPercentage}{\GetDecimalPercentageCompleteCHC{1}}
    \newcommand{\chPercentageA}{\GetDecimalPercentageCompleteCHC{2}}
    
    \usepackage{numprint}
    \usepackage{siunitx}
    
    
    \begin{document}
    
    I have to use MS Project and I've created a basic export.  The table below is what you'll see in the CSV file.
    
    \begin{center}
    \begin{tabular}{ |c|c|c|c| }
    \hline
    UniqueID&Name&DecimalPercentageComplete&PercentageComplete \\ 
    \GetUniqueIDCHC{1} & \GetTaskNameCHC{1} & \GetDecimalPercentageCompleteCHC{1} & \GetPercentageCompleteCHC{1}\\ 
    \GetUniqueIDCHC{2} & \GetTaskNameCHC{2} & \GetDecimalPercentageCompleteCHC{2} & \GetPercentageCompleteCHC{2}\\
    \GetUniqueIDCHC{3} & \GetTaskNameCHC{3} & \GetDecimalPercentageCompleteCHC{3} & \GetPercentageCompleteCHC{3}\\
    \GetUniqueIDCHC{4} & \GetTaskNameCHC{4} & \GetDecimalPercentageCompleteCHC{4} & \GetPercentageCompleteCHC{4}\\ 
    \hline
    \end{tabular}
    \end{center}
    
    \section{Section 1}
    When I put the numbers into the progressbar, it works fine.
    
    \progressbar[linecolor=blue, filledcolor=green, heighta=1cm, width=5cm]{.25} \begin{picture}(0,0)\put(-73,1.5) {\large$25\%$} \end{picture}\\
    
    When I call the variables from the newcommand - \textbackslash PerCompleteDecimal and \textbackslash PerCompleteInt, it works fine.
    
    \progressbar[linecolor=blue, filledcolor=green, heighta=1cm, width=5cm]{\PerCompleteDecimal} \begin{picture}(0,0)\put(-73,1.5) {\large$\PerCompleteInt\%$} \end{picture}\\
    
    If I try and call \textbackslash GetDecimalPercentageCompleteCHC{3} or \textbackslash GetPercentageCompleteCHC{3}, it errors out.  You'll see that it errors out.  Below I should have gotten a progressbar colot that shows 10\% but that doesn't happen.
    
    \progressbar[linecolor=blue, filledcolor=green, heighta=1cm, width=5cm]{\GetDecimalPercentageCompleteCHC{3}} \begin{picture}(0,0)\put(-73,1.5) {\large$\GetPercentageCompleteCHC{3}\%$} \end{picture}\\
    
    Here's what happens when I break the progressbar down.  I've put 0.10 for the color and I put\\
     \textbackslash GetPercentageCompleteCHC{3} to show the number.
    
    \progressbar[linecolor=blue, filledcolor=green, heighta=1cm, width=5cm]{0.10} \begin{picture}(0,0)\put(-73,1.5) {\large$\GetPercentageCompleteCHC{3}\%$} \end{picture}\\
    
    Here's one last thing for you.  I can manipulate it a little and put \textbackslash PerCompleteInt from the newcommand and place it like a decimal.  Here's what it looks like.  Notice that I put it as 0.\textbackslash PerCompleteInt
    
    \progressbar[linecolor=blue, filledcolor=green, heighta=1cm, width=5cm]{0.\PerCompleteInt} \begin{picture}(0,0)\put(-73,1.5) {\large$\PerCompleteInt\%$} \end{picture}\\
    
    Bascially, I'm just trying to put a progressbar in a table for a report.  Without submitting the whole report I've given a simplified one.  We have so much of our documentation and I want to automate this as much as possible when I have to submit my monthly reports this is why I'm asking the question.
    
    
    
    \begin{center}
      \begin{tabular}{ |c|c|c| } 
        \hline
        UniqueID&Name&Progress \\ 
        \GetUniqueIDCHC{1} & \GetTaskNameCHC{1} & \progressbar[linecolor=blue, filledcolor=green]{.45} \begin{picture}(0,0)\put(-35,1.5) {\tiny$45\%$} \end{picture} \\ 
        \GetUniqueIDCHC{2} & \GetTaskNameCHC{2} & \progressbar[linecolor=blue, filledcolor=green]{.95} \begin{picture}(0,0)\put(-35,1.5) {\tiny$95\%$} \end{picture} \\
        \GetUniqueIDCHC{3} & \GetTaskNameCHC{3} & \progressbar[linecolor=blue, filledcolor=green]{0.10} \begin{picture}(0,0)\put(-35,1.5) {\tiny$10\%$} \end{picture} \\
        \GetUniqueIDCHC{4} & \GetTaskNameCHC{4} & \progressbar[linecolor=blue, filledcolor=green]{1} \begin{picture}(0,0)\put(-35,1.5) {\tiny$100\%$} \end{picture} \\
        \hline
      \end{tabular}
    \end{center}
    
    I have to call from many exported CSV files because if I call from one big CSV with about 10000 lines, it takes forever for TexStudio to compile it into a PDF.  It handles many smaller files much easier than one big file.  I don't want to use something else and then call a PDF or any other way.  The reason why I like Latex is because I have so many files and parts of files that I can call from including code like XML or C\#.  \\
    
    Could this be a bug?  I think it might be.\\
    
    Thanks\\
    
    Mike
    
    \end{document}
    

Compile Report.tex and you'll notice that one of the progressbars gets an error. This is the issue. Just read the whole document and you'll see what I mean.

I challenge anyone to explain why this isn't working. I'm willing to take another approach but because my customer really wants progressbars, is there another way to use a progressbar and use it the way I'm trying to do with calling the variables from the CSV file.

Thanks for anyone who can answer this.

Mike

2
  • As far as I can see the issue is that \GetDecimalPercentageCompleteCHC is not expandable.
    – moewe
    Commented Mar 30, 2019 at 14:34
  • I have tried to make your question slightly more readable by formatting the .csv as code and removing the bold face. Note that in CallFromCSV.tex you have two \newcommand\GetUniqueIDCHCs. This will cause an error. Is there any particular reason why the code in `CallFromCSV.tex`` needs to be externalised to a different file in the example? An example with only one file is much easier to handle for others. It took me quite a while to figure out what was going on here, maybe it would be easier for people to understand what is going on if you tried to reduce the code to the bare minimum.
    – moewe
    Commented Mar 30, 2019 at 14:40

1 Answer 1

2

You want that the commands are expandable and you don't want to read the database each time you call one of them.

Change the code in CallFromCSV.tex to

\usepackage{datatool}
\DTLloaddb{CHCplanDB}{texDemo.CSV}

\newcommand{\definefromcsv}[2]{%
  \expandafter\xdef\csname#1@\UniqueID\endcsname{#2}%
}

\newcommand\GetUniqueIDCHC[1]{%
  \csname GetUniqueIDCHC@#1\endcsname
}
\newcommand{\GetTaskNameCHC}[1]{%
  \csname GetTaskNameCHC@#1\endcsname
}
\newcommand{\GetDecimalPercentageCompleteCHC}[1]{%
  \csname GetDecimalPercentageCompleteCHC@#1\endcsname
}
\newcommand{\GetPercentageCompleteCHC}[1]{%
  \csname GetPercentageCompleteCHC@#1\endcsname
}

\DTLforeach*{CHCplanDB}{%
  \UniqueID=UniqueID,%
  \Name=Name,%
  \DecimalPercentageComplete=DecimalPercentageComplete,%
  \PercentageComplete=PercentageComplete%
}{%
  \definefromcsv{GetUniqueIDCHC}{\UniqueID}%
  \definefromcsv{GetTaskNameCHC}{\Name}%
  \definefromcsv{GetPercentageCompleteCHC}{\PercentageComplete}%
  \definefromcsv{GetDecimalPercentageCompleteCHC}{\DecimalPercentageComplete}%
}

and you'll be done.

1
  • Thanks egreg, I think you just saved me from many painful days of doing something manual. It appears to be working. I'm not sure I understand the differences but it works and now I'm going to expand it to all the outputs that I do from MS Project. Much Appreciated. Commented Mar 31, 2019 at 6:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .