简体   繁体   English

使用Ironpython在Spotfire中运行VBA宏

[英]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. 因此,我尝试在该线程中进行询问-IronPython-运行Excel宏,但我的信誉不足。

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. 因此,大致按照链接中给出的代码,我创建了一些代码,该代码将文件保存到特定位置,然后打开一个存在于其中的工作簿,调用其中的宏,这将对我所处理的数据执行少量操作下载到.xls,以使其更加美观。

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. 通常,Spotfire的信息不多,但在这里却很少。 It seems to be something .NET related but that's about all I can tell. 似乎与.NET相关,但这仅是我能说的。

The Error Message 错误讯息

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. 追溯(最近一次呼叫最近):文件“ Spotfire.Dxp.Application.ScriptSupport”,行未知,在ExecuteForDebugging中文件“”,行未知,在StandardError中:调用的目标引发了异常。

The Script 剧本

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. 因此,据我所知,上面的代码非常完美,但是与我的Spotfire环境的配置方式配合不佳。 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. 在Spotfire端,我有两个输入字段,一个提供文件路径,另一个提供文件名。 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. 我从根本上创建了三个xml来实现此解决方案。 The first was the main one which contained all of the main vba stuff. 第一个是包含所有主要vba内容的主要内容。 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. 这将查找该脚本填充的另一个xml中的文件夹,以查找在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. 该脚本填充两个xml文件,并告诉主宏运行,该宏中的代码完成后会自动关闭excel。

The third xml is for a series of colour rules, so user can custom define them depending on their dashboard. 第三个xml用于一系列颜色规则,因此用户可以根据其仪表板自定义定义它们。 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. 长话短说:从Spotfire运行excel宏的一种解决方案是使用我上面使用的system.dianostics方法,只需将您的宏设置为自动运行即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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