Refresh Pivot Table with XLWINGS - python

I am trying to refresh a pivot table in excel upon data written by XLWINGS.
As I don't know how to do it directly from XLWINGS, I tried to use VBA.
Let's split my process in 2 steps:
Step1
I launch the python code from vba (my module name is "PosRep", the python code writtes back a range of data in a specified sheet thanks to xlwings.
Sub launchPython()
RunPython ("import PosRep; PosRep")
End Sub
Step 2
But as I don't know in advance the size of my newly created Range in Excel, I want to select it, add a new Name (NamedRange) and refresh my pivot (already linked to the NamedRange).
Sub SelectRange()
Worksheets("GPODump").Range("A1").Select
'...
End Sub
Both Subs work independently well. But I cannot manage to make them work in a raw. The following code:
Sub Main()
launchPython
SelectRange
End Sub
produces a VBA error "Select method of Range class failed" on the statement:
Worksheets("GPODump").Range("A1").Select
I presume there is a conflict with the XLWINGS VBA module but I can't figure out what it can be...
Anyone's help would be more than welcome !
Thx

The problem came from the VBA code. The following code works fine:
Sheets("GPODump").Select
Sheets("GPODump").Range("A1").Select

Maybe it's too late but you can do it within xlwings - this is what worked for me:
import xlwings as xw
# open excel App
app_excel = xw.App(visible = False)
# open the excel file, select the tab and the PivotTable to refresh
wbook = xw.Book( 'YourFile.xlsx' )
wbook.sheets['Tab1'].select()
wbook.api.ActiveSheet.PivotTables('PivotTableName').PivotCache().refresh()

I was looking how to solve this for Mac, here is how I did to refresh all pivot tables and etc:
wb.api.active_sheet.refresh_all(wb.api)
Hopes that this saves someone else time. Took me a while to figure it out.

Related

How to refresh all pivot table of an excel file using Python xlwings [duplicate]

I am trying to refresh a pivot table in excel upon data written by XLWINGS.
As I don't know how to do it directly from XLWINGS, I tried to use VBA.
Let's split my process in 2 steps:
Step1
I launch the python code from vba (my module name is "PosRep", the python code writtes back a range of data in a specified sheet thanks to xlwings.
Sub launchPython()
RunPython ("import PosRep; PosRep")
End Sub
Step 2
But as I don't know in advance the size of my newly created Range in Excel, I want to select it, add a new Name (NamedRange) and refresh my pivot (already linked to the NamedRange).
Sub SelectRange()
Worksheets("GPODump").Range("A1").Select
'...
End Sub
Both Subs work independently well. But I cannot manage to make them work in a raw. The following code:
Sub Main()
launchPython
SelectRange
End Sub
produces a VBA error "Select method of Range class failed" on the statement:
Worksheets("GPODump").Range("A1").Select
I presume there is a conflict with the XLWINGS VBA module but I can't figure out what it can be...
Anyone's help would be more than welcome !
Thx
The problem came from the VBA code. The following code works fine:
Sheets("GPODump").Select
Sheets("GPODump").Range("A1").Select
Maybe it's too late but you can do it within xlwings - this is what worked for me:
import xlwings as xw
# open excel App
app_excel = xw.App(visible = False)
# open the excel file, select the tab and the PivotTable to refresh
wbook = xw.Book( 'YourFile.xlsx' )
wbook.sheets['Tab1'].select()
wbook.api.ActiveSheet.PivotTables('PivotTableName').PivotCache().refresh()
I was looking how to solve this for Mac, here is how I did to refresh all pivot tables and etc:
wb.api.active_sheet.refresh_all(wb.api)
Hopes that this saves someone else time. Took me a while to figure it out.

Start python script from excel with input

I have a Python script (gui.py - a calculation program, written by somebody else). I try to run this from excel with input data from the same excel file. It works fine when I start the script as:
objShell.Run PythonExe & PythonScript3
In the python script I used the following to get f.ex data from H5 cell, works also fine:
import openpyxl
wb = openpyxl.load_workbook("01.xlsm")
ws = wb.active
mastNumber = ws['H5']
But I don't want to edit a lot in gui.py (have just simple changes) so I planned to use a 2nd script (caller.py) which gets the data from Excel, then I import this to gui.py and there I just use the variable from caller.py. It works also as long as I start gui.py directly. When I start it from Excel I get an error msg.
error msg
So as long as the flow is not Excel -> gui-py -> which imports caller to get data from same Excel file -everything works fine.
I am open to any solution for this problem or a completely new approach if there is better for somebody with limited programming skills.
Looking at the error, can you try putting complete path of the excel file at line wb = openpyxl.load_workbook("01.xlsm") instead of just 01.xlsm.

Excel pivot table filter in Python via win32com

I tried really hard to find how to do these simple lines of VBA code in Python via win32com but I couldn't find how to execute it properly :
ActiveSheet.PivotTables("PivotTable1").PivotFields("Quarters").ClearAllFilters
ActiveSheet.PivotTables("PivotTable1").PivotFields("Effective deadline"). _
PivotFilters.Add2 Type:=xlBefore, Value1:="10/10/2017"
When running these lines :
from win32com.client import DispatchEx
excel = DispatchEx('Excel.Application')
wb = excel.Workbooks.Open('myfile.xlsx')
ws = wb.Worksheets('MySheet')
ws.PivotTables(1).PivotFields("Quarters").PivotFilters('Add2', 'xlBefore', '10/10/2017')
I end up with an 'Invalid number of parameters' so I guess I'm quite close but can't find the documentation to complete my code
Has anyone ever managed to do this kind of work ?
You are calling the wrong method. You should call .Add2 after the PivotFilters property:
ws.PivotTables(1).PivotFields("Effective deadline").ClearAllFilters()
ws.PivotTables(1).PivotFields("Effective deadline").PivotFilters.Add2(31, None, '10/10/2017')
Also, notice that you need to specify the XlPivotFilterType Enumeration according to the type of filter you want to apply (in this case xlBefore = 31)

Can't get image into excel header using openpyxl or win32com

I need to get an image file into an Excel header in an automated fashion; I don't believe this is possible in openpyxl, but I thought it might be doable in win32com, though I am not able to get it working. Does anyone know a way to do this? I found an excel macro that successfully does it within Excel:
Sub InsertPicture
With ActiveSheet.PageSetup.LeftHeaderPicture
.FileName = "C:/Users/bharris/Desktop/my_image_file.png"
.Height = 45
.Width = 30
.CropTop = -30
End With
ActiveSheet.PageSetup.LeftHeader = "&;G"
So I tried implementing from within python using win32com:
excel = DispatchEx('Excel.Application')
excel.Visible = True
wb=excel.Workbooks.Open(my_excel_file.xlsx')
ws = wb.Sheets(1)
ws.PageSetup.LeftHeaderPicture.FileName ="my_image_file.png"
ws.PageSetup.LeftHeader = "&;G"
wb.SaveAs('my_excel_file.xlsx')
wb.Close(True, 'my_excel_file.xlsx')
excel.Application.Quit()
but it gives me:
raise AttributeError("Property '%s.%s' can not be set." % (self._username_, attr))
AttributeError: Property '<unknown>.FileName' can not be set.
So it looks like FileName is not a property within win32com like it is in VBA within Excel. I've tried some different combinations of things and nothing seems to work. If anyone knows how to do this, with any type of openpyxl or win32com code, or any other code (though it has to be able to edit an existing spreadsheet, not just write a new one like xlsxwriter), your help is much appreciated!
P.S. I have found several solutions for how to insert an image into a cell, but this question is for inserting into the header specifically.
Thanks much,
Robert

xlwings doesn't write data in file.xlsm when running through excel

I am trying to use xlwings for simple consolidation from several xls files.
For this, I have a all_files.xlsm file that contains a button with macros assigned to it. The macros looks like:
Sub check_data()
RunPython ("import python_code; python_code.consolidation()")
End Sub
In same folder I have a file python_code.py with function "consolidation" inside.
I also use Workbook.set_mock_caller() in order to have an opportunity to run a code through python interface. It looks like:
def consolidation(file_path):
*** smth to get the data I need ***
...
*** after I got data ***
Range('A1').table.clear_contents() #string1
Range('A1').value = data #string2
def main():
consolidation(file_path)
if __name__ == '__main__':
xl.Workbook.set_mock_caller(path_to_file)
main()
The problem is that when I am running the script through the button in excel file last two strings (string1 and string2) - Range('A1').table.clear_contents() and Range('A1').value = data doesn't work. Although the rest of the code works fine (however, it contains xlwing also). Moreover, if I run the script through the python interface using set mock caller, it works just fine, including string1 and string2 (marked in the code).
Any help and advices are really appreciated!
I found decision for my problem. For using xlwings in python you should import xlwings.bas in your excel file (see manual for xlwings). It turns out, that I imported it for this macros before I've updated xlwings. So I deleted this file and imported a new one. Everything works fine now.

Categories

Resources