Blog

How to use Application.Version in the xlwings API way

The Application object’s Version member in Excel’s object model is a read-only property that returns the version number of the Excel application instance as a string. When automating Excel with xlwings, this property is invaluable for implementing version-specific logic, ensuring compatibility, or logging the environment in which a script runs. Since xlwings acts as a bridge between Python and Excel’s COM (Component Object Model) or AppleScript (on macOS) interfaces, it provides direct access to this property through its API.

Functionality
The primary function of the Version property is to retrieve the exact version number of Microsoft Excel. This information typically follows a format like “16.0” for Excel 2016 or 365, or “15.0” for Excel 2013, allowing scripts to adapt their behavior based on the host application’s capabilities. It is particularly useful for debugging, conditional feature usage (e.g., leveraging functions introduced in newer versions), or generating reports that include the software environment details.

Syntax in xlwings
In xlwings, you access the Application object via the app property of a Book (workbook) object or directly through an App instance. The Version property is then called as an attribute. The syntax is straightforward, as it does not accept any parameters.

# When you have an existing workbook object (book)
version_from_book = book.app.version

# When you have an App instance (app)
version_from_app = app.version

Both approaches return a string representing the Excel version. The property is accessed directly without parentheses, as it is not a method.

Code Examples
Below are practical examples demonstrating how to use the Version property in xlwings scripts.

Example 1: Retrieving and Printing the Excel Version
This basic example opens Excel (if not already running), creates a new workbook, and prints the version to the console. It ensures the Excel application is properly instantiated.

import xlwings as xw

# Start Excel and create a new workbook
app = xw.App(visible=False) # Set visible=True to see the Excel window
wb = app.books.add()

# Get the Excel version
excel_version = app.version
print(f"Excel version: {excel_version}")

# Save, close, and quit (cleanup)
wb.save('example_version.xlsx')
wb.close()
app.quit()

Example 2: Conditional Logic Based on Version
This example shows how to implement version-specific behavior. It checks if the Excel version is 16.0 or higher (typically Excel 2016/365) to decide whether to use a newer function or a fallback method. This is crucial for maintaining compatibility across different user installations.

import xlwings as xw
import re

app = xw.App(visible=False)
wb = app.books.add()

version_str = app.version
# Extract the major version number (e.g., 16 from "16.0")
major_version = int(re.search(r'^(\d+)', version_str).group(1))

if major_version >= 16:
    print("Using features available in Excel 2016 and later.")
    # Here you could call newer Excel functions via xlwings, e.g., XLOOKUP if supported
else:
    print("Using legacy compatibility mode for older Excel versions.")
    # Implement alternative logic for older versions

app.quit()

Example 3: Logging Environment Information for a Report
In this scenario, the script logs the Excel version along with other system details into a worksheet. This is useful for audit trails or technical documentation generated by the script itself.

import xlwings as xw
from datetime import datetime

app = xw.App(visible=False)
wb = app.books.add()
sheet = wb.sheets[0]

# Write environment info to cell A1
info_text = f"Report generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
info_text += f"Excel version: {app.version}\n"
info_text += f"xlwings version: {xw.__version__}"

sheet.range('A1').value = info_text
sheet.range('A1').rows.autofit() # Adjust row height for readability

wb.save('environment_report.xlsx')
app.quit()

How to use Application.VBE in the xlwings API way

The Application.VBE property in Excel’s object model provides a reference to the Visual Basic for Applications (VBA) development environment. This is a powerful and advanced feature, primarily used for programmatically interacting with the VBA project, such as adding modules, reading code, or managing references. In xlwings, this property is accessed through the api property, which exposes the underlying pywin32 COM object, allowing you to call the raw Excel VBA object model methods.

Functionality:
The VBE property returns the root object of the VBA Extensibility library (the VBIDE.VBE object). It enables automation of the VBA Integrated Development Environment (IDE) from an external script. Common use cases include:

  • Dynamically adding standard or class modules to a workbook.
  • Inserting or modifying VBA macro code.
  • Inspecting existing VBA project components.
  • Enabling programmatic access to the VBA project (which often requires setting the “Trust access to the VBA project object model” in Excel’s Trust Center settings).

Syntax in xlwings:

