I want to write a VBA macro in Excel to call a python script. The python script will execute some commands then return a pandas dataframe. I have code that writes to the excel spreadsheet and that is inside the python script.
I have installed xlwings and read through the VBA macro tutorial but am still confused. Should I use a User Defined Function? Do I need to "return anything" in the script?
If your Python script writes to the workbook directly, this is not difficult. First, you don't need to return anything from either the VBA macro or the Python if what you write to the workbook is sufficient for you.
You don't need a UDF. All you need is the following (which I've basically copied from the xlwings official docs here):
1) Make sure your excel book can talk to the file you have your script in (best done using the command xlwings quickstart <project_name> on the command line, then copying your script to the resulting Python file.
2) Make sure you can call everything you need from a single function like __main__() (or be prepared to run execfile or something similar)
3) Go to your excel book and make a command button, then assign it the macro SampleCall which xlwings has kindly provided for you
4) Now open the VBA editor. You should see the SampleCall macro immediately:
Sub SampleCall()
RunPython ("import testproj;testproj.world()")
End Sub
Just edit the names of testproj and world appropriately.
You can now click your CommandButton to execute your script!
Related
I am working with xlwings v0.25.0 and have the matching version for the Excel add-in. I am also using Office 365 and Python 3.7.4.
I am trying to run a Python script, testing_xlwings.py from a vba macro in Excel.
import xlwings as xw
def main():
sheet = xw.Book.caller().sheets[0]
sheet.range('B10').value = 'IT WORKED!!!'
I have assigned the macro to the button and when I click to run, I receive the following error Compile error: Sub or Function not defined.
My sub for the macro looks like this:
Sub Run_xlwings()
RunPython "import testing_xlwings.py; testing_xlwings.main()"
End Sub
If I change sheet = xw.Book.caller().sheets[0] to sheet = xw.Book('testing_workbook.xlsm').sheets[0] the script executes and the text is placed in the Excel file.
I have also downloaded the Monte Carlo example from the xlwings examples page. When I open the file and try to run the .py script using the macro, I receive this error: AttributeError: module 'xlwings.utlis' has no attribute 'prepare_sys_path'
What do I need to change to run the script from the macro?
I was able to get the macro to the call the Python script by pressing Alt + F11 to bring up the VBA editor. From the toolbar across the top, I selected Tools -> References and I ticked the checkbox for xlwings. After I clicked OK I was able to run the script.
if you still get error... try to install a previous version of xlwings.
On the console type:
pip install xlwings==0.27.2
xlwings addin install
I have written a code which opens an excel file via excel wings library and instruct such file to run a macro within the excel file itself. The macro within the file consists of a series of Refreshes which happen on another excel workbook through some excel add ins.
The issue is that when I open the excel file and run the VBA macro from there no issues arise. However, when I use Python to run the process I get a run time error 1004 in the VBA macro, which reads macro not available in the current workbook, despite the macro obviously being there. I believe this is because, for some reason, when Python launches Excel the add ins may not automatically load.
I have long looked for a solution around but nothing satisfactory yet. Any help is massively appreciated!
On my old computer, I was able to run .py files from Jupyter Notebook, edit them, and run them. The .py file was effectively a notebook file for all intents and purposes. I updated to the latest version of notebook, and I am no longer able to do this. How do I use .py files on my notebook?
I know there are roundabout ways to do this. I am looking for the method where, when you are in notebook, instead of opening a .ipynb file, you select a .py file which is opened, and behaves like a .ipnyb. When you save it, it writes to .py.
A text file can be loaded in a notebook cell with the magic command %load.
If you execute a cell containing:
%loadpy filename.py
The content of filename.py will be loaded in the next cell. You can edit and execute it as usual.
To save the cell content back into a file add the cell-magic
%%writefile filename.py at the beginning of the cell and run it.
To see the help for any magic command add a ?: like %loadpy? or %%writefile?.
%COMMAND-NAME?
i.e. %run?
For list of available magic function use %lsmagic.
Alternatively there is also another method magic function called %save-f but I would not recommend that, it's an indirect way of saving files.
Also see -
1. Magic Functions docs
2.this nbviewer for further explanation with examples. Hope this helps.
This is not the exact answer. At one point, I was able to open .py files using python notebook and work on it as if it were a notebook file.
However, I have been able to replicate this behavior using VScode.
https://code.visualstudio.com/docs/python/jupyter-support-py
Using VScode, you can export all your .ipynb files into .py files, then run code blocks. Code blocks are separated by # %%.
I have not used it sufficiently long enough to decide if it is better than python notebook, but this seems to be the best solution so far. I previously tried using Atom/Hydrogen and did not enjoy the experience.
You can save individual cells as files using the following code: %%writefile some_file_name.py.
You can run that code straight from the terming or from another notebook using the following code: %run some_file_name.py
Some editors (like spyder and vscode) have jupyter notebook functionality. These can be used if jupyter in installed in the python environment.
You can use it by add #%% on top of the block of code. (in vscode the button 'run cell' will automatically appear)
Also it is possible to import .ipynb as .py which can be run in to fancy decrypt above.
I just found this package p2j and tested it with a .py file with functions, comments and normal code.
I used it as indicated in this answer by doing the following:
pip install p2j
p2j -o script.py -t new_file.ipynb
You can also add -o flag to overwrite the original file.
With this, I got a working Jupiter Notebook with each block of code in a cell and the comments as markdown.
Example:
Original .py script
Converted .ipynb
I'm currently writing a Python script that opens excel, runs a macro, and then saves it. Because I was having trouble with Openpyxl and XLWings calling specific macros, I decided to just automatically have the macro run when opening up excel. However, is there a way to pass in parameters from the Python script for the automatically-running macro to take?
I have an excel file that I need to press ctrl+q to make a vba code(macro) to run.
is there a way to do this with python?
someting like:
with open (my_file,"wb")
"press ctrl+q"
close file
Thanks!
the open command is for opening a file and manipulating it's raw content - not suitable for your need
the are are modules for reading and writing excel files like openpyxl, but they don't include running vba macros. if the macro functionality can be implemented in python, this will probably be a good start.
If you need to run macros, you need to interact with an instance of excel using com automation (so you need to have it locally installed) - the pywinauto module can be a good start
I built a macro that starts when I open the file and add it to a template.
I created my new files with the template (using panda) and when I open them- the macro runs alone,
Thanks All!