Was ist die effizienteste Möglichkeit, eine JMP-Datentabelle aus einer C#-DataTable-Variablen zu erstellen?Ich verwende derzeit die Windows-Zwischenablage, um alle Informationen in JMP einzufügen. (C# füllt zuerst die Zwischenablage) Das funktioniert, aber die Windows-Zwischenablage ist nicht zuverlässig und manchmal ist sie leer.
Ich habe vor ein paar Monaten ein Support-Ticket gesendet und diese Nachricht erhalten.
Support-Nachricht:
.........................
Außerdem können Sie die Methoden „GetTableHandleFromIndex“ oder „GetTableHandleFromName“ verwenden, um einen C#-Verweis auf das DataTable-Automatisierungsobjekt abzurufen, wie dokumentiert Hier .
.........................
Als ich den Link las, verstand ich nicht wirklich, was das bedeutete, und wusste nicht, was ich tun sollte?
Grundsätzlich möchte ich C#-JMP-Automatisierungscode wie folgt ausführen:
JMPDatatable (DT) erstellen
wobei DT eine Variable vom Typ DataTable (C#) ist.
Ich könnte verschachtelte for-Schleifen ausprobieren, um Spalten und Zeilen zu durchlaufen und JSL Zelle für Zelle füllen zu lassen und die benötigten Spalten und Zeilen zu erstellen (was ich bald versuchen werde), aber ich frage mich, ob es einen schnelleren und einfacheren Weg gibt, das gleiche Ergebnis zu erzielen?(100.000 Zeilen und 100 Spalten, also möchte ich etwas Schnelles und Effizientes)
Danke schön,
Hallo Chris,
Danke für das Update. Darüber habe ich nicht nachgedacht SetDataVector Methode bei der Arbeit am Beispiel. Guter Fang.
Es wäre schön, wenn das Einfügen von etwas anderem als der Windows-Zwischenablage erfolgen könnte. (dh eine tabulatorgetrennte Zeichenfolge, die von einer Methode übergeben wird).Oder eine Methode, die eine datierbare Variable direkt übernehmen und in eine JMP-Datentabelle konvertieren kann.
Wenn Sie die Tabelle bereits in Form einer tabulatorgetrennten Zeichenfolge haben, warum speichern Sie die Zeichenfolge nicht einfach in einer Datei und öffnen diese Datei in JMP? Dadurch würde die Abhängigkeit von der Windows-Zwischenablage entfallen.
Oder noch besser: Sie könnten einfach eine JSL-Variable auf die tabulatorgetrennte Zeichenfolge setzen und die Open-Funktion verwenden, um die Tabelle direkt aus der Zeichenfolge zu öffnen. Nachfolgend finden Sie ein Beispiel dafür.
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" );
Grundsätzlich können Sie eine JSL-Variable anstelle der Zwischenablage verwenden, um die Zeichenfolge zu übergeben, und die Open-Funktion zum Erstellen Ihrer Tabelle anstelle der Option „Mit Spaltennamen einfügen“.
Nur ein Update, Justin_Chilton , Ihre Lösung funktioniert zwar, aber bei sehr großen Tabellen war sie extrem langsam (und erwies sich als unzureichend für meine Anforderungen).
Es ist viel schneller zu verwenden
JmpDT.GetColumn(ColName).SetDataVector (der jeweils eine Spalte füllt)
anstatt
jmpDT.GetColumn(col.ColumnName).SetCellVal
Dadurch wird jeweils nur eine Zelle gefüllt
Sie benötigen also lediglich Code, um Datenspalten in Datentabellen in Arrays umzuwandeln, die in die SetDataVector-Methode eingespeist werden
Beispiel: string[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
Bei diesem Ansatz müssen Sie die Spalten also nur einmal durchlaufen:
Beispielcode:
for (int i = 0; i < Summary.Columns.Count; i++)
{
string ColName = Summary.Columns[i].ColumnName;
var datatype = Summary.Columns[i].DataType;
if (datatype==typeof(string))
{
string[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
JmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
else if (datatype == typeof(double))
{
double[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
else if (datatype == typeof(int))
{
int[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
else if (datatype == typeof(float))
{
float[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
}
Obwohl diese Lösung funktioniert (und um Größenordnungen schneller ist als die Verwendung der Methode „SetCellVal“), ist sie für meine Anwendung immer noch fast doppelt so langsam wie das Einfügen einer tabulatorgetrennten Zeichenfolge aus der Windows-Zwischenablage.
Ich habe Zeitversuche gemacht: ~9000 Zeilen und 175 Spalten
Einfügen der Zwischenablage dauert ca. 2,5 Sekunden, während die Technik länger als ca. 4,5 Sekunden dauert
Daher möchte ich in Zukunft eine direktere Methode anfordern, um Daten aus C#-Datentabellen in JMP zu importieren.
Ich würde die Windows-Zwischenablage verwenden, aber selbst mit Fehlerabfang kann die Windows-Zwischenablage auf manchen PCs unzuverlässig und unzuverlässig sein, daher möchte ich diese Technik nicht verwenden.
Zu Ihrer Information: Die Windows-Zwischenablage wird mit einer tabulatorgetrennten Zeichenfolge gefüllt. Verwenden Sie dann diesen Code, um Daten in JMP zu übertragen.
command = "dts << Fenster nach vorne bringen << Spaltenauswahl löschen << clear select; dts=currentdatatable();";
myJMP.RunCommand(command);
command = "main menu(\"Einfügen mit Spaltennamen\");";
myJMP.RunCommand(command);
Es wäre schön, wenn das Einfügen von etwas anderem als der Windows-Zwischenablage erfolgen könnte. (dh eine tabulatorgetrennte Zeichenfolge, die von einer Methode übergeben wird).Oder eine Methode, die eine datierbare Variable direkt übernehmen und in eine JMP-Datentabelle konvertieren kann.
Danke für deine Rücksicht,
Chris
Vielen Dank für den Link zur Lösung. Ich konnte den Code in Visual Studio einwandfrei überprüfen. Übrigens läuft die JMP-Automatisierung in meiner Lösung einwandfrei, aber die Beispiellösung hat einen Fehler ausgegeben. Ich habe JMP 13 und Visual Studio 2017 installiert.
Wenn ich auf eine beliebige Schaltfläche auf der GUI klicke, erhalte ich diese Fehlermeldung:
System.BadImageFormatException ist aufgetreten
HResult=0x8013101B
Meldung=Datei oder Assembly „Interop.JMP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null“ oder eine ihrer Abhängigkeiten konnte nicht geladen werden. Diese Assembly wird von einer neueren Laufzeit als der aktuell geladenen Laufzeit erstellt und kann nicht geladen werden.
Quelle=
StackTrace:
Betreff: JMP-Datentabelle aus C#-DataTable-Variable erstellen
Und bitte entschuldigen Sie nochmals die Frage, Sie hatten meine Frage im Wesentlichen schon vor ein paar Monaten beantwortet, meine Lesekenntnisse in alten E-Mails waren gestern nicht so gut! Danke noch einmal!
Es gibt keinen direkten Pfad zum Konvertieren eines C#-Datentabellenobjekts in eine JMP-Datentabelle. Stattdessen müssen Sie JMP-Automatisierungsmethoden verwenden, um eine leere Tabelle zu erstellen, die Spalten der C#-Tabelle zu durchlaufen, die JMP-Spalten zu erstellen und dann die Zeilen der C#-Tabelle zu durchlaufen und die Zeilen-/Spaltenwerte zu den JMP-Daten hinzuzufügen Tisch.Betreff: JMP-Datentabelle aus C#-DataTable-Variable erstellenVielen Dank für die ausführliche Antwort. Der technische Support von JMP ist unübertroffen!
Betreff: JMP-Datentabelle aus C#-DataTable-Variable erstellenHallo Chris,
Ich glaube, ich war derjenige, der Ihnen vor ein paar Monaten geholfen hat. Der von Ihnen bereitgestellte Ausschnitt aus unserem Gespräch bezog sich auf die Erstellung eines C#-DataTable-Objekts aus einer JMP-Datentabelle, nicht umgekehrt. Nachfolgend finden Sie meine Ausführungen zum Wechsel von C# zu JMP.
Es gibt keinen direkten Pfad zum Konvertieren eines C#-Datentabellenobjekts in eine JMP-Datentabelle. Stattdessen müssen Sie JMP-Automatisierungsmethoden verwenden, um eine leere Tabelle zu erstellen, die Spalten der C#-Tabelle zu durchlaufen, die JMP-Spalten zu erstellen und dann die Zeilen der C#-Tabelle zu durchlaufen und die Zeilen-/Spaltenwerte zu den JMP-Daten hinzuzufügen Tisch.
Hier ist etwas, das ich zusammengestellt habe und das die Spalten und Zeilen durchläuft, um eine JMP.DataTable zu erstellen:
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;
}
}
Ich hoffe, das ist hilfreich. Lassen Sie mich wissen, wenn Sie weitere Fragen haben.
Danke!
Betreff: JMP-Datentabelle aus C#-DataTable-Variable erstellenJMP wird mit einem C#-Beispielprogramm geliefert.Für JMP 13 befindet sich diese unter C:\Program Files\SAS\JMP\13\Samples\Automation\Visual CSharp Sample.Hier wird gezeigt, wie eine Datentabelle geöffnet wird.Das Visual Basic-Automatisierungsbeispiel für DataTable veranschaulicht die Methoden zum Erstellen und Füllen einer neuen Tabelle (instanziieren Sie einfach eine DataTable-Variable und verwenden Sie NewColumn).Die Methoden lassen sich leicht in C# übersetzen.
Brian Corcoran
JMP-Entwicklung