TL;DR:有更好的方法来做到这一点;如果只是为了列名,我认为不值得做第 2 部分,因为在信息链接中更改 sql 很容易,但这是可能的。
好的,我会尽量(阅读:失败)不要太啰嗦。
1) 是否可以为日期设置下拉菜单? 可以。 最简单的方法是使用您的所有数据提取数据表可供最终用户使用的日期选择。这是一个查找better way to generate months/year table 列表的示例,请记住,在创建下拉列表时,您的文档属性必须具有数据类型“日期”,然后您应该能够通过列中的唯一值设置属性值,以针对您的日期列从新数据,就像您对字符串下拉列表所做的那样。
如果您有一小部分特定日期可供选择,这可能还不错。如果下拉列表变得更长,您的最终用户可以输入他们正在寻找的日期以加快搜索速度(尽管根据我的经验,他们中的许多人会滚动浏览直到找到他们正在寻找的日期)。
虽然这是完全可以接受的,但如果您愿意添加 javascript,我个人建议使用 Popup Calendar 这些对于最终用户来说相当简单,并且可以允许他们使用日历或自己输入. (如果他们输入的不是日期,甚至可以用红色字母和感叹号告知他们没有输入实际日期)
2) 如何传递多个站点名称以仅将这些站点拉入 Spotfire 文件中
Hoo boi,从哪里开始。
第一步:您想如何选择站点名称列表?我将继续假设您有一个包含不同站点名称列表的数据表。
您的下一个选择是如何让您的用户选择他们想要的站点名称。常规选项包括使用列表框过滤器、显示表格和使用标记的行,或者提供一个文本区域,用户可以在其中输入他们自己的选择。
当我需要这样做时,我做了一个数据表和一个文本区域的组合,所以这就是我要在这里描述的内容。
我首先为用户提供了一个文本区域,该区域的格式设置为“特定大小”,其高度大于通常的高度,以提示,是的,他们可以输入多行。如果他们知道他们要查找的值,他们可以手动输入,或者从 Excel 文件中复制粘贴等。
如果他们不知道自己在寻找什么,站点名称列表将显示在为用户显示的表格中,然后他们可以在可视化上标记他们想要的行并按下按钮即可将光标穿过标记的站点名称列表,将它们连接在一起,并将它们放在前面提到的文本框中(注意:如果您不想让它们手动输入列表,您可以离开文本区域,将这些组合起来接下来的两段代码,并将其直接扔到 SpecialFilterProperty 中)。
请注意光标很慢;如果您有超过几千行要循环,这可能会停止几秒钟。
按钮代码:
from Spotfire.Dxp.Application.Visuals import CrossTablePlot
from Spotfire.Dxp.Data import IndexSet
from Spotfire.Dxp.Data import RowSelection
from Spotfire.Dxp.Data import DataValueCursor
from Spotfire.Dxp.Data import DataSelection
TextFltr = ""
crossSource = Document.Data.Tables["Distinct_SiteNames"]
##Get a Row Count
rowCount = Document.Data.Tables["Distinct_SiteNames"].RowCount
##Index Set of all our rows
rowIndexSet=Document.ActiveMarkingSelectionReference.GetSelection(Document.Data.Tables["Distinct_SiteNames"]).AsIndexSet()
allRows = IndexSet(rowCount,True)
if rowIndexSet.IsEmpty != True:
allRows = rowIndexSet
colCurs = DataValueCursor.CreateFormatted(crossSource.Columns["Site_Name"])
##Optional: Loop through to determine average value
colTotal = ''
for row in crossSource.GetRows(allRows, colCurs):
colTotal += ', ' + colCurs.CurrentValue
if TextFltr == "":
TextFltr += colTotal[2:]
else:
TextFltr += colTotal
Document.Properties["SelectedSiteNames"] = TextFltr
from System.Collections.Generic import Dictionary
from Spotfire.Dxp.Application.Scripting import ScriptDefinition
import clr
scriptDef = clr.Reference[ScriptDefinition]()
Document.ScriptManager.TryGetScript("Change Special Filter Value", scriptDef)
params = Dictionary[str, object]()
Document.ScriptManager.ExecuteScript(scriptDef.ScriptCode, params)
在底部它引用了第二个脚本;这是附加到按钮的脚本,当用户想要提交他们的选择并刷新数据表时,它会解析文本区域。
我使用的通用代码在这里,脚本标题为“更改特殊过滤器值”,它允许使用换行符、制表符、逗号、引号和其他一些分隔符。根据您的用户群的需求,随意在此处添加或减去。
strVals = Document.Properties["SelectedSiteNames"]
lst = ""
cnt = 0
x = 0
y = 0
z = 0
for letter in strVals:
if y == 1:
if letter == " ":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == ",":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == "\n":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == "\r":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == "'":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == '"':
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == '\t':
lst = lst + "'" + strVals[x:z] + "', "
y = 0
else:
if letter <> " " and letter <> "," and letter <> "\n" and letter <> "\r" and letter <> "'" and letter <> '"' and letter <> "\t":
if y == 0:
cnt += 1
print letter
x = z
y = 1
z += 1
if y == 1:
lst = lst + "'" + strVals[x:z] + "', "
print lst
lst = lst.upper()
if len(lst) > 0:
lst = lst[1:len(lst) - 3]
Document.Properties["SpecialFilterValue"] = lst
第一步现已完成!您现在可以将所有选定站点名称的列表传递给您的存储过程。
注意:我认为 Spotfire 可以通过字符串值传递的字符数是有限制的。在我之前的测试中,我认为它已经超过 500,000 个字符(已经有一段时间了,所以我不记得确切),所以你有很大的余地,但它确实存在,并且取决于你使用的数据源,可能会更低。
第二步:修改存储过程
您的存储过程基本上是这样的:
Create procedure ProcA(In Start_Date date, IN End_Date date, In Site_Name text)
Begin
DECLARE @Script nvarchar(max) =
N'
Select * from TableA where day between Start_Date and End_Date and Site_Name in (' + @Site_Name + ') '
EXECUTE (@Script)
相比之下简直太容易了!
(毕竟没有循环!我记得的奇怪用例在这里不适用,除非您还使用不允许直接传递参数的数据库......)