Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get name of active Excel workbook from Python

Tags:

python

com

I am trying to write a Python script that will access and modify the active Excel workbook using the Excel COM interface. However, I am having difficulty getting this to work when there are multiple Excel instances running. For example, the code

import win32com.client

xl = win32com.client.Dispatch("Excel.Application")
print(xl.ActiveWorkbook.FullName)

prints out the name of the active workbook from the first running instance of Excel only. What I really want is the workbook that I last clicked on, regardless of what Excel instance it was in.

Thanks.

like image 367
Abiel Avatar asked May 20 '10 18:05

Abiel


People also ask

How do I find my workbook name in openpyxl?

Step1: First Import the openpyxl library to the program. Step2: Load/Connect the Excel Workbook to the program. Step3: Use sheetnames property to get the names of all the sheets of the given workbook. Hope you have learned how to get the names of the sheets using the openpyxl in python from this article.

How do I get the name of a sheet in Python?

Algorithm (Steps) Create a variable to store the path of the input excel file. To create/load a workbook object, pass the input excel file to the openpyxl module's load_workbook() function (loads a workbook). By applying the sheetnames attribute to the workbook, you obtain a list of all the sheetnames.

What is WB active in openpyxl?

If wb = openpyxl. Workbook() is calling wb. active , it gives the title of the default first worksheet, which is Sheet .

How do I get the file path from Excel to Python?

Method 2: Find the path to the given file using os. In order to obtain the Current Working Directory in Python, use the os. getcwd() method. This function of the Python OS module returns the string containing the absolute path to the current working directory.


2 Answers

EDIT FOR COMMENTS

There might be a better way to do this.

Install the excellent psutil

import psutil
excelPids = []
for proc in psutil.process_iter():
  if proc.name == "EXCEL.EXE": excelPids.append(proc.pid)

Now enumerate the windows, but get the window title and pid.

windowPidsAndTitle = []
win32gui.EnumWindows(lambda hwnd, resultList: resultList.append((win32gui.GetWindowThreadProcessId(hwnd),win32gui.GetWindowText(hwnd))), windowPidsAndTitle)

Now just find the first pid that is in our excelPids

  for pid,title in windowPidsAndTitle:
    if pid in excelPids:
      return title 

END EDITS

There is a number of things to take into consideration here:

Does one instance have multiple workbooks open? In this case

xl = win32com.client.Dispatch("Excel.Application")
xl.ActiveWorkbook.FullName

Will indeed give you the last active workbook.

Or are there separate instances of EXCEL.EXE running? You can get each instance with:

xl = win32com.client.GetObjec(None, "Excel.Application") #instance one
xl = win32com.client.GetObject("Name_Of_Workbook") #instance two

But this defeats the purpose because you need to know the name AND this will not tell you which one last had focus.

To @tgrays comment above, if your excel instance is guaranteed to be the foreground window then:

import win32gui
win32gui.GetWindowText(win32gui.GetForegroundWindow()) 
#parse this and use GetObject to get your excel instance

But worst case scenerio, multiple instances and you have to find which had focus last, you'll have to enumerate all the windows and find the one you care about:

windows = []
win32gui.EnumWindows(lambda hwnd, resultList: resultList.append(win32gui.GetWindowText(hwnd)),windows)
#enumerates all the windows open from the top down
[i for i in windows if "Microsoft Excel" in i].pop(0)
#this one is closest to the top

Good luck with this one!

like image 129
Mark Avatar answered Oct 13 '22 19:10

Mark


With xlwings you can simply do:

import xlwings as xw
print(xw.books.active.name)

This will correctly work even if you have multiple instances of Excel open.

like image 42
Felix Zumstein Avatar answered Oct 13 '22 21:10

Felix Zumstein