Ejemplo de Secuencia de Comandos: Importación de Excel Personalizada
Este complemento está diseñado para importar un documento de Excel formateado.
Permite sangrar una columna de datos, ignorar el formato del título antes de llegar a los encabezados, campos de encabezado que abarcan dos filas, omitir filas con subtotales/total general e ignorar un pie de página existente. Evento en ejecución de Business Object:
BusinessObjectID
proporciona el TableID
de destino para los datos importados.
File
proporciona el archivo que se va a importar (campo de datos binarios)
AttachmentID
y AttachmentTypeID
: GUID para identificar la fuente de los datos importados
if (columnName == "Billing")
//donde "Facturación" es el valor en la segunda columna para el comienzo de la primera fila del encabezado.
if (firstColumnName == "Grand Total:")
//primera columna, primer valor de fila después de todos los registros de los datos importados deseados
if (SecondColumnName == "Invoice Number:")
//valor de la primera columna de la última fila de datos del título antes de la primera fila del encabezado la parte inferior, las columnas de destino se corresponden con un recuento del número de columna de Excel para los datos de origen, es decir, la siguiente línea indicará que se debe obtener la décima columna de datos y se la insertará en el campo "Producto" en el objeto comercial de destino
Caso de Uso
Esto se puede utilizar cuando otro servicio o un proceso empresarial interno se gestiona a través de un archivo Excel formateado, que se mantiene y luego se debe incorporar en App Builder como fuente de datos para un proceso empresarial en curso. Esto resulta útil durante una transición cuando se reemplaza un proceso empresarial en App Builder en porciones, en lugar de su totalidad de una vez, y esta se convierte en la mejor opción para garantizar una continuidad precisa y sin problemas de los datos sin pasos adicionales para que la empresa formatee los datos antes de incorporarlos. App Builder para procesos actualizados.
Referencias de Complementos
Columna | Tipo de datos | Descripción |
---|---|---|
BusinessObjectID | Unique ID | Proporciona el TableID del destino para los datos importados |
File | binary data field | proporciona el archivo que se va a importar |
AttachmentID | Unique ID | identificar la fuente de los datos importados |
AttachmentTypeID | Unique ID | identificar la fuente de los datos importados |
Secuencia de Comandos de Importación de Excel Personalizado
#r "ExcelDataReader.dll"
using ExcelDataReader;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Vinyl.Sdk.Filtering;
// TARGET
// The MRP table it will populate
string strBusinessObjectID;
strBusinessObjectID = Row["BusinessObjectID"].Value.ToString();
Guid targetMRPTableId = Guid.Parse(strBusinessObjectID);
// SOURCE
// File to be imported
var file = (byte[])Row["File"].Value;
string strAttachmentID;
strAttachmentID = Row["AttachmentID"].Value.ToString();
string strAttachmentTypeID;
strAttachmentTypeID = Row["AttachmentTypeID"].Value.ToString();
//Guid attachmentID = Guid.Parse(strAttachmentID);
// SERVICES
var tableService = Services.GetService<ITableService>();
var eventService = Services.GetService<IEventService>();
// EVENT TABLES
var mrpTable = await GetEventTable(eventService, tableService, targetMRPTableId);
// Read file
using (var stream = new MemoryStream(file))
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
// Generates the Primary Key for the SRP as it will also be used as a FK
// on the MRP
//var id = Guid.Parse(strAttachmentID);
await ConsumeMRP(eventService, mrpTable, reader, strAttachmentID, strAttachmentTypeID);
}
}
/// <sumary>
/// For a given table id, returns its EventTable
/// </sumary>
private async Task<EventTable> GetEventTable(
IEventService eventService,
ITableService tableService,
Guid tableId)
{
// This workaround is not needed anymore in the latest 2.7 hotfix
// but anything before then, to get the EventTable from a given
// tableId, we need to raise a filter event with no rows
var table = tableService.GetTable(tableId);
var filter = table.CreateFilter();
filter.Limit = 0;
var eventTable = await eventService.InvokeFilterEventAsync(filter);
return eventTable;
}
/// <sumary>
/// Tries to set a cell value, checking if column is available first
/// </sumary>
private void TrySetValue(EventRow row, string columnName, object value)
{
if (row.TryGetCell(columnName, out EventCell cell))
{
cell.Value = value;
}
}
private string GetColumnName(object value)
{
string str = Convert.ToString(value ?? "");
str = Regex.Replace(str, " *[\r\n]+", " ");
return str.Trim();
}
/// <sumary>
/// Populate the MRP until the first cell is empty
/// </sumary>
private async Task ConsumeMRP(
IEventService eventService,
EventTable importTable,
IExcelDataReader reader,
string attachmentID,
string attachmentTypeID)
{
while(reader.Read())
{
var columnName = reader
.GetValue(1)?
.ToString()
.Replace(":", "")
.Trim();
if (columnName == "Billing") {
// MRP started
break;
}
}
var fields = new List<string>();
for (var index = 1; index < reader.FieldCount; index++)
{
fields.Add(GetColumnName(reader.GetValue(index)));
}
if (!reader.Read())
{
// MRP cut short? Throw exception?
return;
}
// Append sub-title
for (var index = 0; index < fields.Count; index++)
{
if (!reader.IsDBNull(index+1))
{
fields[index] += " " + GetColumnName(reader.GetValue(index+1));
}
}
int rowcount= 0;
while(reader.Read())
{
rowcount = rowcount+1;
string SecondColumnName="";
string firstColumnName="";
if(! reader.IsDBNull(1))
{
SecondColumnName = reader.GetValue(1).ToString().Trim();
}
else
{
SecondColumnName ="";
}
if(! reader.IsDBNull(0))
{
firstColumnName = reader.GetValue(0).ToString();
}
else
{
firstColumnName="";
}
if (firstColumnName == "Grand Total:")
{
break;
}
if (SecondColumnName == "Invoice Number:")
{
continue;
}
if (SecondColumnName == "")
{
continue;
}
// Creates a new row in the staging table
var dataRow = await eventService.InvokeNewEventAsync(importTable);
dataRow["stGarnishmentID"].Value = Guid.NewGuid();
dataRow["AttachmentID"].Value = attachmentID;
dataRow["AttachmentTypeID"].Value = attachmentTypeID;
//testRow6["Product"].Value = reader.GetValue(10);
// await eventService.InvokeInsertEventAsync(testRow6);
//row["Invoice Number"].Value=reader.GetValue(1);
for (var index = 0; index < fields.Count; index++)
{
var columnName = fields[index];
var value = Convert.ToString(reader.GetValue(index+1));
TrySetValue(dataRow, columnName, value);
}
await eventService.InvokeInsertEventAsync(dataRow);
}
}