Search code examples
pythonwin32comautofilter

How to AutoFilter Excel by RGB cell color with win32com in Python


Let me start by saying that I am not a very skilled programmer, so please keep your answers as simple as possible so I have a chance to understand :-)

I am trying to figure out how to use win32com to open Excel and AutoFilter a column based on cell background colour. The VBA code for what I want to do is this:

Selection.AutoFilter
    ActiveSheet.Range("$A$1:$S$613").AutoFilter Field:=2, Criteria1:=RGB(255, _
        153, 0), Operator:=xlFilterCellColor

I can make it work by using a VBA color constant value for yellow

ws.Range("B:B").AutoFilter(Field=1, Criteria1=65535, Operator=8)

But I need to be able to filter by more colours than just the VBA color constant colors.

My code so far is:

from win32com.client import constants as c 

excel = win32com.client.gencache.EnsureDispatch("Excel.Application")
excel.Visible = True
wb = excel.Workbooks.Open("path\to\file\filename.xlsm", False, True) 
ws = wb.Worksheets("Sheet1")

ws_current.Range('B:B').AutoFilter(Field=1, Criteria1=65535, Operator=c.xlFilterCellColor)

This works to filter by the color yellow, but I need to be able to replace the Criteria1 Field with an RGB value.

Using this code:

ws_current.Range('B:B').AutoFilter(Field=1, Criteria1=RGB(255,255,0), Operator=c.xlFilterCellColor)

results in this error:

Traceback (most recent call last):
  File "C:\Users\UserName\AppData\Roaming\Python\Python38\site-packages\IPython\core\interactiveshell.py", line 3437, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-64-809552ca6582>", line 1, in <module>
    ws_current.Range('B:B').AutoFilter(Field=1, Criteria1=RGB(255,255,0), Operator=c.xlFilterCellColor)
NameError: name 'RGB' is not defined

Thanks in advance for any insights


Solution

  • The RGB macro comes from the Win32 API and is implemented in Python by pywin32.

    In Python, if you have installed pywin32 (which you will have if you are using win32com), you can just write:

    from win32api import RGB
    
    n = RGB(255,255,0)
    print(n)
    

    which yields 65535.

    So if the OP simply adds the line from win32api import RGB the original code should work.