How do I send VBA output to a Python script? - python

Here is a code snippet:
' Send the query in the body to Jira, and get the response from Jira
strJsonResponse = Utilities.JiraRequest(strJQLQuery)
I'd like to put this json into a Python parser and then return the parsed json back into the spreadsheet. Is this possible? I've never worked with VBA before.
I have downloaded the JIRA API module and the openpyxl module.

You might be able to create a new text file and output VBA to that
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim Fileout As Object
Set Fileout = fso.CreateTextFile("C:\your_path\vba.txt", True, True)
Fileout.Write strJsonResponse
Fileout.Close
VBA code found here
then have VBA start up your python script where you can have python parse your file. There is probably a better way to do this but I'm not sure what.

I think that Tehscript raised a valid question. Are you certain that there's a need to use VBA code in addition to your Python code? By running Python code that makes use of the openpyxl module you can read out and modify basically everything that's in an Excel file, completely without the need to run an Excel application.
Sometimes there are valid reasons for coupling VBA and Python code. The most common one is when you want to use Excel as a familiar graphical user interface to direct data manipulation operations, but want Python to do the actual heavy-lifting. If you're looking to do this, then there's the xlwings module. Xlwings makes it easy to call Python code from inside VBA modules, and to exchange data values between VBA and Python.

Related

How to customize the action of a button in excel sheet using xlsxwriter

I am wondering to use xlsxwriter to control my excel sheet instead of using old fashioned way by using VBA. I need a button to trigger some actions. What I read from the official documentation is
workbook.add_vba_project('./vbaProject.bin')
worksheet.insert_button('B3', {'macro': 'say_hello',
'caption': 'Press Me'})
I don't know how to define my own function as a macro and I don't know how to generate "vbaProject.bin". Is there anyway to write a macro in format like python function and directly assign it to the button?
If I must include the macro in vbaProject.bin, how can I do that? Hope it is not something like vba.
So you have many ways to control and automate your files:
You can use vba
You can use xlsxwriter which uses python syntax
You can use a library called PyXLL https://www.pyxll.com/docs/userguide/macros.html . It seems you are able to write a macro using python syntax but i haven't tried it, you could have a look as it might be what you are looking for.
About your question on how to inject a macro to your excel using xlsxwriter have a look at my answer here, i think it is quite detailed:
Add dataframe and button to same sheet with XlsxWriter
By the way vba is not hard to learn and there is a lot of information online. If you don;t want to write the code manually you can record the macro by pressing record, do your thing and stop the recording. Then you will have the code which you can inject it to your file (look at my tutorial above)

encrypting excel workbook sheet with python

I'm currently implementing a tool to automise parts of my daily work. Therefore I need to create a python tool which creates an excel-file (workbook) with several informations and encrypts the sheets of the file.
The first part which creates the file and fills it with the data works perfectly.
But the encryption doesn't work at all.
I'm using win32com, win32com.client and openpyxl. The workbook hast two different sheets, named "1" and "2".
My Workbook:
import win32com.client
import os, sys, win32com, os.path, time
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True
workbook = excel.Workbooks.Open(reading_path) ####this is the path where the file is stored
sheet = workbook.Worksheets(1)
So I searched through other topics and got the following:
import openpyxl
sheet.protection.set_password('test')
sheet.save(saving_path)
Unfortunately this doesn't work... My shell response an AttributeError. In Detail:
AttributeError: <unknown>.set_password
Does someone knows another way how to encrypt just the pages in excel with python?
Thanks a lot for your help!
It is not entirely clear what you mean by "encrypting the sheet" as the openpyxl code you refer to has nothing to do with encryption; see the warning in the documentation. Excel does support encryption of entire workbooks though, but that appears to be different from what you want.
In any case, your code fails because the sheet you get from win32com is a wildly different beast than what openpyxl expects. For example, sheet being based on COM requires an Excel process to run for manipulation to be possible, while openpyxl does not even require Excel to be available on the host machine.
Now in your particular case, you do not actually need openpyxl (although you might find that using it over win32com has plenty of benefits), and you could stay entirely within COM. As such, adding password protection is possible through Worksheet.Protect which in your case would boil down to simply running
sheet.Protect('test')

Update an Excel sheet in real time using Python

