{ Analytica Model ACPT_Library, encoding="UTF-8" } SoftwareVersion 5.3.3 { System Variables with non-default values: } SampleSize := 1000 TypeChecking := 0 Checking := 0 SaveOptions := 2 SaveValues := 0 DisplayOutputs Null: Function cub_get_show_outputs, Function cub_get_show_inputs Sv__DateOriginOffset := -1462 Sys_DefaultNumberFmt := 2,F,4,2,0,0,4,0,$,0,"ABBREV",0,,,0,0 Graph_LineThickness := 3 {!50000|OutlinerState Sys_FoundSet: 2,542,323,448,280} {!50016|PlusOnTextReturnsNaN := 0} {!-50299|DiagramColor Model: 65535,65535,65535} {!-50299|DiagramColor Module: 65535,65535,65535} {!-50299|DiagramColor LinkModule: 65535,65535,65535} {!-50299|DiagramColor Library: 65535,65535,65535} {!-50299|DiagramColor LinkLibrary: 65535,65535,65535} {!-50299|DiagramColor Form: 65535,65535,65535} NodeInfo FormNode: 1,0,0,1,0,0,0,,0,0,,0,0 NodeColor Text: 65535,65535,65535 {!-40203|Attribute CloudPlayerStyles} Model ACPT_Library Title: ACPT Library Description: Functions for use in ACPT (ACP with Tableau) (and potentially ACP3). Use ACP3_ChangeInputCSV() or ACPchangeInputJSON() in the OnChange attribute of any user input modified from ACP3 to regenerate the output CSV (or JSON) file for any results affected by the input to be displayed in the ACP dashboards. Author: Max Henrion Date: Tue, Nov 5, 2019 9:35 PM DefaultSize: 64,32 NodeSize: 64,24 DiagState: 2,520,0,563,340,21,,4 WindState: 2,290,174,720,350 FontStyle: Century Gothic,15 FileInfo: 0,Model ACPT_Library,2,2,0,0,ACPT Library.ana Button Write_results_to_CSV Title: Write results to CSV old Description: Write results for four datasets to CSV for Tableau testing. NodeLocation: 296,292,1 NodeSize: 72,28 WindState: 2,103,7,986,474 OnClick: WriteTextFile( 'Statistics_by_node.csv' , MakeCSV( Statistics_table, statistics_and_fract, CA_DAM_NODES, columnHeaders:statistics_and_fract, rowHeaders:CA_DAM_NODES, quoteFlags:2 ) );~ WriteTextFile( 'Nodes.csv' , MakeCSV( nodes_map_filtered_l, nodes_coordinates_c2, ca_dam_nodes_local, columnHeaders:nodes_coordinates_c2, rowHeaders:ca_dam_nodes_local, quoteFlags:2 ) );~ WriteTextFile( 'Node_fractiles.csv' , MakeCSV( fractile_values_loca, All_Statistics, graph_fractiles, columnHeaders:All_Statistics, rowHeaders:graph_fractiles, quoteFlags:2 ) );~ WriteTextFile( 'DAM_data.csv' , MakeCSV( DAM_price_flattened, SI_Hour8784, DAM_NODE_ID, columnHeaders:SI_Hour8784, rowHeaders:DAM_NODE_ID, quoteFlags:2 ) ); Decision User_input_choice_x Title: User input choice x Description: Example user input that may be changed in ACP dashboard Definition: Choice(J,2,0) NodeLocation: 296,216,1 NodeSize: 64,24 ValueState: 2,388,394,416,303,,MIDM {!40200|Att_ChoiceIndexes: Index J} OnChange: Onchange_Input_CSV() Variable User_output_A Title: User output A Description: Example user output displayed in ACP dashboard Definition: eg_Array_3D[J = User_input_choice_x] NodeLocation: 472,120,1 NodeSize: 64,24 ValueState: 2,792,108,416,303,,MIDM Variable User_output_B Title: User output B Description: Example user output displayed in ACP dashboard Definition: eg_Array_3D+ User_input_choice_x NodeLocation: 472,216,1 NodeSize: 64,24 ValueState: 2,792,108,416,303,,MIDM Index All_user_outputs_in_ Title: All user outputs in this model Description: All user outputs in this model (excluding this ACP3 Library). We assume that each variable that is displayed in ACP has a user output node, and each variable that is a user input in ACP has a user input node. Definition: #setDifference(FindObjects(hasUserOutput:True), ~ FindObjects(within: Handle(ACPT_Library),hasUserOutput:True)) NodeLocation: 288,40,1 NodeSize: 64,32 WindState: 2,530,184,720,350 ValueState: 2,64,15,445,609,,MIDM MetaOnly: 1 Button Save_outpus_as_CSV Title: Save all user outputs as CSV files Description: Click to save all the variables with user outputs each as a CSV file named as the identifier of its variable. NodeLocation: 104,292,1 NodeSize: 72,28 WindState: 2,-17,319,720,350 OnClick: Metavar v := All_user_outputs_in_ DO Save_CSV_file(v) Library ACP_JSON_Library Title: ACP JSON Library Description: Functions for converting from Analytica objects, tables, and arrays to JSON arrays of JSON objects, and saving as files. Author: Max Henrion Date: Sun, Nov 10, 2019 3:54 PM DefaultSize: 64,32 NodeLocation: 104,216,1 NodeSize: 88,24 DiagState: 2,858,6,749,397,21,, FontStyle: Century Gothic,15 Function SaveUserInputJSON(v: Variable) Title: SaveUserInputJSON(v) Description: Call this function on any user input used by ACP3 when it is initialized to get its title, units if any, current value, list of possible values, and list of the output variables that it influences (which the UI should update when the user changes this user input). It writes this as a JSON files with the identifier of the variable.~ ~ Incomplete! Definition: {WriteTextFile(Identifier OF v & '.JSON', }~ '{ "Identifier: "' & Identifier OF v & '", "Title": "'& Title OF v &'", "Value": "'& (v) ~ & '", "Values": { ... }, "Outputs": { } }' { warn:False, showDialog: false)} NodeLocation: 144,488,1 NodeSize: 104,24 WindState: 2,-25,256,720,350 Variable eg_save_userInputINf Title: eg save userInputINfo Definition: SaveUserInputJSON(User_input_choice_x) NodeLocation: 376,488,1 NodeSize: 88,24 ValueState: 2,213,174,1042,268,,MIDM Function JSON_from_table(x; i: Index) Title: JSON_from_table(x) Description: Given a 1D array x indexed by i, it generates a JSON object containing name-value pairs with each element of i as a name and the corresponding value of x as its value. Definition: Local q := '"';~ '{' & Jointext(q& i & q &': '& IF Isnumber(x) THEN x ELSE (q & x &q), i, ', ', textForNull: '') & '}' NodeLocation: 144,360,1 NodeSize: 104,24 WindState: 2,328,126,720,350 Function JSON_from_array(v: Variable Atom; measureIndex: Optional Index; useTitles, omitZero, omitNull: = True) Title: JSON_from_array(v) Description: Returns the array value of Variable v formatted as JSON -- a (1D) JSON array of JSON objects, where each Object corresponds to a cell in array v. If v has N dimensions each object has N+1 name-value pairs. The first N names are indexes of v and their values are the corresponding values from each index for each array element, The last name-value pair contains the title (or identifier if you set useTitles: False) of V and the value from that cell. For example, given ~ INDEX I := ['A', 'B']~ INDEX J := [1, 2];~ Variable V := @I * J~ JSON_from_array(V) ->~ [{"I": "A", "J": 1, "V": 1}, ~ {"I": "A", "J": 2, "V": 2}, ~ {"I": "B", "J": 1, "V": 2}, ~ {"I": "B", "J": 2, "V": 4}]~ ~ If you set optional parameter measureIndex to m, say, (it must be an index of a), it creates a "fact table" as JSON. Each object has N -1 + M name-value pairs. where M = Size(m). Each of the first N-1 name-value pairs contains an index (excluding m), and the last M pairs have a name that is a value of Index m, and a value that is the corresponding value from array v. In this case each object corresponds to a 1D slice of V with index m over all the other indexes. See the explanation of measureIndex parameter in MdArrayToTable() docs for more.~ ~ The resulting JSON omits any Objects corresponding to cells (or slices) of V that contain only zero (or NULL) values, unless you set omitZero (omitNull) to True. Definition: INDEX indexes := IndexesOf(v);~ IF NOT Isnotspecified(measureIndex) ~ THEN indexes := #SetDifference(\indexes, \([Handle(measureIndex)])); ~ INDEX measureCols := IF IsNotSpecified(measureIndex) ~ THEN [IF useTitles THEN Title OF v ELSE Identifier OF v]~ ELSE (MeasureIndex);~ INDEX cols := IF useTitles ~ THEN Concat(Title OF (indexes), measureCols)~ ELSE Concat(Identifier OF (indexes), measureCols);~ Local colHeaders := Array(cols, Concat((indexes), measureCols));~ Local x := IF IsNotSpecified(measureIndex) ~ THEN MdArrayToTable(v, Col: colHeaders, omitNull:omitNull, omitZero: omitZero)~ ELSE MdArrayToTable(v, Col: colHeaders, valueIndex: measureIndex, omitNull:omitNull, omitZero: omitZero);~ MakeJSON(x, x.Row, cols, Objects: cols, flags:8) NodeLocation: 144,160,1 NodeSize: 104,24 WindState: 2,420,121,806,701 Variable eg_3D_JSON_from_arra Title: eg 3D JSON_from_array Definition: JSON_from_array(eg_Array_3D, measureIndex: kay, useTitles:0) NodeLocation: 376,216,1 NodeSize: 88,24 ValueState: 2,244,601,921,347,,MIDM Variable eg_2D_JSON_from_arra Title: eg 2D JSON_from_array Definition: JSON_from_array(eg_array_2D, useTitles:1) NodeLocation: 376,160,1 NodeSize: 88,24 ValueState: 2,149,210,841,318,,MIDM Att_ResultSliceState: [kay,2,Sys_LocalIndex('Row'),1,Sys_LocalIndex('cols'),1] Function ACPchangeInputJSON() Title: ACPchangeInputJSON() Description: Writes a JSON file for all variables with user outputs that are influenced by the user input variable from whose OnChange attribute you call this function. This is useful in ACP3 to refresh any outputs that may be affected by changing the user input. Definition: METAVAR x[] := #FindObjects(influencedBy: HandleFromIdentifier("_Caller"), hasUserOutput:True)~ DO Save_JSON_file(x) NodeLocation: 144,296,1 NodeSize: 104,24 WindState: 2,463,235,720,350 Function Save_JSON_file(v: Variable Atom) Title: Save_JSON_file(v) Description: Convert the array value of variable v to JSON and save it as a file whose name is the identifier of v (and extension .JSON). Definition: Local fileName := (Identifier OF v)&'.JSON';~ IF Trace_save_files THEN MsgBox('Saving file '& fileName);~ WriteTextFile(fileName, JSON_from_array(v), showDialog: False, warn: False) NodeLocation: 144,232,1 NodeSize: 104,24 WindState: 2,456,420,720,350 Variable JSON_from_obj_attrib Title: JSON_from_obj_attribs Definition: JSON_from_table(Eg_attribs_to_conver OF eg_3D_CSV_from_array, Eg_attribs_to_conver) NodeLocation: 376,360,1 NodeSize: 88,24 ValueState: 2,92,122,1194,322,,MIDM Index Eg_attribs_to_conver Title: Eg attribs to convert to JSON Definition: ['Class','Identifier','Title','Units','Description','Definition'] NodeLocation: 560,360,1 NodeSize: 64,24 Variable JSON_from_obj_attri1 Title: JSON_from_obj_attribs Definition: JSON_Obj_attribs(eg_3D_CSV_from_array, Eg_attribs_to_conver) NodeLocation: 376,424,1 NodeSize: 88,24 ValueState: 2,-80,203,1284,300,,MIDM Function JSON_Obj_attribs(v: Variable; attribs: Index) Title: JSON_Obj_attribs(v: Variable; attribs: Index) Description: Returns the specified attributes of variable v as a JSON object.~ Attributes may be user modifiable text attributes, ~ but not Inputs, Outputs, or others that may be a list of values, Definition: JSON_from_table(attribs OF v, attribs) NodeLocation: 144,424,1 NodeSize: 104,24 WindState: 2,426,134,720,350 Variable eg_1D_JSON_from_arra Title: eg 1D JSON_from_array Definition: JSON_from_array(eg_Array_1D) NodeLocation: 376,104,1 NodeSize: 88,24 ValueState: 2,195,252,921,347,,MIDM Variable eg_0D_JSON_from_arra Title: eg 0D JSON_from_array Definition: JSON_from_array(eg_Array_0D, useTitles:0) NodeLocation: 376,48,1 NodeSize: 88,24 ValueState: 2,303,227,921,347,,MIDM Variable eg_3D_JSON_from_arr1 Title: eg 3D JSON_from_array Definition: JSON_from_array(eg_Array_3D, measureIndex: J, useTitles:0) NodeLocation: 376,272,1 NodeSize: 88,24 ValueState: 2,59,801,921,347,,MIDM Alias Al1294109149 Title: eg Array 3D Definition: 1 NodeLocation: 560,224,1 NodeSize: 64,24 Original: eg_Array_3D Alias Al757238237 Title: eg array 2D Definition: 1 NodeLocation: 560,160,1 NodeSize: 64,24 Original: eg_array_2D Alias Al1830980061 Title: eg Array 1D Definition: 1 NodeLocation: 560,104,1 NodeSize: 64,24 Original: eg_Array_1D Alias Al488802781 Title: eg Array 0D Definition: 1 NodeLocation: 560,48,1 NodeSize: 64,24 Original: eg_Array_0D Variable eg_2D_Save_JSON_file Title: eg 2D Save_JSON_file Definition: Save_JSON_file(eg_2D_JSON_from_arra) NodeLocation: 592,296,1 NodeSize: 96,24 Close ACP_JSON_Library Library ACP_CSV_Library Title: ACP CSV Library Description: Functions for saving arrays into relational form into csv files. Author: Max Henrion Date: Sun, Nov 10, 2019 3:54 PM NodeLocation: 104,120,1 NodeSize: 88,24 DiagState: 2,182,40,935,452,21,, WindState: 2,922,208,720,350 Index I Att_PrevIndexValue: ['A','B'] Title: I Definition: ['A','B'] NodeLocation: 848,96,1 NodeSize: 64,24 Variable eg_Array_3D Title: eg Array 3D Definition: 10 + J^2 + 3*@I + @kay NodeLocation: 704,208,1 NodeSize: 64,24 WindState: 2,98,82,720,350 ValueState: 2,769,46,416,303,,MIDM Aliases: Alias Al1294109149, Alias Al834832861 Index J Att_PrevIndexValue: [1,2] Title: J Definition: 1 .. 2 NodeLocation: 848,152,1 NodeSize: 64,24 Function CSV_from_array(v: Variable Atom; measureIndex: Optional Index; useTitles, omitZero, omitNull: = True) Title: CSV_from_array(v) Description: Returns the array value of Variable v as a text value in CSV (comma-separated value) format. If v has N dimensions each row has N+1 columns. The first N columns are indexes of v and the values are the corresponding values from each index, The column has as header the title (or identifier if you set useTitles: False) of V and the value from that cell. For example, given ~ INDEX I := ['A', 'B']~ INDEX J := [1, 2];~ Variable V := @I * J~ CSV_from_array(V) ->~ "I", "J", "V"~ "A", 1, 1~ "B", 1, 2~ "A", 2, 2~ "B", 2, 4~ ~ If you set optional parameter measureIndex to index m, say (it must be an index of a), it creates a "fact table" with N -1 + M name-value pairs, where M = Size(m). Each of the first N-1 columns is an index of v (excluding m), and the last M columns contain the elements of Index m. Their values are the corresponding value from array v. See the explanation of measureIndex parameter in MdArrayToTable() docs for more.~ ~ The result CSV omits any rows corresponding to cells (or slices) of V that contain only zero (NULL) values, unless you set omitZero (omitNull) to True. Definition: INDEX indexes := IndexesOf(v);~ IF NOT Isnotspecified(measureIndex) ~ THEN indexes := #SetDifference(\indexes, \([Handle(measureIndex)])); ~ INDEX measureCols := IF IsNotSpecified(measureIndex) ~ THEN [IF useTitles THEN Title OF v ELSE Identifier OF v]~ ELSE (MeasureIndex);~ INDEX cols := IF useTitles ~ THEN Concat(Title OF (indexes), measureCols)~ ELSE Concat(Identifier OF (indexes), measureCols);~ Local colHeaders := Array(cols, Concat((indexes), measureCols));~ Local x := IF IsNotSpecified(measureIndex) ~ THEN MdArrayToTable(v, Col: colHeaders, omitNull:omitNull, omitZero: omitZero)~ ELSE MdArrayToTable(v, Col: colHeaders, valueIndex: measureIndex, omitNull:omitNull, omitZero: omitZero);~ MakeCSV(x, cols, x.Row, cols) NodeLocation: 288,152,1 NodeSize: 104,24 WindState: 2,337,34,867,872 Variable eg_3D_CSV_from_array Title: eg 3D CSV_from_array Definition: CSV_from_array(eg_Array_3D, measureIndex: kay, useTitles:0) NodeLocation: 512,208,1 NodeSize: 88,24 ValueState: 2,292,128,265,347,,MIDM Index kay Title: kay Definition: ['Yes','No'] NodeLocation: 848,208,1 NodeSize: 64,24 Variable eg_2D_CSV_from_array Title: eg 2D CSV_from_array Definition: CSV_from_array(eg_array_2D, useTitles:1) NodeLocation: 512,152,1 NodeSize: 88,24 ValueState: 2,343,276,841,318,,MIDM Att_ResultSliceState: [kay,2,Sys_LocalIndex('Row'),1,Sys_LocalIndex('cols'),1] Variable eg_array_2D Title: eg array 2D Definition: @I * J NodeLocation: 704,152,1 NodeSize: 64,24 ValueState: 2,981,98,416,303,,MIDM Aliases: Alias Al757238237 {!50000|Att_ColumnWidths: [,I,\([,63])]} Function Onchange_Input_CSV() Title: OnChange_Input_CSV() Description: Call this function from the Onchange attribute of any user input that can be modified by ACPT. It writes a CSV file for each variable with user outputs that are influenced by the user input variable that calls this function. It also saves the User_inputs.csv file so that user inputs can be reloaded when the user starts a new session. Definition: if (FireOnChangeInputs) then (~ Local inVar := HandleFromIdentifier("_Caller"); ~ local moduleWithOutputs := slice(#FindObjects(regexp: Module_for_Onchange, attribute: 'Title', class: "module"),1);~ /*msgbox(moduleWithOutputs);~ msgbox(User_outputs_inf_by( inVar, moduleWithOutputs));*/~ METAVAR x[] := User_outputs_inf_by( inVar, moduleWithOutputs)~ DO (IF Trace_save_files THEN msgbox(x); Save_CSV_file(x));~ ACP_save_user_inputs(User_inputs_file_nam, User_inputs_in_dashb)~ )~ ~ NodeLocation: 288,288,1 NodeSize: 104,24 WindState: 2,274,19,930,692 Function Save_CSV_file(v: Variable, measureIndex: Optional Index) Title: Save_CSV_file(v) Description: Convert the value of variable v (expected to be an array with >=1 dimensions) into a 2D relational table in CSV (comma-separated value) format and save it as a file whose name is the identifier of v (with extension .csv).~ ~ See description of CSV_from_array() for more details on other parameters. Definition: WriteTextFile(Folder_for_CSV_files & '\' & (Identifier OF v)&'.csv', CSV_from_array(v, measureIndex), showDialog: False, warn: False) NodeLocation: 288,224,1 NodeSize: 104,24 WindState: 2,209,165,890,389 Variable eg_Array_1D Title: eg Array 1D Definition: J^2 NodeLocation: 704,96,1 NodeSize: 64,24 WindState: 2,98,82,720,350 ValueState: 2,769,46,416,303,,MIDM Aliases: Alias Al1830980061 Variable eg_Array_0D Title: eg Array 0D Definition: 100 NodeLocation: 704,40,1 NodeSize: 64,24 WindState: 2,98,82,720,350 ValueState: 2,769,46,416,303,,MIDM Aliases: Alias Al488802781 Variable eg_1D_CSV_from_array Title: eg 1D CSV_from_array Definition: CSV_from_array(eg_Array_1D, useTitles:1) NodeLocation: 512,96,1 NodeSize: 88,24 ValueState: 2,349,317,841,318,,MIDM Att_ResultSliceState: [kay,2,Sys_LocalIndex('Row'),1,Sys_LocalIndex('cols'),1] Variable eg_0D_CSV_from_array Title: eg 0D CSV_from_array Definition: CSV_from_array(eg_Array_0D, useTitles:1) NodeLocation: 512,40,1 NodeSize: 88,24 ValueState: 2,354,258,841,318,,MIDM Att_ResultSliceState: [kay,2,Sys_LocalIndex('Row'),1,Sys_LocalIndex('cols'),1] Variable Folder_for_CSV_files Title: Folder for CSV files Description: The folder where the csv files will be written.~ ~ Make it empty string if you want to write the files to the same folder as the model file. Definition: Data_folder_path NodeLocation: 88,224,1 NodeSize: 72,24 WindState: 2,366,224,720,350 ValueState: 2,317,123,825,303,,MIDM Aliases: FormNode Fo1944157661 Variable eg_onChange_outputs Title: eg onChange outputs Definition: Local inVar := Handle(display_month);~ User_outputs_inf_by(inVar, IsIN OF (Slice(Aliases OF invar, 1)) ) NodeLocation: 704,400,1 NodeSize: 64,32 ValueState: 2,128,140,416,303,,MIDM Variable Module_for_Onchange Title: Module for Onchange Description: The definition of this variable will be the title of the module for which we want to update the CSV files. This will be set by ACP code during the UpdateNodeDef() web service call. Definition: "Price Projections" NodeLocation: 88,288,1 NodeSize: 72,24 WindState: 2,155,59,720,350 Constant User_inputs_file_nam Title: User inputs file name with path Definition: Folder_for_CSV_files & User_inputs_file_na1 NodeLocation: 88,144,1 NodeSize: 64,40 WindState: 2,576,100,720,350 ValueState: 2,95,758,906,303,,MIDM Index z Title: z Definition: [0,1] NodeLocation: 848,264,1 NodeSize: 64,24 Variable eg_Array_0D_2 Title: eg Array 0D 2 Definition: z * n NodeLocation: 704,264,1 NodeSize: 64,24 Variable eg_0D_CSV_from_arra1 Title: eg 0D CSV_from_array 2 Definition: CSV_from_array(eg_Array_0D_2, omitZero: 1, omitNull: 1) NodeLocation: 512,264,1 NodeSize: 88,24 Index n Title: n Definition: [1,Null] NodeLocation: 848,320,1 NodeSize: 64,24 Variable eg_2D_Save_CSV_file Title: eg 2D Save_CSV_file Definition: Save_CSV_file(eg_2D_CSV_from_array) NodeLocation: 512,336,1 NodeSize: 88,24 Variable eg_OnChange_Input_CS Title: eg OnChange_Input_CSV Definition: Onchange_Input_CSV() NodeLocation: 704,464,1 NodeSize: 96,24 Constant User_inputs_file_na1 Title: User inputs file name Definition: 'User_inputs.csv' NodeLocation: 88,56,1 NodeSize: 64,32 WindState: 2,576,100,720,350 ValueState: 2,95,758,906,303,,MIDM Decision FireOnChangeInputs Title: FireOnChangeInputs Description: When a user changes an input, we can to fiire, i.e. execute, OnChange_Input_CSV(). When user inputs are reloaded by the OnChange to Tableau_userID, we don't want to calculate result csv files or save the user inputs csv file. ~ ~ This varialbe will control that. When a user is changing inputs its value should be 1. When updating Tableau_userID, this variable should be 0. Definition: 1 NodeLocation: 288,368,1 NodeSize: 88,32 Close ACP_CSV_Library Alias Al834832861 Title: eg Array 3D Definition: 1 NodeLocation: 296,120,1 NodeSize: 64,24 Original: eg_Array_3D Decision Trace_save_files Title: Trace save files? Description: Check if you want Save_CSV_File(v) to give a message box for the name of each variable saved. (You probably don't want this usually.) Definition: Checkbox(0) NodeLocation: 440,40,1 NodeSize: 64,32 ValueState: 2,36,42,416,303,,MIDM Library ACP_Save_and_load_us Title: ACP Save and load user inputs lib Description: Functions to find all the user inputs in a model, save their definitions to a User_inputs.csv file, and load them back in.~ These are useful when you want to have a single model that can be shared by multiple users or sessions, where user inputs are saved in separate file for each user. Author: Lumina Date: Thu, Feb 6, 2020 8:32 PM NodeLocation: 104,48,1 NodeSize: 88,24 DiagState: 2,35,14,986,296,23,, Variable data_folder Title: data folder Definition: CurrentDataFolder() NodeLocation: 720,168,1 NodeSize: 64,24 ValueState: 2,385,203,863,303,,MIDM Function User_inputs_in(m: Handle) Title: User_inputs_in(m) Description: Returns a list of the identifiers of variables that have user inputs in module m (and not its submodules). Definition: #SetIntersection([FindObjects(withinany: m, hasUserInput:True), \(Original OF (Contains OF m))]) NodeLocation: 136,48,1 NodeSize: 88,24 WindState: 2,164,228,1114,350 Variable eg_user_inputs_in Title: eg user_inputs_in(m) Definition: User_inputs_in( selected_dashboard_m) NodeLocation: 344,48,1 NodeSize: 88,24 ValueState: 2,725,65,416,303,,MIDM Function User_outputs_in(m: Module) Title: User_outputs_in(m) Description: A list of variables that have user outputs in module m (and not its submodules). Definition: #SetIntersection([FindObjects(withinany: m, hasUserOutput:True), ~ \(Original OF (Contains OF m))]) NodeLocation: 136,104,1 NodeSize: 88,24 WindState: 2,269,274,720,350 Variable eg_user_outputs_in Title: eg user_outputs_in(m) Definition: User_outputs_in( selected_dashboard_m) NodeLocation: 344,104,1 NodeSize: 88,24 ValueState: 2,31,242,416,303,,MIDM Variable selected_dashboard_m Title: selected dashboard module Definition: Handle(Price_Projections) NodeLocation: 544,104,1 NodeSize: 88,24 Function User_outputs_inf_by(inVar, m: Handle) Title: User_outputs_inf_by(inVar, m) Description: Returns a list of the identifiers of variables with user outputs in module m (and not its submodules) that are influenced by inVar. This is useful if you want to save all the user outputs displayed in ACPT affected by a change to user input inVar. Definition: #SetIntersection([FindObjects(influencedBy: inVar, withinany: m, hasUseroutput:True), \User_outputs_in(m)]) NodeLocation: 136,168,1 NodeSize: 88,24 WindState: 2,271,157,822,609 Variable eg_user_outputs_in1 Title: eg user_outputs_in(m) Definition: User_outputs_inf_by( Handle(Target_year), selected_dashboard_m) NodeLocation: 344,168,1 NodeSize: 88,24 WindState: 2,1057,457,720,350 ValueState: 2,1437,164,416,303,,MIDM Variable eg_user_outputs_in2 Title: eg user_outputs_in(m) Definition: User_outputs_inf_by( Handle(Selected_year), Handle(Market_prices)) NodeLocation: 544,168,1 NodeSize: 88,24 WindState: 2,879,644,720,350 ValueState: 2,1298,595,416,303,,MIDM Decision Tableau_userID Title: Tableau_userID Description: For ACPT, this contaions the user name for the person using Tableau. I.e. the Tableau Server account id. Definition: "user email goes here" NodeLocation: 280,320,1 NodeSize: 72,32 WindState: 2,327,0,620,367 Aliases: FormNode Fo1307611453 OnChange: New_User_Detected Index User_inputs_in_dashb Title: User inputs in dashboards Description: Variables that are user inputs in the Dashboard modules (and not their submodules) Definition: #SetUnion(LocalAlias m := (Dashboard_modules) DO \User_inputs_in(m), Dashboard_modules) NodeLocation: 544,48,1 NodeSize: 64,24 WindState: 2,291,57,720,350 ValueState: 2,71,201,333,364,,MIDM Index Dashboard_modules Title: Dashboard modules Description: Modules that contain dashboards in ACPT Definition: ListOfHandles(Market_prices, Price_statistics1, Price_Projections) NodeLocation: 712,48,1 NodeSize: 64,24 Aliases: Alias Al394602045 Function ACP_save_user_inputs(fileName: Text; vars: Index) Title: ACP_save_user_inputs(fileName, vars) Description: Given vars a list of variables, save as a csv file into filename a list of variable identifiers (in column 1) and their definitions (in column 2). Definition: WriteTextFile(filename, MakeCSV(Cols_for_saved_input OF (vars), Cols_for_saved_input, vars, quoteFlags: 2+4 ), warn:false) NodeLocation: 304,408,1 NodeSize: 112,24 WindState: 2,116,162,720,350 Button Save_User_inputs Title: Save User inputs NodeLocation: 496,400,1 NodeSize: 64,32 OnClick: ACP_save_user_inputs(User_inputs_file_pat, Test_user_input_list) Function TopModel(m: Handle) Title: TopModel(v) Definition: WHILE Class OF m <> 'Model' DO m := ISIN OF m NodeLocation: 304,240,1 NodeSize: 112,24 Variable Model_id Title: Model id Definition: Identifier OF (TopModel(Handle(self))) NodeLocation: 504,240,1 NodeSize: 64,24 Function ACP_load_vars(fileName: Text; varIDs: Index Optional) Title: ACP_load_vars(fileName, varIDs) Description: Read from filename a csv table that contains a list of variable identifiers (in column 1) and their definitions (in column 2) (typically saved by ACP_Save_user_inputs()).~ It loads the definitions into each variable, overwriting their existing variable.~ It gives an error if no variable exists with an identifier from the file.~ If you specify parameters vars as a list of variables, it checks that the identifiers in column 1 match the variables in that list, and gives an error message if they don't (and does not change any definitions). Definition: Local t;~ (t, fileName) := ReadTextFile(filename);~ t := ParseCSV( t, Cols_for_saved_input, firstLineIsHeader:False, quote:"""", parseFlags:2);~ INDEX rows := CopyIndex(t[@.Cols_for_saved_input=1]);~ t := (Array(rows, t[@.Cols_for_saved_input=2]));~ Index unknownVars := [];~ {IF IsnotSpecified(varIDs) ~ THEN BEGIN~ FOR v := rows~ DO IF HandleFromIdentifier(v)=Null THEN unknownVars := Concat(unknownVars, v);~ END~ ELSE unknownVars := #SetDifference(\rows, \(varIDs));~ IF Size(unknownVars)>0 THEN MSGBox('In function ACP_load_vars(), the file contains these variables that do not match variables in the model: '&JoinText(unknownVars, unknownVars, ', ') & '~ ~ Perhaps the file was saved from an out-of-date version of this model.', 16)~ ELSE} ~ FOR v := (rows) DO IF t[rows=v]<>NULL THEN Definition OF v := t[rows=v];~ MultiResult(fileName, t[@rows = @varIDs]) NodeLocation: 304,480,1 NodeSize: 112,24 WindState: 2,301,71,795,683 Button Load_User_inputs Title: Load User inputs NodeLocation: 496,480,1 NodeSize: 64,32 OnClick: Local f := '';~ (f, Loaded_results) := ACP_load_vars(User_inputs_file_pat, Test_user_input_list) Index Cols_for_saved_input Att_PrevIndexValue: ['Identifier','Definition'] Title: Cols for saved inputs csv Definition: ['Identifier','Definition'] NodeLocation: 88,480,1 NodeSize: 64,24 Variable loaded_results Title: loaded results Definition: Table(Test_user_input_list)('2','Choice(Input_2_options, 1, 0)','Choice(Input_2_options,0,1)','MultiChoice(Input_2_options,1,2,returnList:1)','Table(Input_2_options)(33,44,55)','Table(Cols_for_saved_input,Input_2_options)(~ 30,44,50,~ 20,44,100)','''Max version''') NodeLocation: 640,480,1 NodeSize: 64,24 DefnState: 2,259,100,702,302,0,DFNM ValueState: 2,449,25,748,372,,MIDM Variable Data_folder_path Title: Data folder path Description: The directory or folder in which to store result csv files for each user output used by ACPT, and also the User_inputs.csv file for the latest user inputs.~ Normally, this folder should be ~ \ Results \ ~ where is the path to the directory containing this Analytica model~ is the Analytica identifier of the model (not necessarily the same as the file name)~ is the Tableau user ID. Definition: Tableau_files_path & Model_id &' Data' & '\' & Tableau_userID & '\' NodeLocation: 504,320,1 NodeSize: 64,24 WindState: 2,98,82,720,350 ValueState: 2,447,124,720,176,,MIDM Variable User_inputs_file_pat Title: User inputs file path Description: Data_folder_path & 'User_inputs.csv' Definition: Data_folder_path & 'User_inputs.csv' NodeLocation: 664,320,1 NodeSize: 64,24 WindState: 2,348,85,720,350 ValueState: 2,104,283,1116,303,,MIDM Function Add_quotes(x) Title: Add_quotes(x) Description: If x is a text value, it adds double quotes around it so that it can be assigned as a definition to a variable. otherwise it returns x as it is. Definition: Local q := '"';~ IF IsText(x) AND SelectText(x, 1, 1)<>q THEN q&TextReplace( x,q,q&q)&q ELSE x NodeLocation: 328,632,1 NodeSize: 112,24 Module Example_user_inputs_ Title: Example user inputs for Saving and loading Author: Lumina Date: Thu, Feb 6, 2020 8:32 PM NodeLocation: 312,568,1 NodeSize: 104,32 DiagState: 2,0,0,801,598,17 Index Test_user_input_list Att_PrevIndexValue: [Input_number,Input_choice,Input_choice_with_al,Input_Multichoice,Input_edit_table,Input_edit_2D_table,Input_text] Title: Test user input list Definition: ListOfHandles(Input_number,Input_choice,Input_choice_with_al,Input_Multichoice,Input_edit_table,Input_edit_2D_table,Input_text) NodeLocation: 312,528,1 NodeSize: 64,32 ValueState: 2,1353,60,416,303,,MIDM Variable Input_number Title: Input number Definition: 2 NodeLocation: 264,48,1 NodeSize: 64,24 Aliases: FormNode Fo1876598333 NumberFormat: 2,%,2,2,0,0,2,0,$,0,"ABBREV",0,,,0,0,15 Variable Input_choice Title: Input choice Definition: Choice(Input_2_options, 1, 0) NodeLocation: 264,160,1 NodeSize: 64,24 Aliases: FormNode Fo534421053 {!40200|Att_ChoiceIndexes: Index Input_2_options} Index Input_2_options Att_PrevIndexValue: ['Yes','Maybe','No'] Title: Input 2 options Definition: ['Yes','Maybe','No'] NodeLocation: 112,208,1 NodeSize: 64,32 Variable Input_choice_with_al Title: Input choice with all Definition: Choice(Input_2_options,0,1) NodeLocation: 264,216,1 NodeSize: 64,24 Aliases: FormNode Fo1608162877 {!40200|Att_ChoiceIndexes: Index Input_2_options} Variable Input_Multichoice Title: Input Multichoice Definition: MultiChoice(Input_2_options,1,2,returnList:1) NodeLocation: 264,272,1 NodeSize: 64,24 Aliases: FormNode Fo1071291965 {!40200|Att_ChoiceIndexes: Index Input_2_options} Variable Input_text Title: Input text Definition: 'Max version' NodeLocation: 264,104,1 NodeSize: 64,24 Aliases: FormNode Fo2145033789 Variable Input_edit_table Title: Input edit table Definition: Table(Input_2_options)(33,44,55) NodeLocation: 264,328,1 NodeSize: 64,24 Aliases: FormNode Fo3841597 FormNode Fo1876598333 Title: Input number Definition: 0 NodeLocation: 496,48,1 NodeSize: 136,16 Original: Input_number FormNode Fo534421053 Title: Input choice Definition: 0 NodeLocation: 496,160,1 NodeSize: 136,16 NodeInfo: 1,,,,,,,94,,,,,,0 Original: Input_choice FormNode Fo1608162877 Title: Input choice with all Definition: 0 NodeLocation: 496,216,1 NodeSize: 136,16 NodeInfo: 1,,,,,,,94,,,,,,0 Original: Input_choice_with_al FormNode Fo1071291965 Title: Input Multichoice Definition: 0 NodeLocation: 496,272,1 NodeSize: 136,16 NodeInfo: 1,,,,,,,114,,,,,,0 Original: Input_Multichoice FormNode Fo2145033789 Title: Input text Definition: 0 NodeLocation: 496,100,1 NodeSize: 136,36 NodeInfo: 1,,,,,,,168,,,,,,0 Original: Input_text FormNode Fo3841597 Title: Input edit table Definition: 0 NodeLocation: 496,328,1 NodeSize: 136,16 Original: Input_edit_table Variable Input_edit_2D_table Title: Input edit 2D table Definition: Table(Cols_for_saved_input,Input_2_options)(~ 30,44,50,~ 20,44,100) NodeLocation: 264,384,1 NodeSize: 64,24 DefnState: 2,498,341,416,303,0,DFNM Aliases: FormNode Fo222731837 FormNode Fo222731837 Title: Input edit table Definition: 0 NodeLocation: 504,384,1 NodeSize: 136,16 Original: Input_edit_2D_table Close Example_user_inputs_ Variable eg_add_quotes Title: eg add_quotes(x) (number) Definition: Add_quotes(5) NodeLocation: 536,608,1 NodeSize: 80,24 Variable eg_add_quotes1 Title: eg add_quotes(x) (text) Definition: Add_quotes("five") NodeLocation: 536,672,1 NodeSize: 80,24 Library Files_library Title: Files library Description: Functions to find the files in a folder, check if a file exists, copy a file to a new file, and more.~ ~ Copyright 2018, 2020 Lumina Decision Systems, Inc. All rights reserved. Author: Lumina Date: Thu, Sep 15, 2016 5:12 PM NodeLocation: 96,240,1 NodeSize: 88,24 NodeInfo: 1,,,,,,0,0,,,,,,0 DiagState: 2,709,0,550,457,21,, WindState: 2,657,76,720,350 DiagramColor: 52428,52428,52428 Function ACP_Download_SS(b, file: Text) Title: ACP_Download_SS(b, file) Description: Call this function from the OnClick of a button b (setting b to Self) to download spreadsheet file from the current ACP project folder to the user's computer. ~ If running in ADE (i.e. ACP), it asks the user whether she wants to download the file.~ If so, it prompts the user with a file browser to select the folder and file name.~ ~ It uses a special ACP feature, which sets the CloudPlayerStyles of the button to ~ Download_spreadsheet: ~ to make this happen. Definition: IF AnalyticaEdition='ADE' THEN ~ IF MsgBox("Would you like to download this spreadsheet '"&file&"'?", 4 + 32, 'Question')=6~ THEN CloudPlayerStyles OF b:= 'Download_Spreadsheet:' & file~ ELSE CloudPlayerStyles OF b:= '' NodeLocation: 144,272,1 NodeSize: 120,16 WindState: 2,388,8,769,408 Function Files_in_dir(dir: = 'Models'; substring: = ''; showDirs: = False) Title: Files_in_dir(dir, ext) Description: Return a list of the names of all the files in directory dir (defaults to Model directory) in alphabetic order. If you specify substring, e.g. extension ".xlsx" or ".ana", it returns only file names that contain that substring. Set dir to "Data" for Current data directory, or "Model" to the current Model directory (which contains the current Analytica model). Or set dir to any directory name or path, absolute or relative to the Model directory. Directory name and substring are case insensitive.~ Set showDirs: True if you want to include directories in the list. Definition: dir := TextUpperCase(dir);~ dir := IF dir = '' OR dir = 'MODELS' THEN CurrentModelFolder()~ ELSE IF dir = 'DATA' THEN CurrentDataFolder()~ ELSE dir;~ Local t := RunConsoleProcess('c:\Windows\System32\CMD.exe',~ 'CMD /C DIR /A-D-H /B "' & dir & '" ');~ INDEX x := SplitText(t,'\R', re:true); { Split into lines }~ IF substring = '' THEN Slice(x, 1..(Size(x)-1))~ ELSE Subset(FindInText(substring, x, caseInsensitive:True)>0) NodeLocation: 144,40,1 NodeSize: 120,16 WindState: 2,269,63,765,618 Function Copy_file(file: Text; oldDir, newFile, newDir: = ''; overWrite: = 0) Title: Copy_file(file) Description: Makes a copy of file from directory dirOld (defaults to current model directory). If it can't find a file with that name in dirOld, it prompts for another. It then prompts for a new name (default newFile, or file, if newFile is omitted) to save it under. By default, if the newFile already exists, it asks if you want to overwrite it or give another file name. If overwrite = 1, it will overwrite without asking. If overwrite=-1, it will not even offer to overwrite. Once it gets a good name, it saves the file under that name in newDir (default current model directory). It returns the new filename with newDir path if specified. Definition: WHILE NOT Does_file_exist(file, oldDir) DO ~ file := AskMsgText("Trying to make a copy of file '"& file &"', ~ but can't find it. Please give another file name, ~ from directory '"&oldDir&"':", 'Question', 50, file);~ IF newFile='' THEN newFile := file;~ newfile := AskMsgText('Name for new spreadsheet: ', 'Question', 50, newFile);~ IF Does_file_exist(newfile, newDir) THEN ~ IF (MsgBox("There already is a file named '" & newfile &"' in the directory. Do you want to overwrite it?", 3+48)<>6) THEN ~ WHILE Does_file_exist(newfile, newDir) ~ DO newfile := AskMsgText( 'Please give a different file name: ', 'Question', 50, newfile);~ IF oldDir<>'' THEN file := oldDir & file;~ IF newDir<>'' THEN newfile := newDir&'\'&newfile;~ VAR copyArg := 'cmd /c copy '&(IF overWrite THEN '/D' ELSE '')&' "' & file & '" "' & newfile & '"';~ MsgBox('Running consoleprocess with '©arg); ~ RunConsoleProcess('c:\Windows\System32\cmd.exe', copyarg);~ VAR wb := SpreadsheetOpen(newfile); wb->Save; ~ newfile NodeLocation: 144,152,1 NodeSize: 120,16 WindState: 2,477,28,795,668 Variable Eg_files_in_folder Title: Eg files_in_folder Description: Variable for testing function Files_in_folder(dir, ext). Modify the variable definition with optional parameters dir, ext to test specific examples. Definition: Files_in_dir( '../', '.ana' ) NodeLocation: 368,40,1 NodeSize: 64,24 ValueState: 2,169,116,703,593,0,MIDM Function Does_file_exist(file: Text; dir: = '') Title: Does_file_exist(file) Description: Returns True (1) if a file with that name including extension exists, by default in the Current model folder, or in dir if you specify a different directory, otherwise False (0). Insensitive to case of file name. Definition: Sum(TextUpperCase(Files_in_dir(dir))=TextUpperCase(file))=1 NodeLocation: 144,96,1 NodeSize: 120,16 WindState: 2,733,219,689,401 Variable Eg_Does_file_exist Title: Eg Does_file_exist Description: Example to demonstrate function Does_file_exist(file). Definition: Does_file_exist('..\Ana 4.3 testing.ana') NodeLocation: 368,96,1 NodeSize: 64,24 WindState: 2,761,64,720,350 ValueState: 2,473,333,416,303,,MIDM Button eg_download Title: eg download NodeLocation: 368,276,1 NodeSize: 48,20 OnClick: ACP_Download_SS(Identifier OF self, Select_file) Function Files_dir_table(dir: = 'Models'; ext: = '', orderBy: = 'N') Title: Files_dir_table(dir, ext) Description: Get a table of the files in directory dir, with file name, size, and save date (Index File_dir_fields), and local index .row of the files. dir defaults to the Model directory. ~ Specify substring if you want to get files that contain that substring -- for example, '.xlsx' or '.ana' to return only files with those extensions. ~ Set orderBy to 'N' to order alphabetically by name (default), 'D' by date oldest first, '-D' by date newest first, or 'E' alphabetic by extension. ~ ~ Set dir to 'Data' for Current data directory. Or set dir to any directory name or path relative to the Model directory. Directory name and substring are case insensitive. Definition: dir := TextUpperCase(dir);~ dir := IF dir = '' OR dir = 'MODELS' THEN CurrentModelFolder()~ ELSE IF dir = 'DATA' THEN CurrentDataFolder()~ ELSE dir;~ Local cmdText := 'CMD /C DIR /O:' & orderBy & ' '&~ (IF SelectText(ext, 1, 1)='.' AND Textlength(ext)>1 THEN ('"' & dir & '"'&'*'&ext)~ ELSE '/A-H "' & dir & '"');~ INDEX files := SplitText(RunConsoleProcess( 'c:\Windows\System32\CMD.exe', cmdText),'\R',re:true);~ {substring = '' THEN Slice(x, 1..(Size(x)-1)) { Remove first line which is blank }~ {ELSE Subset(FindInText(substring, x, caseInsensitive:True)>0)}~ files := Slice(files, 8 .. (Size(files) - 3)); { Ignore first 5 and last 2 lines which don't contain files }~ files := TextReplace(files, '', '');~ VAR r := FindInText('(.* [P|A]M)\s*([,|\d]*)\s*(.*)', files, re:True, return:'S', subpattern: 4 - @File_dir_fields);~ INDEX row := 1 .. Size(files);~ r[@files = row] NodeLocation: 144,208,1 NodeSize: 120,16 WindState: 2,72,90,765,651 Variable Eg_Files_dir_table Title: Eg Files_dir_table Description: Variable for testing function Files_in_folder(dir, ext). Modify the variable definition with optional parameters dir, ext to test specific examples. Definition: Files_dir_table(dir: '../') NodeLocation: 368,208,1 NodeSize: 64,24 ValueState: 2,788,33,1163,724,0,MIDM ReformVal: [File_dir_fields,Sys_LocalIndex('files')] {!50000|Att_RowHeights: [,Sys_LocalIndex('files'),\([,16])]} Index File_dir_fields Title: File dir fields Definition: ['File name','Size','Save date'] NodeLocation: 496,208,1 NodeSize: 48,24 Function ACP_Upload_SS(b, file: Text) Title: ACP_Upload_SS(b, file) Description: Call this function from the OnClick of a button b (setting b to Self) to upload a spreadsheet with default name file from the current ACP project folder to the user's computer. ~ If running in ADE (i.e. ACP), it asks the user whether she wants to upload the file.~ If so, it prompts user with a file browser to select the folder and file name.~ ~ It uses a special ACP feature, which sets the CloudPlayerStyles of the button to:~ Upload_spreadsheet: ~ to make this happen. Definition: IF AnalyticaEdition='ADE' THEN ~ IF MsgBox("Would you like to upload a spreadsheet '"&file&"'?", 4 + 32, 'Question')=6~ THEN CloudPlayerStyles OF b:= 'Upload_Spreadsheet:' & file~ ELSE CloudPlayerStyles OF b:= '' NodeLocation: 144,328,1 NodeSize: 120,16 WindState: 2,951,76,769,408 Button eg_ACP_upload Title: eg ACP upload NodeLocation: 368,332,1 NodeSize: 48,20 OnClick: ACP_Upload_SS(Identifier OF self, 'File to upload.xlsx') Function Copy_file2(file: Text; oldDir, newFile, newDir: = '') Title: Copy_file2(file) Description: Makes a copy of file from directory dirOld (defaults to current model directory). If it can't find dirOld or a file with that name, it prompts for another. It prompts for a new name (default newFile, or file, if newFile is omitted) to save it under that does not already exist. Once it gets a good name, it saves the file under that name in newDir (default current model directory). It returns the new filename with newDir path if specified. Definition: WHILE NOT Does_file_exist(file, oldDir) DO file :=~ (IF AnalyticaEdition='ADE' ~ THEN AskMsgText("Trying to make a copy of file '"& file ~ &"' from directory '"&oldDir&"', but can't find it. Please select another name:", ~ 'Question', 50, file)~ ELSE IF MsgBox("Can't find file '"& file &"' from directory '"&oldDir&"', which we are trying to copy. Do you want to copy another file?", 1+32, 'Question')=1 ~ THEN SpreadsheetInfo(SpreadsheetOpen(file), 'Filename')~ ELSE '');~ IF file ='' THEN 0~ ELSE BEGIN~ IF newFile='' THEN newFile := file;~ newfile:= AskMsgText('Name for new spreadsheet: ', 'Question', 50, newFile);~ While Does_file_exist(newfile, newDir) DO ~ IF (MsgBox('There already is a file with that name in the directory. Do you want to overwrite it?', 3+48)<>6) THEN newfile := AskMsgText('Please give a different file name: ', 'Question', 60, newfile);~ IF oldDir<>'' THEN file := oldDir&'\'&file;~ IF newDir<>'' THEN newfile := newDir&'\'&newfile;~ VAR copyArg := 'cmd /c copy "' & file & '" "' & newfile & '"';~ RunConsoleProcess('c:\Windows\System32\cmd.exe', copyarg);~ { VAR wb := SpreadsheetOpen(newfile); wb->Save; }~ newfile~ END NodeLocation: 144,448,1 NodeSize: 120,16 WindState: 2,333,78,795,668 Index Files_in_dir1 Att_PrevIndexValue: ['19469.xlsx','ACP_inactive_list_Nov_2019 (002).xlsx','Data Import Template_mod.xlsx'] Title: Files in dir Definition: Reset_files_in_dir; Files_in_dir( , 'Xlsx') NodeLocation: 816,256,1 NodeSize: 48,24 ValueState: 2,120,123,553,303,,MIDM Decision Select_file Title: Select file Definition: Choice(Files_in_dir1,2,0) NodeLocation: 536,104,1 NodeSize: 48,24 Aliases: FormNode Fo1516242177 {!40200|Att_ChoiceIndexes: Index Files_in_dir1} FormNode Fo1516242177 Title: Select file Definition: 0 NodeLocation: 680,152,1 NodeSize: 216,16 NodeInfo: 1,,,,,,0,336,,0,,,,0 Original: Select_file Function File_delete(file: Text; dir: = '') Title: File_delete(file, dir) Description: Delete file in directory dir (by default CurrentModelDirectory().~ Gives an a copy of file from directory dirOld (defaults to current model directory). If it can't find a file with that name in dirOld, it prompts for another. It then prompts for a new name (default newFile, or file, if newFile is omitted) to save it under. By default, if the newFile already exists, it asks if you want to overwrite it or give another file name. If overwrite = 1, it will overwrite without asking. If overwrite=-1, it will not even offer to overwrite. Once it gets a good name, it saves the file under that name in newDir (default current model directory). It returns the new filename with newDir path if specified. Definition: IF NOT Does_file_exist(file, dir) THEN~ MsgBox("You are trying to delete a file '"&file&"' that does not exist in directory '"&dir&"'.") ~ ELSE BEGIN~ Local copyArg := 'cmd /c DEL "' & file & '"';~ MsgBox('Running consoleprocess with '©arg); ~ RunConsoleProcess('c:\Windows\System32\cmd.exe', copyarg);~ Local wb := SpreadsheetOpen(file); wb->Save; ~ file~ END NodeLocation: 144,376,1 NodeSize: 120,16 WindState: 2,477,28,795,668 Button Delete_file Title: Delete file NodeLocation: 368,384,1 NodeSize: 48,24 OnClick: File_delete(Select_file) Button Copy_file1 Title: Copy file NodeLocation: 368,152,1 NodeSize: 48,24 OnClick: Copy_file(Select_file, CurrentModelFolder() , 'test new.xlsx', overWrite:1) Button Reset_files Title: Reset files NodeLocation: 640,232,1 NodeSize: 48,24 OnClick: Reset_files_in_dir := NOT Reset_files_in_dir Variable Reset_files_in_dir Title: Reset files in dir Definition: 1 NodeLocation: 680,72,1 NodeSize: 48,24 Module Files_model_test Title: Files model test Author: Lumina Date: Fri, Jun 1, 2018 2:53 PM NodeLocation: 824,64,1 NodeSize: 48,32 Close Files_model_test Variable Eg_files_in_folder1 Title: Eg files_in_folder Description: Variable for testing function Files_in_folder(dir, ext). Modify the variable definition with optional parameters dir, ext to test specific examples. Definition: Files_in_dir( './' ) NodeLocation: 512,40,1 NodeSize: 64,24 ValueState: 2,377,-2,543,593,0,MIDM Function Make_Dir(dirName: Text) Title: Make_Dir(dirName) Description: Make a new directory with name dirName in directory dir, default the Models directory. Definition: try((RunConsoleProcess('C:\Windows\System32\Cmd.exe', 'Cmd /C mkdir "' & dirName & '" '); true), catch: false) NodeLocation: 144,496,1 NodeSize: 120,16 WindState: 2,16,73,878,399 Button Test_Make_dir Title: Test Make_dir NodeLocation: 384,524,1 NodeSize: 48,28 OnClick: Make_Dir( CurrentModelFolder() & 'newdirectory\pizza' ) Function Files_in_dir2(dir: = 'Models'; substring: = ''; showDirs: = False) Title: Files_in_dir(dir, ext) Description: Return a list of the names of all the files in directory dir (defaults to Model directory) in alphabetic order. If you specify substring, e.g. extension ".xlsx" or ".ana", it returns only file names that contain that substring. Set dir to "Data" for Current data directory, or "Model" to the current Model directory (which contains the current Analytica model). Or set dir to any directory name or path, absolute or relative to the Model directory. Directory name and substring are case insensitive.~ Set showDirs: True if you want to include directories in the list. Definition: dir := TextUpperCase(dir);~ dir := IF dir = '' OR dir = 'MODELS' THEN CurrentModelFolder()~ ELSE IF dir = 'DATA' THEN CurrentDataFolder()~ ELSE dir;~ Local t := RunConsoleProcess('c:\Windows\System32\CMD.exe',~ 'CMD /C DIR /A-H /B "' & dir & '" ');~ INDEX x := SplitText(t,'\R', re:true); { Split into lines }~ IF substring = '' THEN Slice(x, 1..(Size(x)-1))~ ELSE Subset(FindInText(substring, x, caseInsensitive:True)>0) NodeLocation: 624,320,1 NodeSize: 120,16 WindState: 2,780,53,765,399 Variable Eg_files_in_folder2 Title: Eg files_in_folder Description: Variable for testing function Files_in_folder(dir, ext). Modify the variable definition with optional parameters dir, ext to test specific examples. Definition: Files_in_dir2( '../') NodeLocation: 832,320,1 NodeSize: 64,24 ValueState: 2,997,-6,941,593,0,MIDM Variable Eg_files_in_folder3 Title: Eg files_in_folder Description: Variable for testing function Files_in_folder(dir, ext). Modify the variable definition with optional parameters dir, ext to test specific examples. Definition: Files_in_dir2( './' ) NodeLocation: 824,384,1 NodeSize: 64,24 ValueState: 2,643,154,941,593,0,MIDM Variable Return_Current_Direc Title: Return Current Directory Description: Returns the current directory with just folders, alphabetized. Definition: RunConsoleProcess("C:\Windows\System32\Cmd.exe", "Cmd /C dir /b /ad /o") NodeLocation: 384,464,1 NodeSize: 72,24 Function Find_in_Dir(dirName: Text; dir: = '') Title: Find_in_Dir(dirName) Description: See if a directory exists within a specified directory (dir). If no director is specified, the directory takes the location of the current model directory. Definition: dir := IF dir = '' OR dir = 'MODELS' THEN CurrentModelFolder()~ ELSE IF dir = 'DATA' THEN CurrentDataFolder()~ ELSE dir;~ ~ Local search;~ ~ /*~ Local subDir := FindInText(dirName, "\", return: 'P'); {make work for repeat?}~ {If user supplies a sub directory}~ IF (subDir) THEN~ {Use the position to return the sub directory}~ subDir := SelectText(dirName, subDir+ 1);~ */~ ~ Local dirList := Return_Dir_Folders(dir);~ {See if any of the entries have the specified folder}~ IF (dirList <> Null) THEN (~ search := FindInText(dirName, dirList, caseInsensitive: True);~ search := Max(search);~ ) ELSE (~ search := 0;~ );~ search NodeLocation: 144,664,1 NodeSize: 120,16 WindState: 2,34,173,720,338 Variable Test_Find_in_dir Title: Test_Find_in_dir Definition: Find_in_Dir( 'newdirectory', CurrentModelFolder('test')) NodeLocation: 384,664,1 NodeSize: 48,32 ValueState: 2,196,201,416,304,,MIDM Function Return_Dir_Folders(dir: = '') Title: Return_Dir_Folders Definition: dir := IF dir = '' OR dir = 'MODELS' THEN CurrentModelFolder()~ ELSE IF dir = 'DATA' THEN CurrentDataFolder()~ ELSE dir;~ ~ {Save specified directory text}~ Local dirList := try(RunConsoleProcess('C:\Windows\System32\Cmd.exe', 'Cmd /C cd "' & dir & '" & dir /ad /o /b'), catch: null);~ {Put the files into a list and trim out extra whitespace}~ IF (dirList <> null) THEN dirList := TextTrim( SplitText(dirList, Chr(13)) );~ dirList NodeLocation: 144,592,1 NodeSize: 120,16 WindState: 2,98,82,719,350 Variable Test_Return_dir_fold Title: Test Return_dir_folders Definition: Return_Dir_Folders('koasdjkasd/ljahsdkjasd') NodeLocation: 384,592,1 NodeSize: 48,32 Text Te1190637885 Title: Remember Description: If you create a directory after evaluating the find function, make sure to add a space/etc. to make the find function recompute NodeLocation: 528,624,-1 NodeSize: 64,104 NodeInfo: 1,,,,,1 Function Copy_CSV_Files(destination) Title: Copy_CSV_Files Description: Copies a file from current directory to a newly specified directory. Definition: try(RunConsoleProcess('C:\Windows\System32\Cmd.exe', 'Cmd /C copy *.csv "' & destination & '" '), catch: null) NodeLocation: 144,736,1 NodeSize: 120,16 WindState: 2,98,82,720,350 Variable Test_copy_csv_files Title: Test_copy_csv_files Definition: Copy_CSV_Files(CurrentModelFolder("baba")) NodeLocation: 384,736,1 NodeSize: 48,32 Close Files_library Button New_User_Detected Title: New User Detected Description: OnChangeEvent triggered whenever Tableau_userID is changed. Either:~ Existing Users: Finds and loads an existing user's saved input files~ New Users: Creates the necessary file structure and generates default files for a new user and then loads those input files~ ~ WARNING: supplied directory must be legitimate~ ~ Bug/Feature: If additional text follows, still finds the right folder.~ ~ Old OnClick probably written by Ben....~ ~ {Variable that indicates whether the AMPERE Results folder already exists}~ Local exists = Find_in_Dir('AMPERE Results');~ Local exists2 = 0;~ ~ If (exists) THEN~ (~ exists2 := Find_in_Dir(tableau_userID, CurrentModelFolder('AMPERE Results'));~ CurrentModelFolder('..\');~ );~ ~ IF {AMPERE Results folder exists but tableau user folder does NOT exist} (exists = 1 AND exists2 = 0) THEN~ (~ {Create Tableau User's folder}~ Make_Dir('AMPERE Results\' & Tableau_userID);~ {Place default input files inside Tableau User's folder}~ ACP_save_user_inputs(User_inputs_file_nam, User_inputs_in_dashb);~ { Copy_CSV_Files(Data_folder_path); }~ );~ ~ IF {AMPERE Results folder does NOT exist} (exists = 0) THEN~ (~ {Create AMPERE Results folder + Create Tableau User's folder}~ Make_Dir('AMPERE Results\' & Tableau_userID);~ {Place default input files inside Tableau User's folder}~ ACP_save_user_inputs(User_inputs_file_nam, User_inputs_in_dashb);~ { Copy_CSV_Files(Data_folder_path); }~ ) NodeLocation: 96,320,1 NodeSize: 64,32 WindState: 2,235,39,962,531 OnClick: {Make the folder for the model data files ~ e.g. "c:\acot data\ampere data" if it does not exist}~ Make_Dir(Tableau_files_path & Model_id &' Data');~ ~ {Make the folder for the model files ~ e.g. "c:\acot data\ampere data\henrion@lumina.com" if it does not exist}~ local bUserIdFolderCreated = Make_Dir(Tableau_files_path & Model_id &' Data' & '\' & Tableau_userID);~ ~ if (bUserIdFolderCreated) then (~ {Save the user inputs to a file e.g. "c:\acot data\ampere data\henrion@lumina.com/User_inputs.csv"}~ ACP_save_user_inputs(User_inputs_file_nam, User_inputs_in_dashb); ~ ) else (~ {the user is a returning user, so reload inputs from last session}~ ACP_load_vars(User_inputs_file_nam);~ )~ ~ Variable Tableau_files_path Title: Tableau files path Description: The "root" folder for all tableau data files Definition: "c:\ACPT data\" NodeLocation: 664,240,1 NodeSize: 64,24 Close ACP_Save_and_load_us Close ACPT_Library