Привет всем! Сегодня, наконец-то я доделал давно запланированную задачу по сравнению прайсов (историю возникновения этой задачи я описывал ранее, там же представлен предварительный код программы). Кому интересно — читаем дальше 🙂
Основная проблема, с которой я столкнулся (впрочем, и решить так и не смог) — это ветка, срабатывающая, если позиции в двух прайсах (нашем и конкурента) равны по стоимости. В этот момент в итоговый 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.
Спасибо за внимание! В случае возникновения вопросов или комментариев - пишите на почту или в он-лайн чат (в правом нижнем углу 🙂 )
Support the Blog!
Running a blog takes a lot of effort, time, and passion. Your donations help improve the content, inspire new ideas, and keep the project going.
If you’ve enjoyed the blog’s materials, any support would mean the world to me. Thank you for being here! ❤️