vbe_object = xw.apps[app_key].api.VBE
# or for the active Excel instance
vbe_object = xw.apps.active.api.VBE
  • xw.apps[app_key] or xw.apps.active: This gets the specific or active xlwings App object, representing an Excel instance.
  • .api: This is the crucial bridge to the pywin32/COM object, providing access to the native Excel Application object.
  • .VBE: This is the property call that returns the VBIDE.VBE object.

Important Notes:

  1. Security Setting: To use the VBE property successfully, Excel must have the “Trust access to the VBA project object model” checkbox enabled. This is found under File > Options > Trust Center > Trust Center Settings > Macro Settings.
  2. Library Reference: Your Python environment needs the win32com library (provided by pywin32). xlwings handles this dependency.
  3. VBIDE Constants: When using methods of the returned VBIDE.VBE object, you may need constants like vbext_ct_StdModule. These are available in the win32com.client.constants module after ensuring the VBIDE type library is referenced. A simpler approach is to use their known integer values (e.g., 1 for a standard module).

Code Example:
The following example demonstrates how to access the VBE object, check if the VBA project is accessible, and add a new standard module to the active workbook containing a simple macro.

import xlwings as xw

# Connect to the active Excel instance
app = xw.apps.active

# Access the VBE object via the .api property
vbe = app.api.VBE

# Get the active workbook's VBA project
# The 'VBProject' property of a Workbook is accessed via its .api
active_wb_vbproject = app.books.active.api.VBProject

# Check if we have access (this will raise an error if trust settings are off)
print(f"VBE Version: {vbe.Version}")

# Add a new standard module to the active workbook's VBA project
# Constant vbext_ct_StdModule = 1
new_module = active_wb_vbproject.VBComponents.Add(1) # 1 represents a standard module
new_module.Name = "MyNewModule"

# Insert code into the new module
code_string = """
Sub HelloFromXlwings()
MsgBox "This module was added programmatically via xlwings!"
End Sub
"""
new_module.CodeModule.AddFromString(code_string)

print(f"Module '{new_module.Name}' added successfully.")

How to use Application.Value in the xlwings API way

The Value member of the Application object in the Excel object model is a property that can be used to get or set the value of the active cell or a specified range through the xlwings API. In xlwings, this is typically accessed via the app object, which represents the Excel application instance. The primary function of the Application.Value property in xlwings is to interact with cell data programmatically, allowing for dynamic data entry, retrieval, and manipulation directly from Python. It serves as a bridge between Python scripts and Excel worksheets, enabling automation of data processing tasks without manual intervention.

In xlwings, the syntax for accessing the Value property of the Application object is not directly used in the same way as in VBA. Instead, xlwings provides a more Pythonic approach through the app object and its associated methods. To get or set values, you typically work with Range objects. However, you can access the active cell’s value via the application context. The general syntax is:

  • To get the value: app.active_cell.value
  • To set the value: app.active_cell.value = new_value

Here, app is an instance of the xlwings App class representing the Excel application. The active_cell refers to the currently selected cell in the active workbook. This property can return or accept various data types, such as numbers, strings, dates, or even arrays, depending on the context. For setting values, you can assign a single value or a list of lists to represent a 2D array for a range.

For example, to retrieve the value from the active cell in Excel using xlwings, you can use the following code snippet:

import xlwings as xw

# Connect to the active Excel instance
app = xw.apps.active

# Get the value of the active cell
current_value = app.active_cell.value
print(f"The active cell value is: {current_value}")

# Set a new value to the active cell
app.active_cell.value = "Hello from xlwings"

In this example, app.active_cell.value is used to both read and write data. This demonstrates how the Value property facilitates basic data interaction. For more complex scenarios, such as working with specific ranges, you can use app.range('A1:B2').value to get or set multiple values at once. The Value property in this context automatically handles data conversion between Excel and Python types, making it seamless for data analysis tasks.

Another practical use case is when automating data entry from a Python list into an Excel sheet. For instance:

import xlwings as xw

# Start or connect to Excel
app = xw.App(visible=True) # Make Excel visible
wb = app.books.add() # Add a new workbook
ws = wb.sheets[0] # Access the first worksheet

# Define a Python list of data
data = [[1, "Apple", 2.5], [2, "Banana", 1.8], [3, "Cherry", 3.2]]

