Exemplo de Script - Importação Personalizada do Excel
Este plugin foi desenvolvido para importar um documento Excel formatado.
Ele permite dados recuados 1 coluna para dentro, ignorando a formatação do título antes de chegar aos cabeçalhos, campos de cabeçalho que abrangem 2 linhas, pula linhas com subtotais/total geral e ignora um rodapé existente. No evento de execução do Business Object:
BusinessObjectID
fornece o TableID
de destino para dados importados.
File
fornece o arquivo a ser importado (campo de dados binários)
AttachmentID
e AttachmentTypeID
: GUIDs para identificar a fonte de dados importados
if (columnName == "Billing")
//onde "Faturamento" é o valor na segunda coluna para o início da primeira linha do cabeçalho.
if (firstColumnName == "Grand Total:")
//primeira coluna, primeira linha, valor após todos os registros dos dados importados desejados
if (SecondColumnName == "Invoice Number:")
//primeiro valor da coluna da última linha de dados do título antes da primeira linha do cabeçalho parte inferior, as colunas de destino são correspondidas a uma contagem do número de colunas do Excel para dados de origem. Ou seja, a linha a seguir indicará para obter a 10ª coluna de dados e inseri-la no campo "Produto" no Objeto de Negócios de destino
Caso de Uso
Isso pode ser usado quando outro serviço ou um processo comercial interno é gerenciado por meio de um Excel formatado, que é mantido e posteriormente precisa ser ingerido App Builder como uma fonte de dados para um processo de negócios em andamento. Isso é útil durante uma transição quando um processo de negócios é substituído em App Builder em partes, em vez de na íntegra de uma só vez, e esta se torna a melhor opção para garantir a continuidade precisa e perfeita dos dados, sem etapas adicionais para a empresa formatar os dados antes de trazê-los para App Builder para processos atualizados.
Referências de Plugins
Coluna | Tipo de dados | Descrição |
---|---|---|
BusinessObjectID | Unique ID | fornece o TableID do destino para dados importados |
File | binary data field | fornece o arquivo a ser importado |
AttachmentID | Unique ID | identificar a fonte dos dados importados |
AttachmentTypeID | Unique ID | identificar a fonte dos dados importados |
Script de Importação Personalizado do Excel
#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);
}
}