{"id":2212,"date":"2026-07-28T15:33:58","date_gmt":"2026-07-28T07:33:58","guid":{"rendered":"https:\/\/xlwings.net\/blog\/?p=2212"},"modified":"2026-03-28T10:47:44","modified_gmt":"2026-03-28T10:47:44","slug":"how-to-use-applicationusercontrol-in-the-xlwings-api-way","status":"publish","type":"post","link":"https:\/\/xlwings.net\/blog\/how-to-use-applicationusercontrol-in-the-xlwings-api-way\/","title":{"rendered":"How to use Application.UserControl in the xlwings API way"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The Application.UserControl property in Excel&#8217;s object model is a read-only Boolean value that indicates whether the Excel application was started by a user (True) or programmatically by another application (False). In xlwings, this property is accessed through the <code>api<\/code> property of the App object, which provides direct access to the underlying Excel object model. This can be useful for determining the context in which Excel is running, allowing for conditional logic in automation scripts\u2014for example, to avoid closing an instance that a user is actively interacting with.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Functionality:<\/strong><br>The primary function is to check the startup origin of the Excel instance. If <code>UserControl<\/code> returns <code>True<\/code>, Excel was launched directly by a user (e.g., via desktop shortcut or file double-click). If <code>False<\/code>, it was started programmatically, often through automation tools like xlwings, COM, or other scripting methods. This property helps in managing application lifecycle and user experience in automated processes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Syntax:<\/strong><br>In xlwings, you access this property via the <code>api<\/code> attribute of an App instance. The syntax is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.api.UserControl<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>app<\/code>: An instance of the xlwings App class representing the Excel application.<\/li>\n\n\n\n<li>The property returns a Boolean: <code>True<\/code> for user-controlled, <code>False<\/code> for programmatically controlled.<br>No parameters are required, as it is a property, not a method.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Code Example:<\/strong><br>Here is a practical example using xlwings to check the UserControl property and perform actions based on its value:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import xlwings as xw\n\n# Connect to the active Excel instance or create a new one\napp = xw.apps.active\n\n# Check if Excel was started by the user\nif app.api.UserControl:\n    print(\"Excel was started by the user. Avoid automated shutdown.\")\n    # Perform user-friendly operations, like leaving Excel open\nelse:\n    print(\"Excel was started programmatically. Safe to close after tasks.\")\n    # Perform automated tasks and close Excel\napp.quit()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, the script prints a message and decides whether to quit Excel based on the UserControl value. This prevents accidentally closing an Excel window that a user might be working in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another use case involves launching Excel conditionally:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import xlwings as xw\n\n# Start a new instance of Excel programmatically\napp = xw.App(visible=True)\nprint(f\"UserControl status: {app.api.UserControl}\") # Likely outputs False\n\n# If you need to ensure user control for interaction, you might check and alert\nif not app.api.UserControl:\n    # Add a workbook for user input, but keep automation running\n    wb = app.books.add()\n    wb.sheets&#91;0].range(\"A1\").value = \"Please enter data here.\"\n    # Keep app open without quitting automatically<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Application.UserControl property in Excel&apos;s object model is a read-only Boolean value that indic&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[],"class_list":["post-2212","post","type-post","status-publish","format-standard","hentry","category-xlwings-api-reference"],"_links":{"self":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts\/2212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/comments?post=2212"}],"version-history":[{"count":1,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts\/2212\/revisions"}],"predecessor-version":[{"id":3382,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts\/2212\/revisions\/3382"}],"wp:attachment":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/media?parent=2212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/categories?post=2212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/tags?post=2212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}