7
$\begingroup$

I am trying to write the code for doing the following:

  1. by clicking a button, import specific data from an Excel file which I select through a dialog window;
  2. input a name for the imported data set through an input field;
  3. store the imported data permanently under the given name (for example a variable with that name), so that I don't have to import it again next time I open Mathematica;
  4. repeat 1. - 3. , etc.

The idea is to be able to have several data sets imported from several Excel files, assign specific names to them and store all of them inside the notebook permanently.

Could someone please guide me to achieve this?

$\endgroup$
  • 1
    $\begingroup$ Conrad, could you share what you attempted? Typically questions are better received here if you show your initial efforts, rather than just asking for somebody to code your task for you. $\endgroup$ – MarcoB Jun 30 '15 at 14:23
  • $\begingroup$ @MarcoB yes, of course, sorry... ClearAll; InitializationCell; ExcelFile = SystemDialogInput["FileOpen"] impdatas = {}; AppendTo[impdatas, Import[ExcelFile, {"Data", 5, Table[i, {i, 4, 24}], {1, 2}}]] $\endgroup$ – Conrad Jun 30 '15 at 14:34
  • $\begingroup$ Have you also looked to similar posts by typing in the search box (right up corner) "Import excel" ? $\endgroup$ – SquareOne Jun 30 '15 at 14:38
  • $\begingroup$ Do you want to keep the data in the notebook, or a separate external file? You may want to look at Put and Get. $\endgroup$ – image_doctor Jun 30 '15 at 14:41
  • $\begingroup$ As I wrote, I would like to keep the data in the notebook, for portability reasons. $\endgroup$ – Conrad Jun 30 '15 at 14:42
5
$\begingroup$

My approach to this task would be to create new Input Cells within the notebook, that have the same structure as newly typed in symbol definition.

createNewSymbol[] :=
 Module[{importFileName = SystemDialogInput["FileOpen", ".txt"]},
  With[{importedData = If[StringQ@importFileName, Import[importFileName, "Table"]],
        symName = If[StringQ@importFileName, Input["Enter Symbol Name"]]},
   If[ListQ@importedData && ! MatchQ[symName, $Canceled], 
    CellPrint@ExpressionCell[Defer[symName = importedData;], "Input", 
      InitializationCell -> True]];
   If[StringQ@importFileName, createNewSymbol[]];
   ]]

Button["Create New Symbols with Imported Data", createNewSymbol[], Method -> "Queued"]

I used the following .txt files for testing

Export["aTest.txt", RandomInteger[10, 100]];
Export["bTest.txt", RandomReal[1, 100]];
Export["cTest.txt", RandomPrime[100, 100]];

therefore you will have to adapt my code for your Excel files.

$\endgroup$
  • $\begingroup$ @Karsten.7 Testing the code I observed that, after closing the file and re-opening it, the variables created (I named them a, b and c) are empty... $\endgroup$ – Conrad Jul 1 '15 at 9:09
  • $\begingroup$ @Conrad After re-opening the notebook file there still should be the created Input Cells (e.g., something like a={{3}, {5}, ...}). After evaluation of these cells the variables shouldn't be empty. No values are set before evaluating these variable definitions, but all information is stored in the notebook file and no new import is needed. I thought that's what you wanted. $\endgroup$ – Karsten 7. Jul 1 '15 at 10:38
  • $\begingroup$ @Conrad If you prefer that the values are set after opening the notebook without the need to explicitly evaluate the cells, you could right-click on the cell bracket and select Initialization Cell. $\endgroup$ – Karsten 7. Jul 1 '15 at 10:42
  • $\begingroup$ @Karsten.7 This was exactly my intention: after opening the file again to have the last created symbols set with the corresponding values, without needing to re-evaluate the (resulted) cell. Can I add in the code a specific InitializationCell for the resulting cell for that? $\endgroup$ – Conrad Jul 2 '15 at 15:48
  • 1
    $\begingroup$ @Conrad Yes, see my edit. I added InitializationCell -> True as an option for ExpressionCell. $\endgroup$ – Karsten 7. Jul 2 '15 at 16:11
7
$\begingroup$

it is not etirely clear for what you need that, but I think the best way to store data within a Notebook so that it is available in the next session is the TaggingRules option. This is how you could store data for a there:

 CurrentValue[EvaluationNotebook[],{TaggingRules,"dataset-name"}] = data;

And this is how you can read it:

 data = CurrentValue[EvaluationNotebook[],{TaggingRules,"dataset-name"}];

for most applications it will be fast enough to just use that. To make it more convenient you could define e.g.:

saveDataset[name_String,data_] := saveDataset[name_String,data_] := (
  CurrentValue[EvaluationNotebook[],{TaggingRules,name}] = data
);
getDataset[name_String] := (
  CurrentValue[EvaluationNotebook[],{TaggingRules,name}]
);

if the access via frontend would be too slow you could cache the data in the kernel:

getDataset[name_String] := getDataset[name] = (
  CurrentValue[EvaluationNotebook[],{TaggingRules,name}]
);

but that would mean you should also redefine when the data changes, so you'll also need to update the cached value if a dataset ever should change:

saveDataset[name_String,data_] := (
  getDataset[name] = 
    CurrentValue[EvaluationNotebook[],{TaggingRules,name}] = data;
);
$\endgroup$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.