Задача по сравнению прайсов на Python — решено

Привет всем! Сегодня, наконец-то я доделал давно запланированную задачу по сравнению прайсов (историю возникновения этой задачи я описывал ранее, там же представлен предварительный код программы). Кому интересно — читаем дальше 🙂

Основная проблема, с которой я столкнулся (впрочем, и решить так и не смог) — это ветка, срабатывающая, если позиции в двух прайсах (нашем и конкурента) равны по стоимости. В этот момент в итоговый Excel-файл сливается заголовок «Стоимость товаров равна», и остается на всех проверяемых прайс-листах. Если есть какие-то мысли, где я напортачил — прошу поделиться.

В остальном — задача достаточно интересная (за счет немалого количества используемых переменных из обоих прайсов, среди которых можно выделить такие, как:

  • Наименование товара
  • Стоимость товара
  • Наименование ячейки
  • Логика работы кода тоже вполне прогнозируемая: берем наш прайс, берем прайс конкурента, и — учитывая, что согласно начальным условиям прайсы совершенно равны по структуре на всякий случай проверяем по количеству строк-столбцов, и если прайсы идентичны — начинаем сравнивать стоимость товаров. В случае же, если прайсы различаются по структуре — работы программы останавливается 🙂

    Итак, сам код + комментарии:

    import openpyxl #Подключаем библиотеку для работы с Excel
    from openpyxl.styles import colors #Грузим стили
    from openpyxl.styles import Font, Color, Fill #И еще стили
    from openpyxl import Workbook #И еще ...
    from openpyxl.styles import PatternFill #тут тоже стили ...
    from openpyxl.workbook import Workbook #и тут ... вообще их дофига, и нужно разобраться конкретно что и как - но это позднее :)
    import glob #Библиотека для работы с файлами
    import re #Библиотека для парсинга регулярными выражениями - пригодится чуть позднее
     
    #Создаем итоговый файл
    final_wb = openpyxl.Workbook() #Создаем файл, в который будут собираться все итоги работы программы
     
    print('Начинаем работу: \n')
     
    #Формируем список файлов для работы
    original_path = ' ' #Путь к прайсу с нашими ценами
    path = ' ' #Задали переменную с путем к рабочей папке
     
    list_files = glob.glob(path + '*.xlsx') #Сформировали переменную, содержащую список всех файлов Excel в рабочей папке
    print(glob.glob(path + '*.xlsx')) #Вывели список всех файлов с расширением Excel
    for file in list_files: #Создаем цикл, который обрабатывает каждый файл
        print('Обрабатываем файл: ', file) #Выводим уведомление о начале обработки файла
     
        #Создаем страницу с именем прайса конкурента
        regxp = '\d.xlsx' #Создаем регулярное выражение, которое пропарсит только эксель-файлы с цифровыми названиями
        result = re.findall(regxp, file) #Начинаем парсить
        result = str(result) #Результат парсинга переводим в строковую переменную
        print('Тип: ', type(result)) #Радуем пользователя, что нашли...
        print('Нашли: ', result) #и выводим, что именно нашли
        sheet_name = result.replace('[','').replace('\'','').replace(']','') #Убираем все лишнее из найденного
        print(sheet_name) #Выводим на экран итоговое название (прайс-листа конкурентов)
     
        work_sheet = final_wb.create_sheet(sheet_name) #Создаем лист в файле с названием прайс-листа конкурента
     
        #Получаем данные из нашего прайса (для сравнения)
        wb_orig = openpyxl.load_workbook(original_path) #Грузим наш прайс-лист
        sheets_list_original = wb_orig.sheetnames #Получаем список всех листов в файле
        sheet_active_original = wb_orig[sheets_list_original[0]] #Начинаем работать с самым первым
        row_count_original = sheet_active_original.max_row #Получаем количество столбцов
        column_count_original = sheet_active_original.max_column #Получаем количество строк
     
        #Начинаем получать данные из прайса конкурента
        wb = openpyxl.load_workbook(file) #Грузим прайс-лист конкурента
        sheets_list = wb.sheetnames #Получаем список листов в файле
        sheet_active = wb[sheets_list[0]] #Сделали активной самую первую страницу
        row_count = sheet_active.max_row #Получаем количество столбцов
        column_count = sheet_active.max_column #Получаем количество строк
     
        print('В нашем прайсе', original_path, '\n - строк: ', row_count_original, '\n - колонок: ', column_count_original)
        print('В документе', file, '\n - строк: ', row_count, '\n - колонок: ', column_count, '\n')
        if row_count != row_count_original or column_count != column_count_original: #Если количество строк или колонок не совпадает
            print('Прайсы не совпадают, проверьте данные! \n') #Выводим уведомление, и...
            break #Прекращаем работу программы
        else: #А если параметры совпадают - то ...
            print('Прайсы совпадают, работаем! \n') #Выводим уведомление и продолжаем работу
            max_row = 1 #Создаем переменную, в которой содержится начальное число - откуда начинаем обработку
            worksheet_a = 'A' #Колонка А
            worksheet_b = 'B' #Колонка B
            work_sheet_c = 'C' #Колонка С
            work_sheet_d = 'D' #Колонка D
     
            work_sheet['A1'] = 'Товарная позиция' #В итоговом файле пишем заголовок в ячейке А1
            work_sheet_a1 = work_sheet['A1'] #Создаем переменную, которая содержит эту ячейку
            work_sheet_a1.font = Font(bold=True) #Текст в этой ячейке делаем жирным
     
            work_sheet['B1'] = 'Цена у конкурента' #Аналогично с ячейкой А1 обрабатываем ячейки B
            work_sheet_b1 = work_sheet['B1']
            work_sheet_b1.font = Font(bold=True)
     
            work_sheet['C1'] = 'Цена у нас' #C
            work_sheet_c1 = work_sheet['C1']
            work_sheet_c1.font = Font(bold=True)
     
            work_sheet['D1'] = 'Вердикт' #D
            work_sheet_d1 = work_sheet['D1']
            work_sheet_d1.font = Font(bold=True)
     
            while max_row <= row_count: #Пока количество строк не будет равным количеству переменной, делаем...
                cell_a = worksheet_a + str(max_row) #создаем переменную, которая содержит номер текущей ячейки в столбце А
                cell_b = worksheet_b + str(max_row) #Создаем переменную, которая содержит номер текущей ячейки в столбце B
                cell_c = work_sheet_c + str(max_row) #Создаем переменную, которая содержит номер текущей ячейки в столбце C
                cell_d = work_sheet_d + str(max_row) #Создаем переменную, которая содержит номер текущей ячейки в столбце D
     
                from_cell_a = sheet_active[cell_a].value #Получаем значение ячейки A
                from_cell_b = sheet_active[cell_b].value #Получаем значение ячейки B
                from_cell_a_orig = sheet_active_original[cell_a].value #Получаем значение ячейки А из нашего прайса
                from_cell_b_orig = sheet_active_original[cell_b].value #Получаем значение ячейки В из нашего прайса
                if from_cell_b > from_cell_b_orig: #А теперь все просто... Если у конкурентов дороже:
                    print(from_cell_a, ': \n - у конкурентов: ', from_cell_b, '\n - у нас: ', from_cell_b_orig) #Выводим сообщение
                    print('У конкурентов позиция дороже!\n') #Что у них дороже
                    # Пишем в итоговый файл все
                    work_sheet[cell_a] = from_cell_a #В ячейку А - пишем название товара
                    work_sheet[cell_b] = from_cell_b #В ячейку В - пишем стоимость товара у конкурента
                    work_sheet[cell_c] = from_cell_b_orig #В ячейку С - пишем стоимость товара у нас
                    work_sheet[cell_d] = 'Позиция у конкурентов дороже!' #В ячейку D пишем, что у конкурента дороже
                    work_sheet_cell_fill = work_sheet[cell_d] #Загоняем в переменную ячейку D
                    work_sheet_cell_fill.fill = PatternFill(fill_type='solid', start_color='20FF19', end_color='20FF19') #Эту ячейку делаем цветной для выделения
                elif from_cell_b < from_cell_b_orig: #Если вдруг товар дешевле у конкурента
                    print(from_cell_a, ': \n - у конкурентов: ', from_cell_b, '\n - у нас: ', from_cell_b_orig) #Делаем все, аналогично ветке, где товар дороже
                    print('У конкурентов позиция дешевле\n') #
                    # Пишем в итоговый файл все
                    work_sheet[cell_a] = from_cell_a #
                    work_sheet[cell_b] = from_cell_b #
                    work_sheet[cell_c] = from_cell_b_orig #
                    work_sheet[cell_d] = 'Позиция у конкурентов дешевле!' #
                    work_sheet_cell_fill = work_sheet[cell_d] #
                    work_sheet_cell_fill.fill = PatternFill(fill_type='solid', start_color='ff8327', end_color='ff8327') #
                elif from_cell_b == from_cell_b_orig: #Ветка, отвечающая за равную стоимость... И тут проблема :( 
                    print(from_cell_a, ': \n - у конкурентов: ', from_cell_b, '\n - у нас: ', from_cell_b_orig) #
                    print('Стоимость товара равная\n') #
                    #Пишем в итоговый файл все
                    work_sheet[cell_a] = from_cell_a #
                    work_sheet[cell_b] = from_cell_b #
                    work_sheet[cell_c] = from_cell_b_orig 
                    work_sheet[cell_d] = 'Стоимость товаров равна' #Как только программа отрабатывает эту ветку - уведомление о равной стоимости товара будет на всех последующих листах. Если же закоментить эту строку и следующие три - все будет отлично, но без выделения :( 
                    work_sheet_cell_fill_d = work_sheet[cell_d] #
                    work_sheet_cell_fill_d.fill = PatternFill(fill_type='solid', start_color='FFDD2D', end_color='FFDD2D') #
                max_row = max_row + 1 #Увеличиваем значение переменной на единицу, что бы цикл сработал
     
    final_wb.save('all_data.xlsx') #Результат всей работы пишем в файл

    Полный код программы доступен по ссылке на моем Git.

    Спасибо за внимание! В случае возникновения вопросов или комментариев — пишите на почту или в он-лайн чат (в правом нижнем углу 🙂 )