# How can I change the CDF which imports the data and uses it, without execution of code

I am making an application which first imports the data from the Excel file and then uses it in the deployment of a CDF. But is it possible to change the data of the Excel file and see its corresponding CDF without executing the code in the notebook?

I have imported y1 and y2 from an excel file. Here is the code.

CDFDeploy[
ToFileName["C:\\Users\\murali\\Desktop","demo2thomson.cdf"],
{DynamicModule[{y =
Import["C:\\Users\\murali\\Desktop\\demo.xlsx"], y1 = y[[1, 1]],   y2 = y[[1, 2]], q1, q2},
Panel@Column[{Spacer[70] Text[
Style["iPhone and iPad quarterly sales- units, million", Bold,
18]], Column[{Spacer[70],
Text[Style["Click on/off:", Bold, 14]], q1 = True; q2 = True;
Row[{Labeled[
Button["     ", q1 = ! q1, Background -> Blue,
Appearance -> "Frameless"], "iPhone", {Right}],
Spacer[19],
Labeled[Button["     ", q2 = ! q2, Background -> Orange,
Column[{Dynamic@
BarChart[
Table[{If[q1, y1[[i]], 0], If[q2, y2[[i]], 0]}, {i, 1, 22,
1}], BarSpacing -> 0.8, ChartStyle -> {Blue, Orange},
ImageSize -> {600, 280},
GridLines -> {None, Automatic}]}]}]}]]}]


I am importing these values just as default and want that the end user can change these values. i.e.

I don't want the end user to go to the code and execute again and again if he wants to change some of the values of y1 and y2.

Is it possible that he can change value and see the difference in the CDF itself?

-
If you're on version 7 or higher you should use FileNameJoin[{"C","Users","murali","Desktop","demo2thomson.cdf"}] instead of ToFileName. This makes sure your code works the same on OSX, Linux and windows. Additionally, it's better to make the path relative to the directory where your application resides in using NotebookDirectory[]. –  Sjoerd C. de Vries Jun 15 '12 at 8:13
Have a look at FileDate (to check when a file was last modified) and CreateScheduledTask (to Import the file if it has been changed). I'll try to post an answer later on. –  b.gatessucks Jun 15 '12 at 8:42
ok Thanks both of you.... I will have a look on these functions –  Jennifer Jun 15 '12 at 8:52
@Jennifer: If you use cdf because the receipient needs to run this without a full mathematica license within the cdf-player, AFAIK it just won't work: Import will return $Failed if used within cdf player with a local file. I think it is possible to Import from a public URL, but you would have to test that (I haven't). If the receipient does have a full Mathematica or a PlayerPro this is actually not really a CDF specific question and you might get more people interested if you ask for Import within a DynamicModule which all comments and answers so far do actually treat (only). – Albert Retey Jun 15 '12 at 16:23 @Jennifer: have you tested your CDF file with the CDF player? If it's working in Mathematica that doesn't mean it also will work in the CDF player. Or are you importing those values just as defaults and want the user to be able to change those values? It think it's not only me who obviously doesn't understand what exactly you try to do, so maybe you should reformulate your questions... – Albert Retey Jun 15 '12 at 22:37 ## 3 Answers Import is disabled in the default CDF document reader. There are two common options to get around this: - From your comments I guess you look for something like below, although I'm still not sure as your question is somewhat hard to understand. I have also separated the code into: 1. defining pathes and import default data: directory = FileNameJoin[{$HomeDirectory, "Desktop"}];
y = Import[FileNameJoin[{directory, "demo.xlsx"}]];

2. defining the graphical user interface (I used slightly different constructs as your original code), adding inputfields for the values of y1 and y2:

gui = DynamicModule[{y1 = y[[1, 1]], y2 = y[[1, 2]], q1 = True, q2 = True},
Panel@Grid[{
{Item[
Text[Style["iPhone and iPad quarterly sales- units, million", Bold, 18]],
Alignment -> Center
], SpanFromLeft},
{Spacer[{0, 20}], SpanFromLeft},
{
"iPhone",
Row@Table[
With[{k = k},InputField[Dynamic[y1[[k]]], Number, FieldSize -> 5]],
{k,Length[y1]}
]},
Row@Table[
With[{k = k},InputField[Dynamic[y2[[k]]], Number, FieldSize -> 5]],
{k,Length[y2]}
]},
{Text[Style["Click on/off:", Bold, 14]], SpanFromLeft},
{Row[{
Labeled[
Toggler[Dynamic[q1], {True -> Spacer[{18, 18}], False -> Spacer[{18, 18}]},
Background -> Dynamic[If[q1, Blue, LightGray]]],
"iPhone", {Right}],
Spacer[19],
Labeled[
Toggler[Dynamic[q2], {True -> Spacer[{18, 18}], False -> Spacer[{18, 18}]},
Background -> Dynamic[If[q2, Orange, LightGray]]],
}], SpanFromLeft},
{
Dynamic[
BarChart[
Table[{If[q1, y1[[i]], 0], If[q2, y2[[i]], 0]}, {i,Length[y1]}],
BarSpacing -> 0.8, ChartStyle -> {Blue, Orange},
ImageSize -> {600, 280}, GridLines -> {None, Automatic}
]
], SpanFromLeft
}},
Alignment -> {Left, Center}
]]

3. Only once the above works as intended, export to cdf:

CDFDeploy[FileNameJoin[{directory, "testdemo.cdf"}], gui, Method -> "Standalone"]

-
Thanks for your help and it is working but I dont want the input fields to be shown in the output. I was just trying to import modified values in the code as answered by 'Mr.b.gatessucks'. –  Jennifer Jun 18 '12 at 10:48
"I was importing those values just as default and want the user to change those values." ??? –  Albert Retey Jun 18 '12 at 18:52
@ Albert Retey: I wanted that first the data should be imported from the excel file and display its output, But if end user wants to change the data, then it should change it in the same excel file and display its corresponding output. –  Jennifer Jun 18 '12 at 19:05
@Jennifer: As I said, I don't think importing a local will work if running in the CDF-Player, are you aware of that? Running in Mathematica or PlayerPro will work, though. You could use b.gatessucks suggestion then. –  Albert Retey Jun 18 '12 at 23:31
@ Albert Retey: I was not aware of PlayerPro but as you said, I will try importing, using PlayerPro as soon as I get its license. –  Jennifer Jun 19 '12 at 5:19

One starting point is as follows; it's not ideal because one has to actually save the file before Mathematica picks up the changes. Also I don't know if it will work in the CDF.

file = "test.xls";

Import[file]

(* {{{1., 2., 3.}, {4., 5., 6.}, {7., 8., 9.}}} *)

lastModified := FileDate[file, "Modification"]; (* date of last modification *)
currentData := Import[file];

previousModified = FileDate[file, "Modification"];
startingData = Import[file];

liveData := Module[{currentTime, updateQ},currentTime = lastModified;updateQ = AbsoluteTime[currentTime] > AbsoluteTime[previousModified];{previousModified, startingData} = If[updateQ, {currentTime, currentData}, {currentTime, startingData}]]

(* liveData will Import the data and update the date of last modification *)


This will perform the check every second :

t = CreateScheduledTask[liveData, 1.0];


Now you can start the task and watch the file being changed :

StartScheduledTask[t]

Dynamic[liveData[[2]]]


Remember to stop the task when you're done :

StopScheduledTask[t]

-
For all I know this will not work within the CDF player (but might run in Mathematica or Player Pro if saved to a CDF file). Import for local files gives me OpenRead::sandbox error messages in the CDF Player for code which works fine in Mathematica. And I think that is roughly what the documentation states and not a bug... –  Albert Retey Jun 15 '12 at 22:40
@b.gatessucks: Thanks for this help. aIt is able to retrieve the dynamic data from the Excel file. But can you tell how can I make barchart of the dynamic values Dynamic[liveData[[2,1,1]]] –  Jennifer Jun 17 '12 at 15:21
@Jennifer I'd substitute my livedata with your y and leave the rest of your code untouched. –  b.gatessucks Jun 17 '12 at 16:23
@b.gatessucks: ok ...Thanks –  Jennifer Jun 17 '12 at 17:23