Привет всем! Сегодня, наконец-то я доделал давно запланированную задачу по сравнению прайсов (историю возникновения этой задачи я описывал ранее, там же представлен предварительный код программы). Кому интересно — читаем дальше 🙂
Основная проблема, с которой я столкнулся (впрочем, и решить так и не смог) — это ветка, срабатывающая, если позиции в двух прайсах (нашем и конкурента) равны по стоимости. В этот момент в итоговый 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.
Спасибо за внимание! В случае возникновения вопросов или комментариев — пишите на почту или в он-лайн чат (в правом нижнем углу 🙂 )