简体   繁体   中英

Run a VBA macro in Spotfire using Ironpython

So I would try ask over in this thread IronPython - Run an Excel Macro but I don't have enough reputation.

So roughly following the code given in the link I created some code which would save a file to a specific location, then open a workbook that exists there, calling the macro's within it, which would perform a small amount of manipulation on the data which I downloaded to .xls, to make it more presentable.

Now I've isolated the problem to this particular part of the code (below).

Spotfire normally is not that informative but it gives me very little to go on here. It seems to be something .NET related but that's about all I can tell.

Traceback (most recent call last): File "Spotfire.Dxp.Application.ScriptSupport", line unknown, in ExecuteForDebugging File "", line unknown, in StandardError: Exception has been thrown by the target of an invocation.

from Spotfire.Dxp.Data.Export import DataWriterTypeIdentifiers
from System.IO import File, Directory
import clr
clr.AddReference("Microsoft.Office.Interop.Excel")
import Microsoft.Office.Interop.Excel as Excel 

excel = Excel.ApplicationClass()   
excel.Visible = True
excel.DisplayAlerts = False   
workbook = ex.Workbooks.Open('myfilelocation')

excel.Run('OpenUp')
excel.Run('ActiveWorkbook')
excel.Run('DoStuff')

excel.Quit()

Right, so I'm answering my own question here but I hope it helps somebody. So the above code, as far as I'm aware was perfectly fine but didn't play well with the way my spotfire environment is configured. However, after going for a much more macro heavy approach I was able to find a solution.

On the spotfire end I've two input fields, one which gives the file path, the other the file name. Then there's a button to run the below script. These are joined together in the script but are crucially separate, as the file name needs to be inputted into a separate file, to be called by the main macro so that it can find the file location of the file.

Fundamentally I created three xml's to achieve this solution. The first was the main one which contained all of the main vba stuff. This would look into a folder in another xml which this script populates to find the save location of the file specified in an input field in spotfire. Finding the most recent file using a custom made function, it would run a simple series of conditional colour operations on the cell values in question.

This script populates two xml files and tells the main macro to run, the code in that macro automatically closing excel after it is done.

The third xml is for a series of colour rules, so user can custom define them depending on their dashboard. This gives it some flexibility for customisation. Not necessary but a potential request by some user so I decided to beat them to the punch.

Anyway, code is below.

from Spotfire.Dxp.Data.Export import DataWriterTypeIdentifiers
from System.IO import File, Directory
import clr
clr.AddReference("Microsoft.Office.Interop.Excel")
import Microsoft.Office.Interop.Excel as Excel 
from Spotfire.Dxp.Data.Export import *
from Spotfire.Dxp.Application.Visuals import *
from System.IO import *
from System.Diagnostics import Process

# Input field which takes the name of the file you want to save
name = Document.Properties['NameOfDocument']

# Document property that takes the path 
location = Document.Properties['FileLocation']

# just to debug to make sure it parses correctly. Declaring this in the script 
# parameters section will mean that the escape characters of "\" will render in a 
# unusable way whereas doing it here doesn't. Took me a long time to figure that out.

print(location)

# Gives the file the correct extension. 
# Couldn't risk leaving it up to the user.
newname = name + ".xls"

#Join the two strings together into a single file path 
finalProduct = location + "\\" + newname


#initialises the writer and filtering schema
writer = Document.Data.CreateDataWriter(DataWriterTypeIdentifiers.ExcelXlsDataWriter)
filtering = Document.ActiveFilteringSelectionReference.GetSelection(table).AsIndexSet()

# Writes to file
stream = File.OpenWrite(finalProduct)

# Here I created a seperate xls which would hold the file path. This 
# file path would then be used by the invoked macro to find the correct folder. 

names = []
for col in table.Columns:
  names.append(col.Name)
writer.Write(stream, table, filtering, names)
stream.Close() 

# Location of the macro. As this will be stored centrally 
# it will not change so it's okay to hardcode it in. 
runMacro = "File location\macro name.xls"

# uses System.Diagnostics to run the macro I declared. This will look in the folder I 
# declared above in the second xls, auto run a function in vba to find the most 
# up to date file


p = Process()  
p.StartInfo.FileName = runMacro
p.Start()

Long story short: To run excel macro's from spotfire one solution is to use the system.dianostics method I use above and simply have your macro set to auto run.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM