Copy a macro in an Excel file in "ThisWorkbook" from MATLAB - vba

I wrote a macro in a text file (Macro.txt) and I have an Excel file (Result.xlsm). I need to copy the macro in Excel file in "ThisWorkbook" from MATLAB (picture below). I tried the following code, using the import function. But it write the macro as a module. I am wondering if there is any way to write the macro in "ThisWorkbook"?
[
ResultFileName = [pwd() filesep 'Result.xlsm'];
MacroFileName = [pwd() filesep 'Macro.txt'];
% Import the excel file
Excel= actxserver('Excel.Application');
wb=Excel.Workbooks.Open(ResultFileName);
Excel.visible = 1;
% Add the macro to the excel file
import(wb.VBProject.VBComponents,MacroFileName);
% Save
Excel.Application.DisplayAlerts = 0; %Avoid overwrite warning
SaveAs(wb,ResultFileName);
Excel.Application.DisplayAlerts = 1;
% Close Excel
Quit(Excel);
delete(Excel);

Related

Reading an .xltx file and Writing to .xlsx file with openpyxl

I've been struggling with this problem for a while and couldn't find a solution else where. I have several excel templates in xltx format that I want to read, then write a new xlsx file after filling in some cells.
Every time I run my code it creates a corrupted excel file. Using a preview extension in VS code I'm able to see that the values were correctly changed. When I read an xlsx file instead of an xltx it works fine. Does openpyxl just not allow what I am trying to do?
import openpyxl
import win32com.client
report = openpyxl.load_workbook("0100048-A5_R_11.xltx")
sheet = report["A5 form"]
search_arr = ["Test_Date"]
for r in range(2, sheet.max_row+1):
for c in range(3,sheet.max_column+1):
val = sheet.cell(r,c).value
if val != None and "$!" in str(val):
sheet.cell(r,c).value = 1
report.active = 1
report.save("output.xlsx")
Copied from the docs:
You can specify the attribute template=True, to save a workbook as a template:
wb = load_workbook('document.xlsx')
wb.template = True
wb.save('document_template.xltx')
or set this attribute to False (default), to save as a document:
wb = load_workbook('document_template.xltx')
wb.template = False
wb.save('document.xlsx', as_template=False)
Although the last line is from the latest docs, as_template is not a keyword argument for save!
This works instead:
wb.save('document.xlsx')

Add dataframe and button to same sheet with XlsxWriter

I am able to create an excel file with in one sheet the data from a data frame and in a second sheet a button to run a macro
What I need is to have both the data from the dataframe than the button in the same sheet
This is the code I found that I have tried to modify:
import pandas as pd
import xlsxwriter
df = pd.DataFrame({'Data': [10, 20, 30, 40]})
writer = pd.ExcelWriter('hellot.xlsx', engine='xlsxwriter')
worksheet = workbook.add_worksheet()
#df.to_excel(writer, sheet_name='Sheet1')
workbook = writer.book
workbook.filename = 'test.xlsm'
worksheet = workbook.add_worksheet()
workbook.add_vba_project('./vbaProject.bin')
worksheet.write('A3', 'Press the button to say hello.')
#Add a button tied to a macro in the VBA project.
worksheet.insert_button('A1', {'macro': 'start',
'caption': 'Press Me',
'width': 80,
'height': 30})
df.to_excel(writer, sheet_name ='Sheet2')
writer.save()
workbook.close()
I know that you simply asked how to insert the button in the same sheet but i decided to check how the macros are working with xlsxwriter, so i wrote a complete tutorial on how to add a macro.
1) Firstly we need to create manually a file which will contain the macro in order to extract it as a bin file and inject it later using xlsxwriter. So we create a new excel file, go to Developer tab, Visual Basic, Insert Module and write the following code:
Sub TestMsgBox()
MsgBox "Hello World!"
End Sub
Save the file with xlsm extension to contain the macro, e.g. as Book1.xlsm.
2) Now we need to extract the bin file. Open your cmd and browse to the directory where you have saved the Book1.xlsm. Then browse through file explorer to the folder where you have installed python (or to the virtual environment folder) and search for vba_extract.py. Copy this script into the same folder as the Book1.xlsm. Then type in cmd:
python vba_extract.py Book1.xlsm
This way you will extract the macro and create the vbaProject.bin file in the same folder.
3) Now it's time to create the final file. Delete the Book1.xlsm and the vba_extract.py files as they 're not needed anymore and run the following code:
import pandas as pd
# Create a test dataframe
df = pd.DataFrame({'Data': [10, 20, 30, 40]})
# Import it through the xlsxwriter
writer = pd.ExcelWriter('hello_world.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1', index=False)
# Create the workbook and the worksheet
workbook = writer.book
workbook.filename = 'hello_world.xlsm' # rename the workbook to xlsm extension
worksheet = writer.sheets['Sheet1']
# Inject the bin file we extracted earlier
workbook.add_vba_project('./vbaProject.bin')
# Insert a description
worksheet.write('B1', 'Press the button to say hello.')
#Add a button tied to a macro in the VBA project.
worksheet.insert_button('B2', {'macro': 'TestMsgBox',
'caption': 'Press Me',
'width': 80, 'height': 30})
# Finally write the file
writer.save()
Now button is in the same sheet as your data and working:

