使用 Openpyxl 实现列表数据验证时遇到问题

问题描述 投票:0回答:1

我正在使用 Python 中的 openpyxl 库将数据验证规则应用于 Excel 电子表格中的特定单元格。虽然我可以成功更改单元格的颜色填充,但我遇到了其他类型的数据验证问题,这些问题没有按预期应用。下面是我与数据验证相关的代码片段:

    if ws.max_row < 20:
        for i in range(ws.max_row + 1, 101): 
            ws.cell(row=i, column=1) 



    dropdowns = {
        'B': '"197, 198, 197 S30, 198 S30, B36, B37, B38, B30, BC6, BC6 ANC, BC7, BC7 ANC, BC8, BC8 ANC, BC0, BC0, BH0 D30, BH0 D45, BH0 S30, BH8 S45, BH2 S30, BH6 D30, BH6 D45, BH6 S30, BH6 S45, BH7 D30, BH7 D45, BH7 S30, BH7 S45, BH8 D30, BH8 D45, BH8 S30, BH8 S45, BM6 S30, BM7 S30, BM8 S30, BM6, BM7, BM8, BM0, BP6, BP7, BP8, BP0, BR6, BR7, BR8, BR0, BS0, BS2, BS6, BS7, BS8, CS7, CS8, EDF, FC7 MAX, FC7 MIN, FC8 MAX, FC8 MIN, FC0 MAX, FC0 MIN, FC7 ANC MAX, FC7 ANC MIN, FC8 ANC MAX, FC8 ANC MIN, FC0 ANC MAX, FC0 ANC MIN, FH7, FH8, FL7, FL8, FL0, FR7, FR8, FS7, FS8, M27, M28, M20, M36, M37, M38, M47, M48, MC6 ANC MAX, MC6 ANC MIN, MC6 MAX, MC6 MIN, MC7, MC7 ANC MAX, MC7 ANC MIN, MC7 MAX, MC7 MIN, MC8, MC8 ANC MAX, MC8 ANC MIN, MC8 MAX, MC8 MIN, MC0 ANC MAX, MC0 ANC MIN, MC0 MAX, MC0 MIN, ME7 ANC MAX, ME7 ANC MIN, ME7 MAX, ME7 MIN, ME8 ANC MAX, ME8 ANC MIN, ME8 MAX, ME8 MIN, ME0 ANC MAX, ME0 ANC MIN, ME0 MAX, ME0 MIN, MF7, MF8, MH6 D30, MH6 D45, MH6 S30, MH6 S45, MH7 D30, MH7 D45, MH7 S30, MH7 S45, MH8 D30, MH8 D45, MH8 S30, MH8 S45, MI6, MI7, MI8, ML6, ML7, ML8, MM6, MM7, MM8, MR6, MR7, MR8, MS6, MS7, MS8, MT6, MT7, MT8, MX6, MX7, MX8, ORT, POT, POT MAX, POT MIN, XC6 ANC MAX, XC6 ANC MIN, XC6 MAX, XC6 MIN, XC7 ANC MAX, XC7 ANC MIN, XC7 MAX, XC7 MIN, XC8 ANC MAX, XC8 ANC MIN, XC8 MAX, XC8 MIN"',
        'F': '"Oui, AUT, BRU, CAS, CHO, DEL, EPA, FEN, INS, PER, PIV, POU, ROU, TET"',
        'G':'"Oui, Non"',
        'H':'"Oui, Non"',
        'I':'"Oui, Non"',
        'J':'"Oui, Non"',
        'K':'"Oui, Non"',
        'L':'"Oui, Non"',
        'M':'"Oui, Non"',
        'N':'"Oui, Non"',
        'O': '"TER, BMP, SOC, ROC"',
        'P': '"Non, BGC, BGP, BNC, BNP, HAC, HAP, HBC, HBP"',
        'Q': '"Non, TRM, TDL, TCR, SPC, SPB, PCH, PCG, PCP"',
        'R': '"Non, INV, IN1, IN2, IN3, IN4, IN5, IN6, IN7, IN8, IN9"',
        'S': '"5/9, 5/10, 97-8-6, 97-14-6, 98-4-8, 98-8-4, 98-8-6, 98-14-4, 98-14-6, 98-28-4, 98-28-6, 98-56-4, 98-56-6, 98-112-4, 98-112-6, 98-224-4, 99-14-8, 99-28-8, 99-56-8, 99-8-8, A2, A3, B4, C6, Liaison, L1047-1-A, L1047-1-P, L1047-2-A, L1047-2-P, L1048-A, L1048-P, L1092-1-A, L1092-1-P, L1092-2-A, L1092-2-P, L1092-3-A, L1092-3-P, L1092-11-A, L1092-11-P, L1092-12-A, L1092-12-P, L1092-13-A, L1092-13-P, L1092-14-A, L1092-14-P, L1092-15-A, L1092-15-P, L1083-A, L1083-P, A-H0073A-1F-50, A-H0118B-1FO-50, A-H0151B-2FO-50, A-H0338A-6F-60, A-H0340A-12F-60, A-H0341A-12F-60, A-H0342A-24F-60, A-H0343A-36F-60, A-H0344A-48F-60, A-H0345A-72F-60, A-H0346A-96F-60, A-H0347A-144F-60, A-H0348A-24F-60, A-H0349A-36F-60, A-H0350A-48F-60, A-H0351A-72F-60, A-H0352A-96F-60, A-H0353A-144F-60, A-H0354A-288F-60, A-N7836A-1F-70, A-N7837A-2F-70, A-N7838A-4F-70, A-N7839A-6F-70, A-N7840A-8F-70, A-N7841A-12F-70, A-N8227A-24F-70, A-N8228A-36F-70, A-N8700A-1F-80, A-N8800A-2F-80, A-N8819C-144F-60, A-N8867D-24F-70, A-N8868C-36F-70, A-N9076A-12F-70, A-N9270A-72F-70, A-N9271A-96F-70, A-N9272A-144F-70, A-N9273A-48F-70, A-N9297C-24F-60, A-N9298C-96F-70, A-N9385A-48F-70, A-N9386A-72F-70, A-N9387A-96F-70, A-N9388A-144F-70, A-N9485A-16F-70, A-N9665B-72F-110, A-N9850A-2F-50, A-N9873A-288F-70, A-N9923A-12F-70, A-N9926A-48F-70, A-N9996A-144F-70, A-UNB1625-4F-50, A-Z1295A-288F-80, C-12T12-144F-60, C-1T12-12F-60, C-2T12-24F-60, C-3T12-36F-60, C-4T12-48F-60, C-6T12-72F-60, C-8T12-96F-60, L1047-1-A, L1047-1-P, L1047-1-S, L1047-2-A',
        'V': '"haute, standard, basse"',
        'Z': '"Oui, Non"',
        'AA': '"Oui, Non"',
        'AE': '"197, 198, 197 S30, 198 S30, B36, B37, B38, B30, BC6, BC6 ANC, BC7, BC7 ANC, BC8, BC8 ANC, BC0, BC0, BH0 D30, BH0 D45, BH0 S30, BH8 S45, BH2 S30, BH6 D30, BH6 D45, BH6 S30, BH6 S45, BH7 D30, BH7 D45, BH7 S30, BH7 S45, BH8 D30, BH8 D45, BH8 S30, BH8 S45, BM6 S30, BM7 S30, BM8 S30, BM6, BM7, BM8, BM0, BP6, BP7, BP8, BP0, BR6, BR7, BR8, BR0, BS0, BS2, BS6, BS7, BS8, CS7, CS8, EDF, FC7 MAX, FC7 MIN, FC8 MAX, FC8 MIN, FC0 MAX, FC0 MIN, FC7 ANC MAX, FC7 ANC MIN, FC8 ANC MAX, FC8 ANC MIN, FC0 ANC MAX, FC0 ANC MIN, FH7, FH8, FL7, FL8, FL0, FR7, FR8, FS7, FS8, M27, M28, M20, M36, M37, M38, M47, M48, MC6 ANC MAX, MC6 ANC MIN, MC6 MAX, MC6 MIN, MC7, MC7 ANC MAX, MC7 ANC MIN, MC7 MAX, MC7 MIN, MC8, MC8 ANC MAX, MC8 ANC MIN, MC8 MAX, MC8 MIN, MC0 ANC MAX, MC0 ANC MIN, MC0 MAX, MC0 MIN, ME7 ANC MAX, ME7 ANC MIN, ME7 MAX, ME7 MIN, ME8 ANC MAX, ME8 ANC MIN, ME8 MAX, ME8 MIN, ME0 ANC MAX, ME0 ANC MIN, ME0 MAX, ME0 MIN, MF7, MF8, MH6 D30, MH6 D45, MH6 S30, MH6 S45, MH7 D30, MH7 D45, MH7 S30, MH7 S45, MH8 D30, MH8 D45, MH8 S30, MH8 S45, MI6, MI7, MI8, ML6, ML7, ML8, MM6, MM7, MM8, MR6, MR7, MR8, MS6, MS7, MS8, MT6, MT7, MT8, MX6, MX7, MX8, ORT, POT, POT MAX, POT MIN, XC6 ANC MAX, XC6 ANC MIN, XC6 MAX, XC6 MIN, XC7 ANC MAX, XC7 ANC MIN, XC7 MAX, XC7 MIN, XC8 ANC MAX, XC8 ANC MIN, XC8 MAX, XC8 MIN"',
        'AF': '"Remplacement, Renforcement, Recalage"',
        'AG': '""Ville, commune, Réseau à déployer en calcul de charge, Hypothèses climatique pour le calcul de charge, Appuis concernés par l\'étude, N° appui""',
        'AI': '"Oui, Non"',
        'AJ': '"Non, PB, PEO"',
        'AK': '"0, 1, 2, >2"',
        'AL': '"Non, Existante, Création"',
        'AN': '"Oui, Non"',

    }

    for col, values in dropdowns.items():
        dv = DataValidation(type="list", formula1=values, allow_blank=True)
        ws.add_data_validation(dv)
        form = col+str(row)+":"+col +str(ws.max_row + 1)
        print(form)
        dv.showInputMessage = True
        dv.showErrorMessage = True
        dv.add(form)
        ws.add_data_validation(dv)
        
 
    green_fill = PatternFill(start_color='00FF00', end_color='00FF00', fill_type='solid')
    red_fill = PatternFill(start_color='FF0000', end_color='FF0000', fill_type='solid')


   
    for col in 'FGHIJKLMN':
        if ws.max_row >= 9:
            col_range = f'{col}9:{col}{ws.max_row}'
            ws.conditional_formatting.add(
                col_range,
                CellIsRule(operator='equal', formula=['"Oui"'], stopIfTrue=True, fill=green_fill)
            )
            ws.conditional_formatting.add(
                col_range,
                CellIsRule(operator='equal', formula=['"Non"'], stopIfTrue=True, fill=red_fill)
            )
    
    wb.save(novo_arquivo_path)

