Ir para o conteúdo

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);



    }

}