# Write the data to a range starting at cell A1
ws.range('A1').value = data

# Read back the data to verify
retrieved_data = ws.range('A1:C3').value
print(f"Retrieved data: {retrieved_data}")

# Close the workbook and quit Excel
wb.close()
app.quit()

How to use Application.UseSystemSeparators in the xlwings API way

The Application.UseSystemSeparators property in Excel is a Boolean value that controls whether Excel uses the system’s decimal and thousands separators for number formatting, or the separators specified in the Windows regional settings for the Excel application itself. When set to True (the default), Excel will use the separators defined by the operating system’s regional settings (e.g., a period for decimal and a comma for thousands in the US locale). When set to False, Excel will use the alternative separators, which are typically a comma for decimal and a period for thousands, as might be used in some European locales. This property is crucial for ensuring data is displayed and interpreted correctly in international environments, especially when workbooks are shared across different regional systems.

In the xlwings API, this property is accessed through the Application object. The syntax for getting or setting the property is straightforward:

import xlwings as xw

app = xw.apps.active # or xw.App() for a new instance

# Get the current value
current_setting = app.api.UseSystemSeparators

# Set the value
app.api.UseSystemSeparators = False # Use alternative separators

Here, app.api provides direct access to the underlying Excel Application object from the COM interface. The UseSystemSeparators property is a read/write Boolean. No parameters are required for getting or setting it. To determine the system’s current separators, you can check the Application.DecimalSeparator and Application.ThousandsSeparator properties, which are influenced by this setting.

Example use cases include preparing a workbook for users in a locale with different formatting norms or ensuring consistent number parsing in automated scripts. Below is a practical xlwings code example that demonstrates toggling this property and observing the effect on cell formatting:

import xlwings as xw

# Connect to the active Excel instance
app = xw.apps.active

# Display initial state
print(f"Initial UseSystemSeparators: {app.api.UseSystemSeparators}")
print(f"Decimal Separator: {app.api.DecimalSeparator}")
print(f"Thousands Separator: {app.api.ThousandsSeparator}")

# Change to alternative separators
app.api.UseSystemSeparators = False
print(f"\nAfter setting to False:")
print(f"Decimal Separator: {app.api.DecimalSeparator}")
print(f"Thousands Separator: {app.api.ThousandsSeparator}")

# Write a sample number to a cell to see formatting
wb = app.books.active
ws = wb.sheets[0]
ws.range('A1').value = 12345.67
ws.range('A1').number_format = '#,##0.00'

# The display in Excel will reflect the current separators.
# For example, with UseSystemSeparators=False, it might show as "12.345,67" depending on system settings.

# Revert to system separators
app.api.UseSystemSeparators = True
print(f"\nReverted to True:")
print(f"Decimal Separator: {app.api.DecimalSeparator}")
print(f"Thousands Separator: {app.api.ThousandsSeparator}")

# Save and close
wb.save()
app.quit()

How to use Application.UserName in the xlwings API way

The Application.UserName property in Excel’s object model represents the name of the current user as set in the Excel application options. In xlwings, this property can be accessed to retrieve or set the user name, which is useful for personalizing workbooks, tracking user activity, or implementing user-specific logic in automated Excel tasks. This property reflects the name entered under “File > Options > General > User name” in Excel, and changes made via xlwings will update this setting globally within the Excel instance.

Functionality:
The primary function is to get or set the current user’s name in Excel. This can be utilized to customize workbook behavior, such as displaying personalized messages, logging user interactions, or controlling access to certain features based on the user. It is a straightforward way to integrate user identity into automation scripts.

Syntax:
In xlwings, the Application object is accessed through the app property of a workbook or directly via xw.apps. The UserName property is used as follows:

  • To get the current user name: user_name = app.user_name
  • To set a new user name: app.user_name = "NewUserName"
    Here, app refers to an instance of the Excel application (e.g., xw.App or xw.apps.active). The property is a string, and setting it requires a valid string input; if no argument is provided or an invalid type is used, Excel may raise an error.

Parameters:
The UserName property does not take parameters in the traditional sense, as it is a property getter/setter. When setting, the value must be a string representing the desired user name. There are no additional options or enumerations; any text can be used, but it is typically limited to alphanumeric characters and common symbols.

