# Using system.\* inside a custom function?

**URL:** <https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355>\
**Category:** Ignition\
**Created:** [November 14, 2016, 6:52pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355 "2016-11-14T18:52:13Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![TedNewman](https://avatars.discourse-cdn.com/v4/letter/t/85e7bf/32.png) [@TedNewman](https://forum.inductiveautomation.com/u/TedNewman)\
**Post date:** [November 14, 2016, 6:52pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/1 "2016-11-14T18:52:13Z")

</div>

I have a custom function on a component called refreshData. Inside this function I have a call to [tt]system.util.invokeAsynchronous[/tt] and it was giving me the error that it couldn’t find the attribute [tt]invokeAsynchronous[/tt]. I tried it with [tt]invokeLater[/tt] as well and it had the same issue. I added a simple call to [tt]system.db.runQuery(“Select 4”)[/tt] and this time instead of erroring on [tt]runQuery[/tt] it errored on [tt]db[/tt] with a similar message:

`Traceback (most recent call last):
  File "<event:visionWindowOpened>", line 5, in <module>
  File "<custom-function refreshData>", line 4, in refreshData
AttributeError: 'com.inductiveautomation.ignition.common.script.Scr' object has no attribute 'db'
`  
This code is being called from inside [tt]visionWindowOpened[/tt], if that makes any difference. I even tried calling the function with [tt]invokeLater[/tt] from within the [tt]visionWindowOpened[/tt] event thinking maybe there was an issue with system.\* not having fully loaded yet or something odd like that, but that made no difference.

Help!

---

<div class="post-metadata">

**Author:** ![MMaynard](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mmaynard/32/3366_2.png) [@MMaynard](https://forum.inductiveautomation.com/u/MMaynard)\
**Post date:** [November 14, 2016, 7:21pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/2 "2016-11-14T19:21:34Z")

</div>

Have you tried adding import system at the top?

---

<div class="post-metadata">

**Author:** ![TedNewman](https://avatars.discourse-cdn.com/v4/letter/t/85e7bf/32.png) [@TedNewman](https://forum.inductiveautomation.com/u/TedNewman)\
**Post date:** [November 14, 2016, 7:25pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/3 "2016-11-14T19:25:48Z")

</div>

Yes I forgot to mention that. Adding [tt]import system[/tt] changes nothing.

---

<div class="post-metadata">

**Author:** ![MMaynard](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mmaynard/32/3366_2.png) [@MMaynard](https://forum.inductiveautomation.com/u/MMaynard)\
**Post date:** [November 14, 2016, 7:36pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/4 "2016-11-14T19:36:14Z")

</div>

I’m not sure why it isn’t finding system  
What version of Ignition? Can you post the actual code from the component?

While you are in the code editor, what happens when you type system.db. and then hit control - space?

---

<div class="post-metadata">

**Author:** ![TedNewman](https://avatars.discourse-cdn.com/v4/letter/t/85e7bf/32.png) [@TedNewman](https://forum.inductiveautomation.com/u/TedNewman)\
**Post date:** [November 14, 2016, 9:40pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/5 "2016-11-14T21:40:13Z")

</div>

Here is the code:

`def refreshData(self)
	import system
	system.db.runQuery("Select 4") #Testing system.*
	progressBar = self.parent.getComponent(self.progressBar)
	progressBar.visible = True
	def runQ():
		query = """select distinct concat(r.recipename, " - ", r.tooltypeid) as RecipeName,count(r.id) as Recipes
		from runrecipes rr
		left join recipes r
			on r.recipename = rr.recipename
		where rr.recipename is not null
		group by rr.recipename
		limit 5"""
		res = system.db.runQuery(query)
		self.data = res
		progressBar.visible = False
	system.util.invokeAsynchronous(runQ) #Why is this failing?`  
Ignition version is 7.8.4

Control+Space pops up the list of all available commands as usual. This list includes the commands I am trying to execute. Copying/pasting this code into the Script Console (and modifying it to not have invalid references to [tt]self[/tt], [tt]progressBar[/tt] etc.) executes without issue.

I know it’s possible to use these things within custom functions because I have executed queries and invocations in custom functions in other projects.

---

<div class="post-metadata">

**Author:** ![JGJohnson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jgjohnson/32/29582_2.png) [@JGJohnson](https://forum.inductiveautomation.com/u/JGJohnson)\
**Post date:** [November 14, 2016, 10:18pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/6 "2016-11-14T22:18:13Z")

</div>

[quote=“TedNewman”]Here is the code:

`def refreshData(self)
	import system
	system.db.runQuery("Select 4") #Testing system.*
	progressBar = self.parent.getComponent(self.progressBar)
	progressBar.visible = True
	def runQ():
		query = """select distinct concat(r.recipename, " - ", r.tooltypeid) as RecipeName,count(r.id) as Recipes
		from runrecipes rr
		left join recipes r
			on r.recipename = rr.recipename
		where rr.recipename is not null
		group by rr.recipename
		limit 5"""
		res = system.db.runQuery(query)
		self.data = res
		progressBar.visible = False
	system.util.invokeAsynchronous(runQ) #Why is this failing?`  
Ignition version is 7.8.4

Control+Space pops up the list of all available commands as usual. This list includes the commands I am trying to execute. Copying/pasting this code into the Script Console (and modifying it to not have invalid references to [tt]self[/tt], [tt]progressBar[/tt] etc.) executes without issue.

I know it’s possible to use these things within custom functions because I have executed queries and invocations in custom functions in other projects.[/quote]

There is no semicolon after the define function statement. Fix that and see if that does it.

---

<div class="post-metadata">

**Author:** ![TedNewman](https://avatars.discourse-cdn.com/v4/letter/t/85e7bf/32.png) [@TedNewman](https://forum.inductiveautomation.com/u/TedNewman)\
**Post date:** [November 14, 2016, 10:27pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/7 "2016-11-14T22:27:28Z")

</div>

[quote=“JGJohnson”]  
There is no semicolon after the define function statement. Fix that and see if that does it.[/quote]

That’s because I had to manually type it to paste it here, sorry. It DOES have a colon in my actual code. The first line of custom functions is not editable and therefore blocks all keystrokes including copy/paste. Quite annoying if you ask me.

---

<div class="post-metadata">

**Author:** ![TedNewman](https://avatars.discourse-cdn.com/v4/letter/t/85e7bf/32.png) [@TedNewman](https://forum.inductiveautomation.com/u/TedNewman)\
**Post date:** [November 15, 2016, 10:06pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/8 "2016-11-15T22:06:51Z")

</div>

I was able to solve it, though I still don’t know what the bug was exactly.

It looks like the issue had something to do with calling it from within the [tt]visionWindowOpened[/tt] event handler. Placing the function call in a button and clicking the button worked with no problems. I had tried using [tt]system.util.invokeLater(root.getComponent(“My Component”).myFunction)[/tt] to invoke the function later but that didn’t make a difference. However I found that if I put the call to myFunction() inside another function an invoked that one later, it worked.

`root = event.source.getRootContainer()
def doLater():
    root.getComponent("My Component").myFunction()
system.util.invokeLater(doLater)`  
I don’t understand why the cases of those would be different but clearly something about it changed the way system.\* was loaded or something.

---

<div class="post-metadata">

**Author:** ![systemparadox](https://avatars.discourse-cdn.com/v4/letter/s/b5e925/32.png) [@systemparadox](https://forum.inductiveautomation.com/u/systemparadox)\
**Post date:** [November 2, 2017, 11:35am UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/9 "2017-11-02T11:35:59Z")

</div>

Inductive have confirmed that this is a bug (ticket #44974).

Custom functions on windows cannot access project/system or import anything. The workaround is to move the custom function to a component. The best option is to move them to the Root Container.

I would strongly advise against using multiple invokeLater calls to fix this, as this is likely to be unreliable.

---

<div class="post-metadata">

**Author:** ![silverbacknet](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/silverbacknet/32/7385_2.png) [@silverbacknet](https://forum.inductiveautomation.com/u/silverbacknet)\
**Post date:** [July 4, 2020, 10:08pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/10 "2020-07-04T22:08:21Z")

</div>

Old thread now, but the best I found, so I figured I’d post back. I’ve just accepted that in Vision every single custom method needs to start with a system argument that you pass around like a… well, you know. Throwing in a second argument that’s rootContainer is often helpful, too. It’s so crazy that the components are completely shorn of their context outside of event handlers.

I actually did find a hack so dirty even I won’t use it. It’s way more boilerplate than just passing the system around anyway.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 5, 2020, 2:10am UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/11 "2020-07-05T02:10:56Z")

</div>

Huh. I’ve never had this problem on components. As noted, this was a bug on custom methods for Vision _ **windows** _, not components.

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 7:20pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/12 "2021-06-11T19:20:08Z")

</div>

Hello @silverbacknet ,  
I’m having similar issues ([Attribute Error in Component Custom Method](http://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712)). I don’t mind passing a system argument…can you explain how I’d actually do that?  
Thank you and regards,  
Ted.

---

<div class="post-metadata">

**Author:** ![silverbacknet](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/silverbacknet/32/7385_2.png) [@silverbacknet](https://forum.inductiveautomation.com/u/silverbacknet)\
**Post date:** [June 11, 2021, 8:15pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/13 "2021-06-11T20:15:57Z")

</div>

It’s literally just passing the object `system` to the custom method. Say you’ve defined a custom method `doStuff` on the window, and you have parameters `stuffToDo, stuffData`.

Change the parameters to `system, stuffToDo, stuffData`, and invoke it from any component event handler as  
`doStuff(system, "log", event.data)`  
instead of just  
`doStuff("log", event.data)`.

Now you’ve brought the entire system.\* set of internal functions in, and you can use them as usual.

I do it this way, instead of putting it at the end, since typically you either require the functions or not when you’re making the method. But you can make it the last argument with a `= Null` default and test against that before any use, if you want to be sure you don’t break any legacy call.

---

<div class="post-metadata">

**Author:** ![mark.sluser](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mark.sluser/32/19753_2.png) [@mark.sluser](https://forum.inductiveautomation.com/u/mark.sluser)\
**Post date:** [June 16, 2021, 2:50pm UTC](https://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/14 "2021-06-16T14:50:50Z")

</div>

Thank you @silverbacknet for your solution. It worked like a charm.

This is still a bug and I am running Ignition 8.1.4.
