如何使用win32com python在Excel单元格中添加下拉列表

5

我正在尝试使用Python的win32com API在Excel单元格中添加下拉菜单,但无法实现。

以下是我的代码:

from win32com.client import Dispatch
import os
import win32api
path = os.getcwd()

path1 = path + '\\myExcel.xlsx'
try:
    xl = Dispatch("Excel.Application")   
    xl.Visible = 1  # fun to watch!
    wb = xl.Workbooks.Open(Filename=path1)

    ws = wb.Worksheets(1)

    ws.Cells(1,1).Value = "GREEN"
    ws.Cells(2,1).Value = "YELLOW"
    ws.Cells(3,1).Value = "RED"
    ws.Cells(4,1).Value = "WHITE"
    ws.Cells(5,1).Value = "NOT SURE"
    ws.Cells(6,1).Value = "["GREEN", "YELLOW", "RED", "WHITE", "NOT SURE"]" //I want drop down here
    wb.Close(SaveChanges=True)
    xl.Quit()
except Exception as e:
    print(e)

@ycx 这是一个列表。我修改了我的问题。 :) - Saurabh Agrawal
@MediaEU 如何使用win32com python在Excel单元格中添加下拉列表?ws.Cells(6,1).Value = "["GREEN", "YELLOW", "RED", "WHITE", "NOT SURE"]" //我想在这里添加下拉列表 - Saurabh Agrawal
1
OP想要做的是在Excel 2016中可以交互式完成的操作:数据选项卡|数据工具窗格|数据验证|数据验证...|设置|允许:列表,来源:<单元格引用>。以下是使用VBA完成此操作的方法:https://software-solutions-online.com/excel-vba-drop-down-lists/#Jump2 - BoarGules
@DavidHeffernan 是的,它可以。您可以查看 BoarGules 发布的链接。它正在执行相同的操作,但使用 VBA。 - Saurabh Agrawal
1
@SaurabhAgrawal,与您的代码所做的方式不同,应该设置ws.Cells(6,1).Validation而不是ws.Cells(6,1).Value。请参考VBA示例进行设置。所有这类Excel文档都假定您正在使用VBA编程,因此您需要学会将解决方案转换为Python。 - BoarGules
显示剩余5条评论
1个回答

4

由于这行代码,你所做的并没有生效。

ws.Cells(6,1).Value = "["GREEN", "YELLOW", "RED", "WHITE", "NOT SURE"]" //I want drop down here

这行代码是要设置单元格的,就像前面的行所做的那样。(或者说,试图对其进行设置:该行包含两个语法错误,一个在引号中,另一个在注释中。)

但你不想设置单元格的值,而是希望对单元格应用验证。因此,您需要设置ws.Cells(6,1).Validation对象的属性。

仅考虑您的try...except子句中的代码,代码看起来像这样:

xl = Dispatch("Excel.Application")   
xl.Visible = 0  # Not really such fun to watch because the code below closes down Excel
                # straightaway. xl.Visible = 1 will just show a screen flicker.
wb = xl.Workbooks.Open(Filename=path1)

ws = wb.Worksheets(1)

ws.Cells(1,1).Value = "GREEN"
ws.Cells(2,1).Value = "YELLOW"
ws.Cells(3,1).Value = "RED"
ws.Cells(4,1).Value = "WHITE"
ws.Cells(5,1).Value = "NOT SURE"

# Set up validation
val = ws.Cells(6,1).Validation
val.Add(Type=3, AlertStyle=1, Operator=1, Formula1="=Sheet1!A1:A5")
val.IgnoreBlank = -1
val.InCellDropdown = -1
val.InputTitle = ""
val.ErrorTitle = ""
val.InputMessage = ""
val.ErrorMessage = ""
val.ShowInput = -1
val.ShowError = -1

wb.Close(SaveChanges=True)
xl.Quit()

设置验证的代码与我评论中给出的参考示例完全相同。从Excel获取的对象不是Python对象:它们是VBA对象的薄Python包装器,而这些VBA对象遵循自己的约定,而不是Python的约定。因此,Python代码完全遵循VBA,除了语法。唯一的区别是外观。
  1. .Add带有括号,因为Python中的函数必须有括号(VBA方法没有)。
  2. 命名参数使用Python的=而不是VBA的:=
  3. xlBetween这样的常量表示整数值;您可以在MSDN上找到这些值。
  4. VBA将True定义为-11True也可能有效:我没有尝试过。
  5. Python没有VBA的with语句的等效语句,因此val在类似val.ErrorMessage = ""的赋值中必须是显式的,而不是像VBA中那样是隐式的。
这是我得到的结果。

Excel 2016 screenshot of drop-down list


啊,这就是我代码中缺失的部分...非常感谢你的帮助BoarGules。但似乎 val.IgnoreBlank = True 不起作用,因为如果单元格为空,则仍会显示在下拉列表中。 - Saurabh Agrawal
它只是看起来不起作用。 忽略空白并不意味着Excel将忽略您在Formula1中提供的命名范围中的空单元格,并构建一个没有它们的下拉列表,正如您所期望的那样。这意味着当空白不是下拉列表中的选项之一时,Excel不会抱怨单元格中的空值。https://www.mrexcel.com/forum/excel-questions/599304-data-validation-list-doesnt-ignore-blank-cells.html - BoarGules
谢谢您向我展示了一些关键点。顺便说一下,win32com 内部使用 COM 对象,而我想避免使用它。有没有其他方法可以访问完整的 Excel 功能而不使用 COM 对象? - Saurabh Agrawal
我猜你已经发现了这个解决方案无法部署到没有安装Excel的机器上。win32com模块使用COM,这是它的目的,正如其名称所示。xlwings模块也使用COM,但正如其名称所示,它是专门针对Excel的。你可以尝试使用openpyxl。它至少支持一些验证(https://openpyxl.readthedocs.io/en/stable/validation.html),但我不能确定它的支持是否扩展到完整的Excel功能。唯一能够做到Excel所能做的*所有事情*的软件就是Excel本身,而COM是访问它的编程方式。 - BoarGules
如何将记录列表添加到下拉菜单中,而不是使用公式1="=Sheet1!A1:A5"。 - praveen kumar
我认为在Excel本身中做那件事是不可能的。因此,你也不能使用com来做它。 - BoarGules

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接