Examples:
Below are practical xlwings API code instances demonstrating the use of Application.UserName:

  1. Retrieving the Current User Name:
    This example connects to the active Excel instance and prints the current user name.
import xlwings as xw
# Connect to the active Excel application
app = xw.apps.active
# Get the user name
current_user = app.user_name
print(f"Current user: {current_user}")
  1. Setting a New User Name:
    This example changes the user name to a custom value and verifies the update.
import xlwings as xw
# Start a new Excel instance (or use an existing one)
app = xw.App(visible=True)
# Set a new user name
app.user_name = "JohnDoe"
# Check the updated name
updated_user = app.user_name
print(f"Updated user: {updated_user}")
# Close the application
app.quit()
  1. Using User Name for Personalization:
    This example retrieves the user name and uses it to personalize a message in a workbook.
import xlwings as xw
# Open a specific workbook
wb = xw.Book("example.xlsx")
app = wb.app
# Get user name and insert into a cell
user = app.user_name
wb.sheets[0].range("A1").value = f"Welcome, {user}!"
# Save and close
wb.save()
wb.close()

How to use Application.UserLibraryPath in the xlwings API way

The Application.UserLibraryPath property in Excel VBA returns the path to the folder where user-defined add-ins (XLA or XLAM files) are typically stored on the user’s system. This path is often used to locate or manage custom add-ins. In xlwings, you can access this property through the Application object, which is part of the Excel object model. The property is read-only, meaning you cannot set it directly via xlwings; it provides information about the system’s configuration.

The syntax for accessing UserLibraryPath in xlwings is straightforward. You first need to create an instance of the Excel application, then reference the Application object to retrieve the property. In xlwings, this is done using the app object, which represents the Excel application. The property is called as an attribute, and it returns a string representing the folder path. There are no parameters for this property, as it simply provides a value. For example, in xlwings, you can call app.api.UserLibraryPath to get the path. Note that app.api provides access to the underlying COM object, allowing you to use Excel’s native properties and methods. The return value is a string, such as “C:\Users[Username]\AppData\Roaming\Microsoft\AddIns” on Windows systems. If the path does not exist or is not set, it may return an empty string or an error, so it’s good practice to handle exceptions.

Here is a code example using xlwings to demonstrate the usage of UserLibraryPath. This example opens an Excel application, retrieves the user library path, prints it, and then checks if the directory exists to ensure it’s valid. It also includes error handling for cases where Excel might not be accessible.

import xlwings as xw
import os

# Start an Excel application instance
app = xw.App(visible=True) # Set visible=False to run in background

try:
    # Access the UserLibraryPath property via the Application object
    user_library_path = app.api.UserLibraryPath

    # Print the retrieved path
    print(f"User Library Path: {user_library_path}")

    # Check if the path exists on the system
    if os.path.exists(user_library_path):
        print("The directory exists.")
    else:
        print("The directory does not exist or is inaccessible.")
except Exception as e:
    print(f"An error occurred: {e}")
finally:
    # Close the Excel application to free resources
    app.quit()

How to use Application.UserControl in the xlwings API way

The Application.UserControl property in Excel’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 api 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—for example, to avoid closing an instance that a user is actively interacting with.

Functionality:
The primary function is to check the startup origin of the Excel instance. If UserControl returns True, Excel was launched directly by a user (e.g., via desktop shortcut or file double-click). If False, 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.

Syntax:
In xlwings, you access this property via the api attribute of an App instance. The syntax is:

app.api.UserControl
  • app: An instance of the xlwings App class representing the Excel application.
  • The property returns a Boolean: True for user-controlled, False for programmatically controlled.
    No parameters are required, as it is a property, not a method.

Code Example:
Here is a practical example using xlwings to check the UserControl property and perform actions based on its value:

import xlwings as xw

# Connect to the active Excel instance or create a new one
app = xw.apps.active

# Check if Excel was started by the user
if app.api.UserControl:
    print("Excel was started by the user. Avoid automated shutdown.")
    # Perform user-friendly operations, like leaving Excel open
else:
    print("Excel was started programmatically. Safe to close after tasks.")
    # Perform automated tasks and close Excel
app.quit()

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.

Another use case involves launching Excel conditionally:

import xlwings as xw

