When I try to use the code snippet from the documentation (in Perspective) it tells me that saveFile isn’t an attribute of system.file. If I use the ctrl+space suggestions of system.file from a button’s onClick event in Perspective there is no saveFile method. The code examples show using saveFile to create the file and then system.file.writeFile to write to the file.
It’s been a few years since I wrote to a file from Ignition so I don’t remember how it’s supposed to work.
Ultimately, I’m just trying to export data from historical tag data to a .csv. I’m starting with the “easy stuff” so I’m just trying to write a text string to a file.
saveFile doesn’t actually save a file. It opens a file chooser dialog looking at the local filesystem to allow the user to construct a file path+name. That string is the return value. It only works in Vision because browsers don’t permit this kind of action.
writeFile is then used to actually perform the save operation. Again, it only works (locally) in Vision because browsers don’t permit this kind of action. The alternative in Perspective is to construct a downloadable file first, then place a link to it in your view. Following that link uses the browser’s download mechanism, which may or may not automatically offer a dialog to select a location and name to save under.
Perspective is fundamentally different from Vision. This is one of those differences.
To add onto @pturmel’s response, please look at the available scopes for the functions you’re attempting to use; saveFile() is only available in Vision Client scripting - not Perspective Sessions.
The writeFile() function IS available in Perspective, but ALL functions in Perspective run on the Gateway (so that’s where the file is written to), so you will never see a file on your local machine as a result of using writeFile().
There’s no mechanism in Perspective as of today that allows for exporting or downloading files of any type - short of coupling with the WebDev Module.
@pturmel
Thanks for the clarification. I vaguely remember that from training now that you mention it.
@cmallonee I saw your other response on this about the file being saved on the server. It threw me a bit when I tried to use the example from the help and it blew up. The scope makes sense.
I was having trouble getting it to accept my path. I had to escape “” in my path. It’s been a while since I did this and after figure out the problem it was kinda obvious. It’s not every year I have to write to a file from an HMI.
I figured out a pretty good solution for what I need to do. The customer wants to be able to select data points and have them displayed in a grid. Then they want to be able to hit a button to download a CSV file of the data from the grid.
This code got it done:
dataset = self.getSibling(“Table”).props.data
export = system.dataset.toCSV(dataset, 1, 0, 0)
system.perspective.download(filename=“test.csv”, data=export)
system.perspective.download isn’t documented on the official documentation yet. I found it on the intellisence thing and poked it until it worked.
Of course, selecting data points to display on the grid is the next fun challenge. I suspect this code will export all datapoints in the dataset whether I have them hidden or not.
I appreciate your help as always. I have been developing better stuff in general thanks to your help. I’m still using some of the stuff you showed me to muddle my way through unrelated things. My general approach to developing Perspective projects has improved thanks to your feedback.
I also appreciate the feature. It is EXACTLY what I needed. So thumbs up to that developer also
org.python.core.PySyntaxError: SyntaxError: (u"no viable alternative at character '\u201c'", ('', 4, 38, u'\tsystem.perspective.download(filename=\u201ctest.csv\u201d, data=export)\n'))
at org.python.core.ParserFacade.fixParseError(ParserFacade.java:95)
at org.python.core.ParserFacade.parse(ParserFacade.java:205)
at org.python.core.Py.compile_flags(Py.java:2205)
at com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:841)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunctionSuper(ProjectScriptLifecycle.java:526)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.getOrCreateDelegate(ProjectScriptLifecycle.java:565)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.(ProjectScriptLifecycle.java:556)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunction(ProjectScriptLifecycle.java:515)
at com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:822)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:68)
at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:65)
at com.inductiveautomation.perspective.gateway.action.ActionDecorator.runAction(ActionDecorator.java:18)
at com.inductiveautomation.perspective.gateway.action.SecuredAction.runAction(SecuredAction.java:51)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:257)
at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:246)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:215)
at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
That’s a pure syntax error, not a problem with the logic. I can’t tell from your code block precisely what the problem is, but it isn’t a problem with system.perspective.download(). Possibly it is the paired quotation marks. You must use the straight quote marks in code.
That error generally means a syntax error. I see curly quotes in your code’s third line around test.csv. Those should be ASCII straight double quotes. This commonly occurs when someone posts code without proper formatting marks, and this forum tries to “prettify” the “paragraphs”, like here. Don’t cut and paste from improperly formatted code on forums.