在这段代码中,我希望看到数据验证,例如下拉列表或输入限制应用于单元格,但这些验证都没有生效——只有颜色填充起作用。

有人可以帮我确定这里可能出了什么问题吗?关于如何使用 openpyxl 正确应用不同类型的数据验证有什么建议吗?

python python-3.x openpyxl
1个回答
0
投票

DV 可能有两个问题;

  1. 据我所知,列表有一个限制(我认为是 256 个字符),因此大于此的“值”将会损坏。这包括字典中的第一列“B”以及至少“S”和“AE”
  2. 我看到您正在尝试正确引用值,但您的方法不起作用。

您可能想尝试以下方法;
我提取了一些值在限制范围内的字典元素,并将其更改为用单引号引起来。

formula1=
的实现已更改为
DataValidation

由于您的代码示例中没有
row
的定义,因此我将其设置为 1。

dropdowns = {
             'F': 'Oui, AUT, BRU, CAS, CHO, DEL, EPA, FEN, INS, PER, PIV, POU, ROU, TET',
             'G': 'Oui, Non',
}

for col, values in dropdowns.items():
    row = 1
    print(values)
    # dv = DataValidation(type="list", formula1=values, allow_blank=True)
    dv = DataValidation(type="list", formula1=f'"{values}"', allow_blank=True)
    ws.add_data_validation(dv)
    form = col + str(row) + ":" + col + str(ws.max_row + 1)
    print(form)
    dv.showInputMessage = True
    dv.showErrorMessage = True
    dv.add(form)
    ws.add_data_validation(dv)

这将生成一个工作簿,该工作簿将在“F”列和“G”列中以 DV 打开,直至最大行。

© www.soinside.com 2019 - 2024. All rights reserved.