# Start a new instance of Excel programmatically
app = xw.App(visible=True)
print(f"UserControl status: {app.api.UserControl}") # Likely outputs False

# If you need to ensure user control for interaction, you might check and alert
if not app.api.UserControl:
    # Add a workbook for user input, but keep automation running
    wb = app.books.add()
    wb.sheets[0].range("A1").value = "Please enter data here."
    # Keep app open without quitting automatically

How to use Application.UsedObjects in the xlwings API way

The Application.UsedObjects property in Excel’s object model provides a powerful way to access all objects that are currently in use within a workbook. In the context of xlwings, this property is exposed through the api property, allowing Python scripts to programmatically inspect and manage the resources consumed by an Excel instance. This is particularly useful for debugging memory issues, monitoring application performance, or programmatically cleaning up objects to prevent memory leaks in long-running automation tasks.

Functionality
The primary function of Application.UsedObjects is to return a Workbooks collection that represents all objects—such as ranges, charts, shapes, and named ranges—that are currently allocated in memory. This collection includes objects from all open workbooks. By accessing this property, developers can get a count of used objects or iterate through them to perform specific actions, like checking their properties or releasing them if necessary.

Syntax in xlwings
The xlwings library provides a Pythonic interface to Excel’s COM API. To access the UsedObjects property, you must first obtain the Excel Application object via xlwings. The typical syntax is:

import xlwings as xw

# Connect to the active Excel instance or start a new one
app = xw.apps.active.api # or xw.App().api for a new instance

# Access the UsedObjects property
used_objects = app.UsedObjects

Here, app is an xlwings proxy to the Excel Application object, and .api is used to access the underlying COM object. The UsedObjects property returns a collection that can be treated similarly to other Excel collections in xlwings.

Parameters and Usage
The UsedObjects property does not accept any parameters. It is a read-only property that provides a Workbooks collection. Key points to note:

  • The collection’s Count property gives the total number of used objects.
  • You can iterate through the collection using a for loop or access individual items by index (1-based indexing, as is standard in Excel VBA).
  • Each item in the collection is an object that can be of various types (e.g., Range, Chart, Shape). You may need to inspect the object’s type to perform type-specific operations.

Example Code
Below is an xlwings API code example that demonstrates how to use the Application.UsedObjects property to list all used objects and their types in the active Excel instance:

import xlwings as xw

# Connect to the active Excel application
app = xw.apps.active.api

# Get the UsedObjects collection
used_objects = app.UsedObjects

# Print the count of used objects
print(f"Total used objects: {used_objects.Count}")

# Iterate through each used object and display its type and address (if applicable)
for i in range(1, used_objects.Count + 1):
    obj = used_objects.Item(i)
try:
    # Try to get the address for Range objects
    if hasattr(obj, 'Address'):
        print(f"Object {i}: Type={obj.__class__.__name__}, Address={obj.Address}")
    else:
        print(f"Object {i}: Type={obj.__class__.__name__}")
except Exception as e:
    print(f"Object {i}: Error accessing properties - {e}")

# Example: Release objects (if needed, by setting to None or closing workbooks)
# Note: Directly releasing objects from UsedObjects may require careful handling to avoid crashes.

How to use Application.UseClusterConnector in the xlwings API way

The Application.UseClusterConnector property in Excel is a member of the Excel object model that enables or disables the use of a cluster connector for sharing data connections across multiple instances of Excel in a clustered environment, such as a server farm. This property is particularly relevant in enterprise settings where centralized management of data connections is required to improve performance, security, and consistency. When enabled, it allows Excel to utilize a shared connection file stored on a network, rather than relying on individual, local connection files. In xlwings, this property can be accessed and manipulated through the api property of the Application object, providing a way to control this setting programmatically via Python.

The syntax for accessing the UseClusterConnector property in xlwings follows the pattern of referencing Excel VBA properties through the api interface. The property is a Boolean value, meaning it can be set to either True or False. In xlwings, you typically start by instantiating an application object, either by creating a new one or connecting to an existing instance. Once you have the application object, you can get or set the UseClusterConnector property. The xlwings API call format is straightforward: app.api.UseClusterConnector, where app represents the xlwings Application object. This property does not accept parameters directly, as it is a simple property. However, its value determines whether Excel will attempt to use a cluster connector for data connections. It’s important to note that this property might not be available in all versions of Excel or may require specific configurations, such as the presence of a cluster connector setup on the server. In terms of usage, you can retrieve the current setting by reading the property, or modify it by assigning a new Boolean value. For example, setting it to True activates the cluster connector functionality, while False deactivates it, reverting to local connection files. This can be useful in scripts that prepare Excel for automated reporting in clustered environments, ensuring that all instances use the same centralized data source.

