Как с помощью opepyxl получить значение из ячейки, в которой содержится формула?
Функция заполняет файл Excel значениями, которые используются в формулах на этом же листе. Затем другая функция пытается считать значения из ячеек с формулами. Используя аргумент data_only=True в функции load_workbook(), думал буду получать значения из ячеек с формулами, но выходит None. Если вместо заполнения ячеек использовать не функцию, а сделать это вручную, то тогда значения из ячеек с формулами считываются корректно.
Кто-нибудь может объяснить такое поведение?
from openpyxl import load_workbook
book = load_workbook('file.xlsx', data_only=True)
sheet = book['Сводная']
book.active = sheet
for_record = []
dict_with_total = {'Управление': 3, 'Офис': 4, 'Склад': 5}
columns_status = {'Карандаш': 'B', 'Ручка': 'C', 'Тетрадь': 'D'}
with (open('report.txt', mode='w', encoding='utf-8') as file):
for podrazd, row in dict_with_total.items():
for_record.append(podrazd + '\n')
str_temp = ''
for head, column in columns_status.items():
str_temp += head + ' ' + str(sheet[column + str(row)].value) + ', '
for_record.append(str_temp[:-2] + '.' + '\n')
file.write(''.join(for_record))
book.close()
sheet[column + str(row)].value вот здесь считывается None
Ответы (1 шт):
Как я понимаю, вы заполняете начения Excel файла скриптом. Тогда надо открыть этот файл в Excel, чтобы формулы пересчитались.
Когда вы открываете файл с data_only=True, openpyxl пытается прочитать последние вычисленные значения из ячеек.
Что можно с этим сделать (вдруг будет полезно кому-то):
- Делать все вычисления в скрипте и записывать в Excel файла значения, а не использовать формулы.
- Если на компьютере есть Excel, то можно в скрипте сделать перерасчёт формул в файле. Например так (сработает на Windows):
import win32com.client as win32
# Открываем Excel, загружаем файл и пересчитываем
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(r'C:\full\path\to\file.xlsx') # Полный путь!
wb.RefreshAll() # Обновляем все связи и формулы
excel.CalculateFull() # Принудительный пересчёт
wb.Save() # Сохраняем изменения
wb.Close()
excel.Quit()
Или так (и на Mac сработает):
import xlwings as xw
# Открываем файл и пересчитываем
with xw.App(visible=False) as app:
wb = xw.Book('file.xlsx')
wb.api.RefreshAll() # Обновить все данные
wb.api.CalculateFull() # Пересчитать всё
wb.save()
wb.close()