从 C# DataTable 变量创建 JMP 数据表从 C# DataTable 变量创建 JMP 数据表的最有效方法是什么?我目前正在使用 Windows 剪贴板将所有信息粘贴到 JMP 中。 (C# 首先填充剪贴板)这可行,但 Windows 剪贴板不可靠,有时会显示为空。
几个月前我发送了一张支持票并收到了这条消息。
支持留言:
……………………
此外,您还可以使用 GetTableHandleFromIndex 或 GetTableHandleFromName 方法获取对 DataTable 自动化对象的 C# 引用,如文档所述这里。
……………………
当我阅读链接时,我真的不明白这意味着什么,并且不知道该怎么办?
基本上 C# JMP 自动化代码我想做这样的事情:
创建JMP数据表 (DT)
其中 DT 是 DataTable 类型的变量 (C#)
我可以尝试嵌套 for 循环来遍历列和行,并让 JSL 逐个单元格填充并创建所需的列和行(我很快就会尝试),但想知道是否有更快、更简单的方法来实现相同的结果?(100,000 行和 100 列,所以我想要快速高效的东西)
谢谢你,
回复:从 C# DataTable 变量创建 JMP 数据表嗨克里斯,
感谢更新。 我没有想到设置数据向量处理示例时的方法。 接得好。
如果可以通过 Windows 剪贴板以外的其他方式进行粘贴,那就太好了。 (即从方法传递的制表符分隔字符串)。或者直接获取数据表变量并转换为JMP数据表的方法。
如果您已经拥有制表符分隔字符串形式的表格,为什么不直接将该字符串保存到文件中并在 JMP 中打开该文件呢? 这将消除对 Windows 剪贴板的依赖。
或者更好的是,您可以将 JSL 变量设置为制表符分隔的字符串,然后使用 Open 函数直接从该字符串打开表。 下面是如何执行此操作的示例。
tabDelimitedStr = "name age sex height weight
KATIE 12 F 59 95
LOUISE 12 F 61 123
JANE 12 F 55 74";
Open( Char to Blob( tabDelimitedStr ), "text" );
基本上,您可以使用 JSL 变量而不是剪贴板来传递字符串,并使用 Open 函数来创建表而不是“使用列名粘贴”选项。
回复:从 C# DataTable 变量创建 JMP 数据表只是一个更新,贾斯汀·奇尔顿,虽然您的解决方案有效,但对于非常大的表来说速度非常慢(结果不足以满足我的需求)
使用起来要快得多
JmpDT.GetColumn(ColName).SetDataVector(一次填充 1 列)
代替
jmpDT.GetColumn(col.ColumnName).SetCellVal
一次仅填充 1 个单元格
因此,您只需要代码将数据表中的数据列转换为数组即可输入到 SetDataVector 方法中
示例: string[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
因此,使用这种方法,您只需要循环遍历列一次:
示例代码:
for (int i = 0; i < Summary.Columns.Count; i++)
{
字符串 ColName = Summary.Columns[i].ColumnName;
var datatype = Summary.Columns[i].DataType;
if (数据类型==typeof(字符串))
{
string[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
JmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
else if (数据类型 == typeof(double))
{
double[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
else if (数据类型 == typeof(int))
{
int[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
else if (数据类型 == typeof(float))
{
float[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
}
虽然此解决方案有效(并且比使用“SetCellVal”方法快几个数量级,但它仍然比从我的应用程序的 Windows 剪贴板粘贴制表符分隔字符串慢几乎两倍。
我进行了计时试验:约 9000 行和 175 列
粘贴剪贴板〜2.5s,而技术以上〜4.5s
因此,我希望将来有一种更直接的方法将数据从 C# 数据表引入 JMP。
我会使用 Windows 剪贴板,但即使有错误捕获,Windows 剪贴板在某些人的 PC 上也可能不稳定且不可靠,因此不喜欢使用该技术。
仅供参考,WIndows 剪贴板将填充制表符分隔的字符串,然后使用此代码将数据获取到 JMP 中。
command = "dts << 将窗口置于前面 << 清除列选择 << 清除选择; dts=currentdatatable();";
myJMP.RunCommand(命令);
command = "主菜单(\"粘贴列名\");";
myJMP.RunCommand(命令);
如果可以通过 Windows 剪贴板以外的其他方式进行粘贴,那就太好了。 (即从方法传递的制表符分隔字符串)。或者直接获取数据表变量并转换为JMP数据表的方法。
谢谢您的考虑,
克里斯
回复:从 C# DataTable 变量创建 JMP 数据表感谢您提供解决方案的链接,我能够在 Visual Studio 中很好地检查代码。 BTW JMP 自动化在我的解决方案中运行良好,但示例解决方案出现错误。 我安装了 JMP 13 和 Visual Studio 2017。
当我单击 GUI 上的任何按钮时,我收到此错误:
发生 System.BadImageFormatException
H结果=0x8013101B
Message=无法加载文件或程序集“Interop.JMP,版本=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。 该程序集是由比当前加载的运行时更新的运行时构建的,无法加载。
Source=<无法评估异常源>
堆栈跟踪:
<无法评估异常堆栈跟踪>
回复:从 C# DataTable 变量创建 JMP 数据表
另外,再次对这个问题感到抱歉,您基本上在几个月前就回答了我的问题,昨天我阅读旧电子邮件的能力不太好! 再次感谢!
没有将 C# 数据表对象转换为 JMP 数据表的直接路径。 相反,您需要使用 JMP 自动化方法创建一个空表,循环遍历 C# 表的列,创建 JMP 列,然后循环遍历 C# 表的行,将行/列值添加到 JMP 数据桌子。回复:从 C# DataTable 变量创建 JMP 数据表感谢您的详细回复,JMP 的技术支持是首屈一指的!
回复:从 C# DataTable 变量创建 JMP 数据表嗨克里斯,
我相信我就是几个月前帮助你的人。 您在我们的对话中提供的代码片段涉及从 JMP 数据表创建 C# DataTable 对象,而不是相反。 下面是我所说的从 C# 到 JMP 的情况。
没有将 C# 数据表对象转换为 JMP 数据表的直接路径。 相反,您需要使用 JMP 自动化方法创建一个空表,循环遍历 C# 表的列,创建 JMP 列,然后循环遍历 C# 表的行,将行/列值添加到 JMP 数据桌子。
以下是我将循环遍历列和行以创建 JMP.DataTable 的内容放在一起:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
// call method to get sample C# data table
DataTable dt = p.GetTable();
JMP.Application myJMP = new JMP.Application();
myJMP.Visible = true;
myJMP.EnableInteractiveMode(true);
JMP.DataTable jmpDT;
jmpDT = myJMP.NewDataTable("Example");
Object jmpCol;
// add each column to the JMP table
foreach (DataColumn col in dt.Columns)
{
// if its an integer, create numeric column (you may need to check for other Types, such as Decimal or DateTime)
if (col.DataType == System.Type.GetType("System.Int32"))
{
jmpCol = jmpDT.NewColumn(col.ColumnName, JMP.colDataTypeConstants.dtTypeNumeric, 0, 8);
}
else
{
jmpCol = jmpDT.NewColumn(col.ColumnName, JMP.colDataTypeConstants.dtTypeCharacter, 0, 8);
}
}
// add rows to the table
jmpDT.AddRows( (Int16) dt.Rows.Count, 0 );
int i = 1;
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
{
jmpDT.GetColumn(col.ColumnName).SetCellVal(i, row[col.ColumnName].ToString());
}
i++;
}
}
// From: https://msdn.microsoft.com/en-us/library/9ha04z01(v=vs.110).aspx
private DataTable GetTable()
{
// Create new DataTable.
DataTable table = new DataTable();
// Declare DataColumn and DataRow variables.
DataColumn column;
DataRow row;
// Create new DataColumn, set DataType, ColumnName
// and add to DataTable.
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "id";
table.Columns.Add(column);
// Create second column.
column = new DataColumn();
column.DataType = Type.GetType("System.String");
column.ColumnName = "item";
table.Columns.Add(column);
// Create new DataRow objects and add to DataTable.
for (int i = 0; i < 10; i++)
{
row = table.NewRow();
row["id"] = i;
row["item"] = "item " + i;
table.Rows.Add(row);
}
return table;
}
}
我希望这是有帮助的。 如果您还有任何疑问,请告诉我。
谢谢!
回复:从 C# DataTable 变量创建 JMP 数据表JMP 附带一个 C# 示例程序。对于 JMP 13,该文件位于 C:\Program Files\SAS\JMP\13\Samples\Automation\Visual CSharp Sample。这将展示如何打开数据表。DataTable 的 Visual Basic 自动化示例将说明创建新表并填充它的方法(只需实例化 DataTable 变量并使用 NewColumn)。这些方法很容易转换为 C#。
布赖恩·科科伦
JMP开发