To illustrate the use of the Application.UseClusterConnector property with xlwings, consider the following code examples. First, ensure you have xlwings installed and imported in your Python environment. The examples demonstrate how to check the current setting and change it as needed. In the first example, we connect to a running Excel instance and print the current UseClusterConnector value. This is done by using the xw.apps collection to access the active application. The code snippet is as follows:

import xlwings as xw

# Connect to the active Excel application
app = xw.apps.active

# Get the current UseClusterConnector setting
current_setting = app.api.UseClusterConnector
print(f"Current UseClusterConnector setting: {current_setting}")

This will output whether the cluster connector is enabled (True) or disabled (False). In the second example, we create a new Excel application instance and set the UseClusterConnector property to True to enable it. This might be used in an automation script that configures Excel for a server environment. The code is:

import xlwings as xw

# Start a new Excel application
app = xw.App(visible=False) # Run in background if needed

# Set UseClusterConnector to True
app.api.UseClusterConnector = True
print("UseClusterConnector has been enabled.")

# Perform other tasks, like opening workbooks with shared connections
wb = app.books.open('data_source.xlsx')
# ... additional operations ...

# Close the application
app.quit()

How to use Application.UsableWidth in the xlwings API way

The UsableWidth property of the Application object in Excel returns a Double value that represents the maximum width, in points, of the area within the main application window where a workbook can be placed. This measurement excludes the space occupied by fixed elements such as the ribbon, scrollbars, and the taskbar. It is particularly useful for dynamically sizing and positioning windows or user forms to ensure they fit optimally within the available screen space without overlapping interface components.

In xlwings, the Application object is accessed via the app property of a Book instance or directly through xw.apps. The UsableWidth property is a read-only attribute. The general syntax to retrieve this value is:

usable_width = xw.apps[app_key].usable_width
# or, if you have a book object:
usable_width = book.app.usable_width

Where:

  • app_key is the PID (Process ID) of the Excel instance, typically accessed as xw.apps.keys()[index] or by using the active app xw.apps.active.
  • book is an xlwings Book object (e.g., book = xw.Book('file.xlsx')).

There are no parameters for this property.

Code Examples:

  1. Getting the usable width of the active Excel application:
    This is the most straightforward method to check the available horizontal space in the currently active Excel instance.
import xlwings as xw

# Ensure Excel is running and connected
app = xw.apps.active # Gets the active Excel app
current_usable_width = app.usable_width
print(f"The current usable width in the application window is: {current_usable_width} points")
  1. Using UsableWidth to set the width of a specific workbook window:
    You can use this property to programmatically adjust the width of a workbook’s window to occupy a specific percentage of the available space.
import xlwings as xw

# Open or connect to a workbook
wb = xw.Book('Report.xlsx')

# Set the window width to 80% of the application's usable width
target_width = wb.app.usable_width * 0.8
wb.app.api.ActiveWindow.Width = target_width
print(f"Window width set to {target_width:.1f} points (80% of usable width).")

Note: Direct window manipulation (like setting Width) often requires the underlying Excel API (.api), as xlwings’ high-level API focuses primarily on data and formula handling.

  1. Centering a UserForm (using the Excel API via xlwings):
    While xlwings itself does not have direct methods for VBA-style UserForms, you can use UsableWidth with the Excel API to calculate positions for shapes or other objects to simulate centered placement.
import xlwings as xw

app = xw.apps.active
usable_w = app.usable_width
usable_h = app.usable_height # Often used together for centering

# Example: Center a shape horizontally (assuming a shape width of 200 points)
shape_width = 200
target_left_position = (usable_w - shape_width) / 2

# Apply to a shape on the active sheet
sht = app.books.active.sheets.active
my_shape = sht.shapes.add_shape(1, target_left_position, 50, shape_width, 100) # Left, Top, Width, Height
my_shape.text = "Centered Shape"