從 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開發