Is there a way to update a spreadsheet in real time while it is open in Excel? I have a workbook called Example.xlsx which is open in Excel and I have the following python code which tries to update cell B1 with the string 'ID':
import openpyxl
wb = openpyxl.load_workbook('Example.xlsx')
sheet = wb['Sheet']
sheet['B1'] = 'ID'
wb.save('Example.xlsx')
On running the script I get this error:
PermissionError: [Errno 13] Permission denied: 'Example.xlsx'
I know its because the file is currently open in Excel, but was wondering if there is another way or module I can use to update a sheet while its open.
I have actually figured this out and its quite simple using xlwings. The following code opens an existing Excel file called Example.xlsx and updates it in real time, in this case puts in the value 45 in cell B2 instantly soon as you run the script.
import xlwings as xw
wb = xw.Book('Example.xlsx')
sht1 = wb.sheets['Sheet']
sht1.range('B2').value = 45
You've already worked out why you can't use openpyxl to write to the .xlsx file: it's locked while Excel has it open. You can't write to it directly, but you can use win32com to communicate with the copy of Excel that is running via its COM interface.
You can download win32com from https://github.com/mhammond/pywin32 .
Use it like this:
from win32com.client import Dispatch
xlApp = Dispatch("Excel.Application")
wb=xlApp.Workbooks.Item("MyExcelFile.xlsx")
ws=wb.Sheets("MyWorksheetName")
At this point, ws is a reference to a worksheet object that you can change. The objects you get back aren't Python objects but a thin Python wrapper around VBA objects that obey their own conventions, not Python's.
There is some useful if rather old Python-oriented documentation here: http://timgolden.me.uk/pywin32-docs/contents.html
There is full documentation for the object model here: https://msdn.microsoft.com/en-us/library/wss56bz7.aspx but bear in mind that it is addressed to VBA programmers.
If you want to stream real time data into Excel from Python, you can use an RTD function. If you've ever used the Bloomberg add-in use for accessing real time market data in Excel then you'll be familiar with RTD functions.
The easiest way to write an RTD function for Excel in Python is to use PyXLL. You can read how to do it in the docs here: https://www.pyxll.com/docs/userguide/rtd.html
There's also a blog post showing how to stream live tweets into Excel using Python here: https://www.pyxll.com/blog/a-real-time-twitter-feed-in-excel/
If you wanted to write an RTD server to run outside of Excel you have to register it as a COM server. The pywin32 package includes an example that shows how to do that, however it only works for Excel prior to 2007. For 2007 and later versions you will need this code https://github.com/pyxll/exceltypes to make that example work (see the modified example from pywin32 in exceltypes/demos in that repo).
You can't change an Excel file that's being used by another application because the file format does not support concurrent access.

Is there anyway we can call an excel addin using python?

Is there anyway we can call an excel addin using python?
I would like to call a user-defined add-in which is present in excel using a python program. I need a freeware I think pyxll requires license.
You can try xlwings if you like to use python inside your excel.
Or try to dispatch excel with win32com
excel = win32com.client.gencache.EnsureDispatch ("Excel.Application")
I think that you'd have to save your add-in as vba project (How to Use Your Excel Add-In Functions in VBA.
Generally nearly everything that can be done via VBA could be done with python and dispatched excel, so VBA Object Model reference is a good documentation on it.

Generating correct excel xls format

I created a little script in python to generate an excel compatible xml file (saved with xls extension). The file is generated from a part database so I can place an order with the extracted data.
On the website for ordering the parts, you can import the excel file so the order fills automatically. The problem here is that each time I want to make an order, I have to open excel and save the file with xls extension of type MS Excel 97-2003 to get the import working.
The excel document then looks exactly the same, but when opened with notepad, we cannot see the xml anymore, only binary dump.
Is there a way to automate this process, by running a bat file or maybe adding some line to my python script so it is converted in the proper format?
(I know that question has been asked before, but it never has been answered)
There are two basic approaches to this.
You asked about the first: Automating Excel to open and save the file. There are in fact two ways to do that. The second is to use Python tools that can create the file directly in Python without Excel's help. So:
1a: Automating Excel through its automation interface.
Excel is designed to be controlled by external apps, through COM automation. Python has a great COM-automation interface inside of pywin32. Unfortunately, the documentation on pywin32 is not that great, and all of the documentation on Excel's COM automation interface is written for JScript, VB, .NET, or raw COM in C. Fortunately, there are a number of questions on this site about using win32com to drive Excel, such as this one, so you can probably figure it out yourself. It would look something like this:
import win32com.client
excel = win32com.client.Dispatch('Excel.Application')
spreadsheet = excel.Workbooks.Open('C:/path/to/spreadsheet.xml')
spreadsheet.SaveAs('C:/path/to/spreadsheet.xls', fileformat=excel.xlExcel8)
That isn't tested in any way, because I don't have a Windows box with Excel handy. And I vaguely remember having problems getting access to the fileformat names from win32com and just punting and looking up the equivalent numbers (a quick google for "fileformat xlExcel8" shows that the numerical equivalent is 56, and confirms that's the right format for 97-2003 binary xls).
Of course if you don't need to do it in Python, MSDN is full of great examples in JScript, VBA, etc.
The documentation you need is all on MSDN (since the Office Developer Network for Excel was merged into MSDN, and then apparently became a 404 page). The top-level page for Excel is Welcome to the Excel 2013 developer reference (if you want a different version, click on "Office client development" in the navigation thingy above and pick a different version), and what you mostly care about is the Object model reference. You can also find the same documentation (often links to the exact same webpages) in Excel's built-in help. For example, that's where you find out that the Application object has a Workbooks property, which is a Workbooks object, which has Open and Add methods that return a Workbook object, which has a SaveAs method, which takes an optional FileFormat parameter of type XlFileFormat, which has a value xlExcel8 = 56.
As I implied earlier, you may not be able to access enumeration values like xlExcel8 for some reason which I no longer remember, but you can look the value up on MSDN (or just Google it) and put the number 56 instead.
The other documentation (both here and elsewhere within MSDN) is usually either stuff you can guess yourself, or stuff that isn't relevant from win32com. Unfortunately, the already-sparse win32com documentation expects you to have read that documentation—but fortunately, the examples are enough to muddle your way through almost everything but the object model.
1b: Automating Excel via its GUI.
Automating a GUI on Windows is a huge pain, but there are a number of tools that make it a whole lot easier, such as pywinauto. You may be able to just use swapy to write the pywinauto script for you.
If you don't need to do it in Python, separate scripting systems like AutoIt have an even larger user base and even more examples to make your life easier.
2: Doing it all in Python.
xlutils, part of python-excel, may be able to do what you want, without touching Excel at all.

Categories

Resources