¿Cuál es la forma más eficiente de crear una tabla de datos JMP a partir de una variable DataTable de C#?Actualmente estoy usando el portapapeles de Windows para pegar toda la información en JMP. (C# llena primero el portapapeles) Esto funciona, pero el portapapeles de Windows no es confiable y, a veces, aparece vacío.
Envié un ticket de soporte hace unos meses y recibí este mensaje...
Mensaje de soporte:
..........................
Además, puede usar los métodos GetTableHandleFromIndex o GetTableHandleFromName para obtener una referencia de C# al objeto de automatización DataTable, como se documenta. aquí .
..........................
Realmente no entendí lo que esto significaba, cuando leí el enlace y no tenía ni idea de qué hacer.
Básicamente, código de automatización C# JMP. Quiero hacer algo como esto:
CreateJMPDatatable (DT)
donde DT es una variable de tipo DataTable (C#)
Podría intentar bucles for anidados para recorrer columnas y filas y hacer que JSL rellene celda por celda y cree las columnas y filas necesarias (que intentaré pronto), pero me pregunto si hay una manera más rápida y fácil de lograr el mismo resultado.(100.000 filas y 100 columnas, así que quiero algo rápido y eficiente)
Gracias,
Hola Chris,
Gracias por la actualización. no pensé en el EstablecerVectorDeDatos método al trabajar en el ejemplo. Buena atrapada.
Sería bueno si este pegado se pudiera hacer desde algo que no sea el portapapeles de Windows. (es decir, una cadena delimitada por tabulaciones pasada desde un método).O un método que puede tomar la variable de la tabla de datos directamente y convertirla en una tabla de datos JMP.
Si ya tiene la tabla en forma de cadena delimitada por tabuladores, ¿por qué no simplemente guardar la cadena en un archivo y abrir ese archivo en JMP? Eso eliminaría la dependencia del portapapeles de Windows.
O incluso mejor, podría establecer una variable JSL en la cadena delimitada por tabuladores y usar la función Abrir para abrir la tabla directamente desde la cadena. A continuación se muestra un ejemplo de cómo hacerlo.
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" );
Básicamente, puede usar una variable JSL en lugar del portapapeles para pasar la cadena y la función Abrir para crear su tabla en lugar de la opción "Pegar con nombres de columna".
Solo una actualización, justin_chilton , si bien su solución funciona, fue extremadamente lenta para tablas muy grandes (y resultó ser inadecuada para mis necesidades)
Es mucho más rápido de usar.
JmpDT.GetColumn(ColName).SetDataVector (que llena 1 columna a la vez)
en lugar de
jmpDT.GetColumn(col.ColumnName).SetCellVal
Que solo llena 1 celda a la vez
Por lo tanto, solo necesita código para convertir columnas de datos en tablas de datos en una matriz para alimentar el método SetDataVector
ejemplo: string[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
Entonces, con este enfoque, solo necesita recorrer las columnas una vez:
Código de muestra:
for (int i = 0; i < Resumen.Columnas.Recuento; i++)
{
cadena ColName = Summary.Columns[i].ColumnName;
var tipo de datos = Summary.Columns[i].DataType;
si (tipo de datos == tipo de (cadena))
{
string[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
JmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
más si (tipo de datos == tipo de (doble))
{
double[] ColArray = Summary.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
más si (tipo de datos == tipo de (int))
{
int[] ColArray = Resumen.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
más si (tipo de datos == tipo de (flotante))
{
float[] ColArray = Resumen.AsEnumerable().Select(rw => rw.Field(ColName)).ToArray();
jmpDT.GetColumn(ColName).SetDataVector(ColArray);
}
}
Si bien esta solución funciona (y es mucho más rápida que usar el método "SetCellVal", todavía es casi el doble de lenta que pegar una cadena delimitada por tabulaciones desde el portapapeles de Windows para mi aplicación.
Hice pruebas contrarreloj: ~9000 filas y 175 columnas
pegar portapapeles ~ 2.5 s, mientras que la técnica por encima de ~ 4.5 s
Por lo tanto, me gustaría solicitar en el futuro un método más directo para traer datos a JMP desde las tablas de datos de C#.
Yo usaría el portapapeles de Windows, pero incluso con la captura de errores, el portapapeles de Windows puede ser escamoso y poco confiable en las PC de algunas personas, por lo tanto, no me gustaría usar esa técnica.
Para su información, el portapapeles de WIndows se completaría con una cadena delimitada por tabulaciones, luego use este código para obtener datos en JMP.
command = "dts << Traer ventana al frente << Borrar selección de columna << clear select; dts=currentdatatable();";
myJMP.RunCommand(comando);
comando = "menú principal (\"Pegar con nombres de columna\");";
myJMP.RunCommand(comando);
Sería bueno si este pegado se pudiera hacer desde algo que no sea el portapapeles de Windows. (es decir, una cadena delimitada por tabulaciones pasada desde un método).O un método que puede tomar la variable de la tabla de datos directamente y convertirla en una tabla de datos JMP.
Gracias por su consideración,
cris
Gracias por el enlace a la solución, pude revisar bien el código en Visual Studio. Por cierto, la automatización JMP funciona bien en mi solución, pero la solución de muestra dio un error. Tengo JMP 13 y Visual Studio 2017 instalados.
Cuando hago clic en cualquier botón en la GUI, aparece este error:
Ocurrió System.BadImageFormatException
HResult=0x8013101B
Mensaje=No se pudo cargar el archivo o ensamblado 'Interop.JMP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' o una de sus dependencias. Este ensamblaje está creado por un tiempo de ejecución más reciente que el tiempo de ejecución cargado actualmente y no se puede cargar.
Source=
Rastreo de pila:
Re: Crear una tabla de datos JMP a partir de la variable DataTable de C#
Además, disculpe la pregunta nuevamente, esencialmente respondió mi pregunta hace algunos meses, ¡mis habilidades para leer correos electrónicos antiguos no fueron tan buenas ayer! ¡Gracias de nuevo!
No hay una ruta directa para convertir un objeto de tabla de datos de C# en una tabla de datos de JMP. En su lugar, deberá usar los métodos de automatización de JMP para crear una tabla vacía, recorrer las columnas de la tabla de C#, crear las columnas de JMP y luego recorrer las filas de la tabla de C#, agregando los valores de fila/columna a los datos de JMP. Mesa.Re: Crear una tabla de datos JMP a partir de la variable DataTable de C#Gracias por la respuesta detallada, ¡el soporte técnico de JMP es insuperable!
Re: Crear una tabla de datos JMP a partir de la variable DataTable de C#Hola Chris,
Creo que fui yo quien te ayudó hace unos meses. El fragmento que proporcionó de nuestra conversación se refería a la creación de un objeto DataTable de C# a partir de una tabla de datos JMP, no al revés. A continuación se muestra lo que dije acerca de pasar de C# a JMP.
No hay una ruta directa para convertir un objeto de tabla de datos de C# en una tabla de datos de JMP. En su lugar, deberá usar los métodos de automatización de JMP para crear una tabla vacía, recorrer las columnas de la tabla de C#, crear las columnas de JMP y luego recorrer las filas de la tabla de C#, agregando los valores de fila/columna a los datos de JMP. Mesa.
Aquí hay algo que armé que recorre las columnas y filas para crear una 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;
}
}
Espero que esto sea útil. Avísame si tienes más preguntas.
¡Gracias!
Re: Crear una tabla de datos JMP a partir de la variable DataTable de C#JMP se envía con un programa de muestra de C#.Para JMP 13, se encuentra en C:\Program Files\SAS\JMP\13\Samples\Automation\Visual CSharp Sample.Esto le mostrará cómo abrir una tabla de datos.El ejemplo de automatización de Visual Basic para DataTable ilustrará los métodos para crear una nueva tabla y llenarla (simplemente cree una instancia de una variable DataTable y use NewColumn).Los métodos se traducen fácilmente a C#.
Brian Corcorán
Desarrollo JMP