A file which has data I need to access is being generated in xlsx format yet I need it to be in xls format for my purpose.
I'm able to use win32com.client to open the file however the save cannot fully complete due to Compatibility Checker dialog pop up which notifies you of loss of formatting/features by going from a xlsx --> xls format.
Here's the code which currently doesn't allow me to save the file as execution hangs waiting for the dialog to close, any help would be much appreciated:
excel = win32com.client.Dispatch('Excel.Application')
excel.DisplayAlerts = False
in_file = u"C:\\Path\\to\\infile\\infile.xlsx"
out_file = u"C:\\Path\\to\\outfile\\outfile.xls"
wb = excel.Workbooks.Open(in_file)
wb.CheckCompatibility = False
wb.DoNotPromptForConvert = True
wb.SaveAs(out_file, FileFormat=56) #Execution hangs here
wb.Close()
excel.Quit()
I've seen other similar posts which mention the methods and attributes I've already set in this script. I've also modified my the registry value to ShowCompatDialog = 0.
MSDN says on Workbook.DoNotPromptForConvert property:
"true to prompt the user to convert the workbook; otherwise, false".
Write in your code:
wb.DoNotPromptForConvert = False
UPDATE: Solved this issue using this Excel Add-In
For reference: Changing the registry value was working however the values were being reset daily on the internal network which I develop in. Without being able to edit the registry values myself b/c I don't possess the admin rights to do so, the above solution was the only thing that ended up solving my problem.
Related
In Excel, a workbook knows whether it already was given a filename or not. This changes Excel behavior when one clics on the save button. If the wb has no name, the save button redirects to the "save as" action. I wonder if openpyxl has a similar mechanism. This would help me in a function such as:
def smartSaveXLbook(wb, defaultName='MyBook.xlsx'):
if wb.properties.title: # this does not work. No wb passes this test :-(
print("wb has a name :", wb.properties.title) # wb.properties.title always empty
wb.save() # wants to save with the current existing name
else:
wb.save(defaultName) # Simplified version here. I will grant name uniqueness.
No, and for good reason: once openpyxl has read the file, it releases it and any other application can do what they want with it. But you can easily write a wrapper function that would store the name used to open the workbook. You could then use parameters to work with this: overwrite or always new?
I want to open an xlsm file via xlwings and then edit it and save it. However, some problems arose.
If I run the code with no excel file working, or just open another excel file and do not edit the excel file, it works fine. However, if I open an Excel file and do some work, for example open a blank Excel file and enter 'test' in cell A1, and run the code, sometimes it works, but sometimes it becomes unresponsive in the third line.(wb_xl = xw.Book(copy)) In this case, the code does not jump from the third line in an unresponsive state. What makes more sense is that the code works fine in some cases.
I want to know when the code works fine in all cases.
And there is one more problem.
If this code is executed while working with another Excel, only wb_xl should be terminated. I don't want another Excel to be closed. I want to exit only wb_xl. However, when the app.quit() code is executed, all open Excels are closed. In this case, how can I close only the Excel(wb_xl) opened through the code without closing the working Excel?
import xlwings as xw
copy = 'C:/Users/ijung/Desktop/210919_Mk_Lot_test/210922_101test.xlsm'
wb_xl = xw.Book(copy) #sometimes no response in this line
ws_xl = wb_xl.sheets['Main']
app = xw.apps.active
ws_xl.range('A1').value = 'test'
wb_xl.save()
app.quit()
#wb_xl.app.kill()
#wb_xl.close()
I also used openpyxl. However, in this part of wb_open.save(copy), an error such as xml.etree.ElementTree.ParseError: mismatched tag: line 20, column 8 occurred. When I use xlsx, the save works fine, but when I use xlsm, an error occurs.
import openpyxl
wb_open = openpyxl.load_workbook(copy, read_only = False, keep_vba = True)
ws_open = wb_open.active
ws_open.cell(1,1).value = 'test'
wb_open.save(copy) #error
wb_open.close()
As a result, the purpose of this code is to open the xlsm file by executing this code even when working with another Excel, edit and save, and close only this xlsm file.However, using multiple packages and searching multiple sites could not solve the problem.I'm under a lot of stress with this issue. Any help would be greatly appreciated. Please help me.
Thanks in advance.
openpyxl does not works with xlsm files that contains form objects
I think the problem is in app.quit() you are closing the excel instance, just use wb_xl.close()
import xlwings as xw
copy = 'C:/Users/ijung/Desktop/210919_Mk_Lot_test/210922_101test.xlsm'
wb_xl = xw.Book(copy) #sometimes no response in this line
ws_xl = wb_xl.sheets['Main']
#app = xw.apps.active # don't needed
ws_xl.range('A1').value = 'test'
wb_xl.save()
wb_xl.close()
This should only close the book, take a look this post has insteresting answers
I have a python script that every morning opens an excel file, refreshes it and saves as new file with todays date. Even though no changes occur between the .SaveAs and .Close and despite all precausions taken to not display save prompt, excel of course display a dialog prompting me to save or not before close. And to make this a bit more interesting, this doesn't happen every time, sometimes it can run for weeks without it happening, and then one day it just doesn't work.
Code sample:
import os
import datetime
import win32com.client as win32
from pywinauto.application import Application
# set todays date
dt = datetime.date.today()
# connect to Excel instance
xl = win32.dynamic.Dispatch("Excel.Application")
# open the excel template
wb = xl.Workbooks.Open([path to excel file])
# set report name
report_name = "Pending Report - INTERNAL - " + str(dt) + ".xlsx"
# refresh data
wb.RefreshAll()
# save as new file with todays date
wb.SaveAs(os.path.normpath(path + report_name))
# set excel not to display alerts - to not prompt for save before close
xl.DisplayAlerts = False
# disable Events - to not prompt for save before close
xl.EnableEvents = False
# set state of workbook to Saved to make sure excel sees the file as saved
xl.Workbooks(report_name).Saved = True
# close file and save changes set to true, ie. save the changes upon close
xl.Workbooks(report_name).Close(SaveChanges=1)
# looks for the save prompt - but the code never gets here, it halts on previous line waiting for input on dialog window
try:
app = Application(backend="uia").connect(title_re=".*Workbook Before Close*")
txt = app[u"Dialog"][u"Static"].window_text()
if "Do you want to save the changes you made" in txt:
app[u"Dialog"].YesButton.click()
except:
log("l", "i", "Didn't find excel or dialog window, might not be an issue but the Save dialog check wasn't successful")
Anyone have any ideas, or know what I'm doing wrong here?
Just to be fully clear, I've tested different combinations of these xl.DisableEvents etc. also tried them separately, some seem to work for a while then one day suddenly it doesn't anymore. Since this is an automated scheduled task, when it halts, it just sits there until I get an angry email asking for the report.
Now I know a workaround would be to create another scheduled task that runs another py file, that checks for the dialog, but that's not the issue here, what I want to get working is excel to do as instructed - i.e. not displaying the save before close prompt.
Thanks everyone.
Try the following:
xl = win32.gencache.EnsureDispatch('Excel.Application')
I am using a Excel template which have 6 tabs (All unprotected) and writing the data on each worksheet using openpyxl module.
Once the excel file is created and when tried to open the generated file, its not showing all data untill and unless I click "Enable editing" pop up.
Is there any attribute to disable in openpyxl.
This sounds like Windows has quarantined files received over a network. As this is done when the files are received, there is no way to avoid this when creating the files.
I solved this for me.
I found the answer here:
https://codereview.stackexchange.com/questions/240136/python-script-for-refreshing-and-preprocessing-data-in-excel-report-files
I only used the refresh function and it basically opened the excel file, click/refreshed, and closed/saved. You see an Excel file appear briefly on the screen. I'll insert this in a loop to go through all the files I am creating. It might take a little while to run hundreds, but much faster than open-click-save.
Here is all the code I used:
import win32com.client as win32
def refresh(directory, file_name):
xlapp = win32.DispatchEx('Excel.Application')
xlapp.DisplayAlerts = False
xlapp.Visible = True
xlbook = xlapp.Workbooks.Open(directory + '\\' + file_name)
xlbook.RefreshAll()
xlbook.Save()
xlbook.Close()
xlapp.Quit()
return()
I am running a program using python with would open a macro enabled excel file that uses COM objects to capture the real time data from an application. I frequently end up in an Excel crash error (occurs when i run the job more than two or three times). I went through web and found that this might be due to add ins that are installed to my excel file, I followed the instructions to remove the add ins from excel but still have the problem. I am using win32com to open the excel file and here is the code that I am using. I am new to python, please share your comments to improve this code and fix this issue.
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(excel, r'C:\\pynow_futu.xlsm')
win32api.Sleep(5000)
ws = wb.Worksheets('fut')
excel.Visible = True
excel.DisplayAlerts = False
for wb in excel.Workbooks:
ws = wb.Worksheets('fut')
if wb.Name == 'pynow_futu.xlsm':
print("WB:", str(wb.Name))
wb.DoNotPromptForConvert = True
wb.CheckCompatibility = False
filename = "C:\\futu.csv"
win32api.Sleep(2000)
wb.SaveAs(filename,FileFormat=24, ConflictResolution=2)
win32api.Sleep(1000)
wb.Close(True)
The excel file got crashed because few child process from the previous run was still active and it stops from opening the new file thus it crash. Fixed it by killing the child process