TMS FlexCel - Open a xlsx generated by EPPlus

I have created a simple workbook with EPPlus in C# .NET Core (The file is XLSX).
I need to export this workbook to PDF.
I am trying to export using TMS FlexCel for .NET.
But, when the code try to export I get the error below:
FlexCel.Core.FlexCelCoreException: 'Invalid Cell: "#REF!"'
If I save the same workbook as XLS, the code works perfectlly.
Below is my code:
string file = #"D:\Test.xlsx";
string pdfFile = Path.ChangeExtension(file, ".pdf");
Excel.SaveAs(new FileInfo(file));
XlsFile xls = new XlsFile(false);
xls.Open(file);
FlexCelPdfExport pdf = new FlexCelPdfExport(xls, true);
pdf.Export(pdfFile);
Thanks
I found the problem.
The file generated by EPPlus is OpenXml format and the FlexCel doesn't recognize the format.

Using win32com/python to recalculate excel sheet that uses an add-in

Description of problem: I have been manually using a spreadsheet that works with an excel add-in. I am trying to automate it with win32com & python. I can input a value into an input cell, but the sheet does not recalculate. When I try to read the output cell, I get an error as described below. Also, after running the below code, when I open up the sheet manually, I see that the calculated cells all say #VALUE!. Manually, I can press CTRL+ALT+F9, and the sheet recalculates, leaving no #VALUE! cells. Note, when I say "calculated cells", these cells rely on functions that are part of a VBA macro/the add-in.
Main question: How can I force a recalculation of the sheet from python?
Code:
import win32com.client
import win32api
def open_util():
excel = win32com.client.Dispatch("Excel.Application")
wb1 = excel.Workbooks.Open(r'C:\...the add-in.xla')
wb = excel.Workbooks.Open(r'C:\...the file name.xlsm')
ws = wb.Worksheets('the sheet name')
# get the values from two cells.
myInput = ws.Cells(1,1).Value # this is an input cell, not calculated
myOutput = ws.Cells(1,2).Value # this cell is calculated
print("The original value of myOutput is : ", myOutput)
# put a new value into the input cell.
newInput = 42
ws.Cells(1,1).Value = newInput
# Now I want the sheet to recalculate and give me a new output.
# (when manually operating this spreadsheet, I just input a new value,
# and the whole sheet automatically recalculates)
# Note: these two lines of code appear not to have any effect.
ws.EnableCalculation = True
ws.Calculate()
# get the new output
newOutput = ws.Cells(1,2).Value
wb.Close(True)
print("newOutput is : ", newOutput)
return True # I haven't finished writing the function... no return value yet.
Output:
The original value of myOutput is : 10 # this is fine.
newOutput is : -2146826273 # when I open the spreadsheet, this cell now says #VALUE!
About the add-in: I'm using this chemistry-related software which is basically a complicated spreadsheet and an execel add-in. The output cells in my code that say "#VALUE!": they use named formulas, which are in a macro that I can't look at (I suppose to not give away the code of the chemistry-related software).
Similar question: I found this similar question. In my case, I'm not sure the add-in is involved in calculating the cells. Anyway, I tried adding the code suggested in the answer:
def open_util():
excel = win32com.client.Dispatch("Excel.Application")
excel.AddIns.Add("rC:\...\add-in.xla").Installed = True # <-- This is the line I added.
...
However, this only generated an error message:
Traceback (most recent call last):
File "C:\...\my_program_name.py", line 246, in <module>
open_util()
File "C:\...\my_program_name.py", line 216, in open_util
excel.AddIns.Add("C:\...\add-in.xla").Installed = True
File "C:\Users\00168070\AppData\Local\Programs\Python\Python36-32\lib\site-packages\win32com\gen_py\00020813-0000-0000-C000-000000000046x0x1x9\AddIns.py", line 35, in Add
, CopyFile)
pywintypes.com_error: (-2147352567, '例外が発生しました。', (0, 'Microsoft Excel', 'Add method of AddIns class failed', 'xlmain11.chm', 0, -2146827284), None)
(Note: the bit of Japanese means, I think, 'An exception occurred'.)
Side question: Is there documentation about what python/win32com functions are available for excel, and how to write a program with them? (for example, I never would have known that I needed the line of code "ws.EnableCalculation = True" until I saw it in a fragemet of someone else' code.) I've found only bits of tutorials.
A little late, but I ran into a similar issue. I am also using a third-party add-in. I believe this was causing the issue.
Test case to see if
ws.EnableCalculation = True
ws.Calculate()
is working
import time
import win32com.client
xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible = True # so we can see what is happening
wb = xlApp.Workbooks.Open(excel_wb) # make excel wb a saved file where A1 = A2 + A3
ws = wb.ActiveSheet
for x in range(9):
ws.EnableCalculation = False
ws.Range('A2').Value = x
ws.Range('A3').Value = 2 * x
print(ws.Range('A1').Value) # value in A1 should remain the same
time.sleep(10)
ws.EnableCalculation = True
ws.Calculate()
# value in A1 should update
print(ws.Range('A1').Value) # value in A1 should be updated
This works just fine for me. Our expected output is 0, 3, 3, 6, 6, 9, etc. as it remains the same before updating.
If this code works for you, the issue is likely the plugin. For my plugin, the issue was a "phantom" excel instance that would hang out after closing the excel workbook and interfere with the plug-in.
To fix this, 2a. use a finally statement that closes excel at the end of the program and 2b. explicitly add a command line excel kill at the beginning of the main function
2a.
def quit_xl(xlApp, xlWB=None, save=True):
if xlWB is not None:
xlWB.Close(save)
xlApp.Quit()
del xlApp
2b.
import subprocess # be careful - make sure that an outside user can't pass anything in
def kill_xl():
try:
kill_excel = """"“taskkill / f / im
excel.exe”""" # command prompt to kill all excel instances
subprocess.run(kill_excel, shell=True)
return 0
except Exception as e:
return 1
put together:
def main():
kill_xl()
xlApp = win32com.client.Dispatch("Excel.Application")
try:
pass # main part of function
except Exception as e:
pass # if something goes wrong
finally:
quit_xl(xlApp)

how to copy popup window text message and paste into Excel file using selenium

I want to copy popup window Text Message and paste that message into Excel file and then compare that data with Actual data. I am able to read the popup window text message and display on consol window, But how to paste that message into excel file
Selenium doesn't provide any functionality to deal with Excel documents, however assuming you're using Java you can read and write Excel files using Apache POI library
Workbook wb = new HSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("Sheet1");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue(createHelper.createRichTextString("Hello world"));
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
Hope it will help you.