quinta-feira, 2 de outubro de 2014

Manipulando o quadro de Gantt e Criando uma regra de sequenciamento Personalizada - Treinamento API Preactor

Uma regra de sequenciamento consiste em distribuir da melhor for possível as operações/ ordens de produção pelos recursos produtivos disponíveis.

O Preactor já faz isso muito bem, pois possui inúmeras regras de sequenciamento Padrão: Minimização de Setup, Sequencia Preferida, Regras APS para frente, para trás, por prioridade, por data de entrega. 

Mas alguns empresas possuem particularidades que não são atendidas por essas regras, por isso a necessidade de desenvolver um algorítimo que interaja com o Preactor sequenciando as ordens de forma a atender essas particularidades.

O intuito desse tutorial não é te tornar um expert em regras de sequenciamento, e sim abrir sua cabeça sobre o que pode ser feito e através das funções que conhecerá. Com esse conhecimento você poderá montar sua própria regra de sequenciamento dentro do Preactor.

Para essa parte do treinamento você irá precisar baixar o modelo workshop 03



Funções PlanningBoard Preactor


A biblioteca PlanningBoard do Preactor é um grupo de funções que permitem o programador interagir com o Gráfico de Gantt. Na PlanningBoard que estão contidas as funções de sequenciamento de ordens, manipulação de calendários, movimentar da linha de tempo do Preactor, além de outras.

Vamos aprender então alguns funções básicas do PlanningBoard:

Instanciando a classe:
 IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);
 //criando uma instancia da classe
 IPlanningBoard planning = preactor.PlanningBoard;



Função para mover a linha do tempo do Preactor:
IPlanningBoard planning = preactor.PlanningBoard;
//POSICIONA A LINHA DO TEMPO EM 02/10/2014 14:30
planning.TerminatorTime = new DateTime(2014,10,02,14,30,0);


Sequenciando todas as Desprogramadas:
            //SEQUENCIAMENTO PARA FRENTE
            planning.SequenceAll(SequenceAllDirection.Forwards, SequencePriority.Default);

            //SEQUENCIAMENTO PARA FRENTE POR DATA DE ENTREGA
            planning.SequenceAll(SequenceAllDirection.Forwards, SequencePriority.DueDate);

            //SEQUENCIAMENTO PARA FRENTE POR ORDEM DE CRIAÇÃO DAS ORDENS
            planning.SequenceAll(SequenceAllDirection.Forwards, SequencePriority.FileOrder);

            //SEQUENCIAMENTO PARA FRENTE POR PRIORIDADE
            planning.SequenceAll(SequenceAllDirection.Forwards, SequencePriority.Priority);

            //SEQUENCIAMENTP PARA FRENTE POR PRIORIDADE REVERSA
            planning.SequenceAll(SequenceAllDirection.Forwards, SequencePriority.ReversePriority);

            //SEQUENCIAMENTO PARA FRENTE POR CARGA/PESO 
            planning.SequenceAll(SequenceAllDirection.Forwards, SequencePriority.Weight);

            //TODAS ESSES TIPOS DE SEQUENCIAMENTO TAMBÉM PODEM SER APLICADOS PARA
            //SEQUENCIAMENTO PARA TRÁS, BASTA ALTERAR O PARÂMETRO 1 DA FUNÇÃO
            planning.SequenceAll(SequenceAllDirection.Backwards, SequencePriority.Default);


Desprogramar, ou desalocar as ordens do Gantt:
            //TODAS ESSES TIPOS DE SEQUENCIAMENTO TAMBÉM PODEM SER APLICADOS PARA
            //SEQUENCIAMENTO PARA TRÁS, BASTA ALTERAR O PARÂMETRO 1 DA FUNÇÃO
            planning.SequenceAll(SequenceAllDirection.Backwards, SequencePriority.Default);

            //DESPROGRAMAR TODAS AS ORDENS QUE ESTÃO DENTRO DO INTERVALO DE 2 MESES APÓS O TERMINADOR
            planning.UnallocateAll(planning.TerminatorTime, planning.TerminatorTime.AddMonths(2), OperationReferencePoint.ChangeStart);

            //DESPROGRAMAR UMA ORDEM, E TODAS SUAS OPERAÇÕES
            planning.UnallocateOperation(10, OperationSelection.AllOperations);
            //DESPROGRAMAR APENAS A OPERAÇÃO COMPREENDIDA PELO REGISTRO 10
            planning.UnallocateOperation(10, OperationSelection.ThisOperation);


Sequenciar uma única operação ou Ordem:
            //SEQUENCIAR TODAS AS OPERAÇÕES DA ORDEM 10 PARA FRENTE EM 01/01/2000 14:30
            var data = new DateTime(2000, 01, 01, 14, 30, 0);
            planning.SequenceOperation(10, SequenceOperationSelection.AllForwards, data);

            //SEQUENCIAR APENAS A OPERAÇÃO 10 EM 01/01/2000 14:30
            planning.SequenceOperation(10, SequenceOperationSelection.ThisOperation, data);


WorkShop 03



Com base nas funções que você aprendeu até o momento utilize o modelo do Workshop 03 e crie uma regra de sequenciamento personalizada.

Sua regra de sequenciamento deve ler o campo "Atributo 2" de cada ordem e sequenciar as operações de acordo com a sequencia de cadastro da tabela "Atributo 2", que segue a seguinte ordem:Regra 01, Regra 02, Regra 03, regra 04;

Explicando melhor: leia o campo "Atributo 2" das ordens, e sequencie 
1º todas as ordens "Regra 01", 
2º todas as ordens "Regra 02", e assim por diante.



Mãos a obra e boa sorte.

dúvidas: besaleel@msn.com




workShop 02 - Treinamento Preactor API

Conforme o primeiro workshop a solução do problema será exposta em tópicos, num formato de passo-a-passo, ok?


1º - Criar uma nova classe workshop02;




2º - Copiar e colar o método de ler o arquivo CSV, e altera-lo para atender o layout do novo arquivo CSV ( AtualizaOrdens.csv);

private IList getApontamentosByFileCSV(string pathFile)
        {
            try
            {
                IList apos = new List();

                if (!File.Exists(pathFile))
                {
                    MessageBox.Show("O arquivo de Apontamento não foi encontrado.");
                    return new List();
                }
                StreamReader rd = new StreamReader(pathFile, Encoding.Default);
                try
                {
                    var count = 0;
                    while (!rd.EndOfStream)
                    {
                        count++;
                        var linha = rd.ReadLine();
                        if (count == 1) continue;
                        if (string.IsNullOrEmpty(linha)) continue;

                        var colunas = linha.Split(';');
                        Apontamento iten = new Apontamento();
                        iten.Ordem = colunas[0];
                        iten.Recurso = colunas[1];
                        iten.Status = colunas[2];

                        apos.Add(iten);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    rd.Close();
                }


                return apos;
            }
            catch (Exception ex)
            {
                throw new Exception("Falha ao recuperar os dados do arquivo CSV:"
+ Environment.NewLine + ex.Message);

            }

        }

3º - Criar o método de interface com o Preactor, e fazer a função que atualize os dados da tabela de "Apontamento";


public int AtualizaApontamento(ref PreactorObj preactorComObject, ref object pespComObject, ref string arquivo)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);

            try
            {
                preactor.DisplayStatus("Atualizar Apontamentos", "Lendo arquivo CSV...");
                IList itens = getApontamentosByFileCSV(arquivo);
                preactor.DestroyStatus();
                if (itens.Count == 0)
                {
                    MessageBox.Show("O arquivo está em branco.");
                    return 0;
                }
                preactor.DisplayStatus("Atualizar Apontamentos", "Aplicando Atualizações");
                var total = itens.Count;
                var count = 0;
                preactor.UpdateStatus(count, total);
                foreach (var iten in itens)
                {
                    count++;
                    preactor.UpdateStatus(count, total);
                    //BUSCAR A ORDEM NA TABELA DE APONTAMENTOS
                    var record = preactor.FindMatchingRecord("Apontamento", "Ordem", 0, iten.Ordem);
                    if(record < 0)
                        continue;

                    //SÓ AS ORDENS QUE RECEBERAM UM STATUS CONHECIDO
                    switch (iten.Status)
                    {
                        case "Iniciada":
                            preactor.WriteField("Apontamento", "Recurso", record, iten.Recurso);
                            preactor.WriteField("Apontamento", "Status", record, iten.Status);
                            break;
                        case "Liberada":
                            preactor.WriteField("Apontamento", "Recurso", record, iten.Recurso);
                            preactor.WriteField("Apontamento", "Status", record, iten.Status);
                            break;
                        case "Cancelada":
                            preactor.DeleteRecord("Apontamento", record);
                            break;
                        case "Finalizada":
                            preactor.DeleteRecord("Apontamento", record);
                            break;
                    }
                }
                MessageBox.Show("Seus registros foram atualizados com sucesso!");
                preactor.DestroyStatus();
            }
            catch (Exception ex)
            {
                preactor.DestroyStatus();
                MessageBox.Show("Falha ao atualizar os registros de Apontamento: " + Environment.NewLine + ex.Message);
            }
            return 0;

        }



4º - Criar um Botão para chamar a ação do workshop 02;


segue a codificação do Botão:
; ---------------------------------------------------------------------------
; Edit Apontamentos
; ---------------------------------------------------------------------------
;
EDIT_Apontamentos : PREDIT.EXE,
   "/FMT:Apontamento"   /NDS
   "/ActiveX:Atualizar Dados da Tabela:PESP.EventHandler:RunScriptByName:AtualizaApontamento",
   Edit Apontamento,
   Preactor Database Editor,
   Foreground,
   ALWAYS:{RETURN};

;

5º - Criar a Ação Personalizada, dentro do Preactor;





6º - Testar nossa função;

Nesse workshop eu alterei o local de execução da função, não está dentro do quadro de Gantt conforme o workshop 01, isso para que você posso ver a flexibilidade do Preactor quanto a customizações.

A ação será chamada diretamente da tela e edição da tabela de "Apontamentos", em um menu de nome "Ferramentas".


Alguns comandos utilizados

preactor.DisplayStatus("Atualizar Apontamentos", "Aplicando Atualizações");
Exibe uma janela de Status sendo seu primeiro parâmetro o Título da Janela e o segundo o descritivo do Status;

preactor.UpdateStatus(count, total);
Atualiza o Status Bar que está contido na janela, sendo seu primeiro parâmetro andamento do status (inteiro), e o segundo numero que equivale a 100% do Status Bar, pode ser o número total de elementos de uma lista, ou Array, ou mesmo número de elementos de um tabela de banco de dados que estamos lendo;

preactor.DestroyStatus();
Fecha a janela de Status aberta pelo comando DisplaySTatus. Caso você abra um DisplayStatus e se esqueça de fechar, ao chamar sua ação ela irá manter a janela aberta causando um problema para o Preactor, deixado ele inoperante, e para restaurar o Preactor você precisará matar o processo (ctrl + alt + del) e restartar o Preactor.

Dica, por essa razão sempre que você utilizar o DisplayStatus se lembre de colocar dentro do Catch de sua função um DestroyStatus.


Arquivos do work02 para download.

Dúvidas besaleel@msn.com ou comente aqui.

quarta-feira, 1 de outubro de 2014

3ª PARTE - Buscando Dados em uma tabela - Treinamento Preactor

Funções para buscar informações nas tabelas


O API da Preactor possui funções para facilitar a vida do programar ao buscar alguma informação dentro das tabelas do Preactor. Por exemplo, quando queremos identificar uma ordem pelo seu Número, ou pelo recurso que ela está alocado, ou mesmo buscar todas as operações de uma ordem.

Creio que essa função sem sombra de dúvidas é a mais utilizada ao se trabalhar com Preactor.

preactor.FindMatchingRecord("TABELA","CAMPO", posição, ValorBuscado);
Sobregarca:
preactor.FindMatchingRecord("TABELA", "CAMPO", posição, ValorBuscado, SearchDirection.Backwards);

A função básica possui 4 parâmetros:

  1. Tabela: "Apontamento";
  2. Campo ou Field: "Ordem";
  3. Posição, ou a partir de qual posição dentro da fila você deseja buscar sua informação: posição ou record ;
  4. Valor: valor a ser buscado, pode ser uma string, double, date, int bool;
  5. O quinto parâmetro da sobrecarga indica a direção de sua busca, "SearchDirection.Forwards" você quer buscar a informação do início da fila para o final, ou "SearchDirection.Backwards" do final da fila para o início;


Veja o exemplo abaixo onde iremos procurar dentro da tabela de Apontamento uma ordem A001:

public int Run(ref PreactorObj preactorComObject, ref object pespComObject)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);

            var ordem = "A001";

            int record = preactor.FindMatchingRecord("Apontamento", "Ordem", 0, ordem);
            if (record > 0)
            {
                MessageBox.Show("A ordem: " + ordem + " foi encontrada, registro núm. " + record);
                return 0;
            }
            MessageBox.Show("A ordem " + ordem + " não foi encontrada!");
            return 0;

        }
Infelizmente esse método se resumo a buscar apenas um valor em um campo, ele não funciona também para buscarmos um trecho de uma string dentro de outra.

Quando precisamos buscar dois campos em uma tabela, efetuamos uma busca por um campo (ex: Recurso), em seguida lemos os valores do outro campo( ex: Ordem), aí se encontrarmos o que procuramos saímos da função e retornamos o resultado.

Veja esse exemplo em que buscamos os registros que possuem o Recurso: "Packing Line 1" e que o campo ordem possua o valor "A001":

 public int Run(ref PreactorObj preactorComObject, ref object pespComObject)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);

            
            var recurso = "Packing Line 1";
            int record = preactor.FindMatchingRecord("Apontamento", "Ordem", 0, recurso);
            while (record > 0)
            {
                var ordem = preactor.ReadFieldString("Apontamento", "Ordem", record);
                if(ordem == "A001")
                    break;              
                //VEJA QUE A PRÓXIMA BUSCA SERÁ A PARTIR DO REGISTRO "RECORD"
                record = preactor.FindMatchingRecord("Apontamento", "Ordem", record, recurso);
            }

            if (record > 0)
            {
                MessageBox.Show("O recurso " + recurso + " e a ordem A001 possuem o registro " + record);
                return 0;
            }
            MessageBox.Show("O recurso " + recurso + " e a ordem A001, não foram encontrados!");
            return 0;
        }
Uma observação, vale apena lembrar que o Preactor tem seus registros indexados como uma fila, por esse motivo, veja que no final do while, nós refazemos a busca a partir do registro "Record", sendo que "Record" nada mais é do que uma índice dentro da fila.



WorkShop 02

Para o workshop 02 faça download do modelo (Clique aqui para Download).
Importe o arquivo CSV AtualizaOrdens.csv que está contido na pasta Import-Export Files do modelo. Busque na tabela de "Apontamento" os registros das ordens que estão contidas no arquivo CSV e atualize o nome do Recurso e o Status, se o Status do arquivo for "finalizada", você deverá excluir o registro da tabela de Apontamento.
Mãos a obra.


Resposta do workShop 02


WorkShop 01 - Preactor API

Resolução workshop 01:

Irei mostrar a resolução do workshop em tópicos, seguindo uma sequencia lógica de trabalho, ok?

1º - Dentro de meu projeto Olá Mundo, eu criei uma classe contendo exatamente as mesmas propriedades do arquivo CSV:
 public class Apontamento
    {
        private string _ordem;
        private string _recurso;
        private string _status;
        private DateTime _dataDeInicio;
        private DateTime _dataDeFim;

        public string Ordem
        {
            get { return _ordem; }
            set { _ordem = value; }
        }

        public string Recurso
        {
            get { return _recurso; }
            set { _recurso = value; }
        }

        public string Status
        {
            get { return _status; }
            set { _status = value; }
        }

        public DateTime DataDeInicio
        {
            get { return _dataDeInicio; }
            set { _dataDeInicio = value; }
        }

        public DateTime DataDeFim
        {
            get { return _dataDeFim; }
            set { _dataDeFim = value; }
        }

        public override bool Equals(object obj)
        {
            if (obj is DBNull) return false;
            if (obj == null) return false;
            var m = (Apontamento) obj;
            return m.Ordem == _ordem;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
2º Criei uma função para ler os dados do arquivo CSV e passar os valores para uma lista de Apontamentos:
 private IList getApontamentosByFileCSV(string pathFile)
        {
            try
            {
                IList apos = new List();

                if (!File.Exists(pathFile))
                {
                    MessageBox.Show("O arquivo de Apontamento não foi encontrado.");
                    return new List();
                }
                StreamReader rd = new StreamReader(pathFile, Encoding.Default);
                try
                {
                    var count = 0;
                    while (!rd.EndOfStream)
                    {
                        count++;
                        var linha = rd.ReadLine();
                        if (count == 1) continue;
                        if (string.IsNullOrEmpty(linha)) continue;

                        var colunas = linha.Split(';');
                        Apontamento iten = new Apontamento();
                        iten.Ordem = colunas[0];
                        iten.Recurso = colunas[1];
                        iten.Status = colunas[2];
                        iten.DataDeInicio = parseDate(colunas[3]);
                        iten.DataDeFim = parseDate(colunas[4]);

                        apos.Add(iten);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                  rd.Close();  
                }


                return apos;
            }
            catch (Exception ex)
            {
                throw new Exception("Falha ao recuperar os dados do arquivo CSV:" + Environment.NewLine + ex.Message);
            }
        }
3º Criei um método que faz a comunicação com o Preactor, recebe a lista de apontamentos baseado no arquivo CSV e grava na tabela do Preactor:
OBS: a diferença entre este novo método e o OláMundo (Run) é um novo parâmetro que foi adicionado a função, "ref string arquivo". Eu achei essa forma mais simples configurar o nome e local onde o arquivo csv se encontra, mas você poderia também ter deixa o caminho e nome do arquivo fixos em seu projeto, ok?


 public int ImportApontamento(ref PreactorObj preactorComObject, ref object pespComObject, ref string arquivo)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);
            try
            {
                //RECUPERAR OS DADOS DO ARQUIVO CSV
                IList itens = getApontamentosByFileCSV(arquivo);
                if (itens.Count == 0) return 0;

                //LIMPAR TABELA DE APONTAMENTOS
                preactor.Clear("Apontamento");

                preactor.DisplayStatus("Apontamentos","Importando arquivos de apontamentos.");
                var count = itens.Count;
                var i = 0;
                preactor.UpdateStatus(i, count);
                //INSERIR O GRUPO DE REGISTROS
                foreach (var iten in itens)
                {
                    i++;
                    preactor.UpdateStatus(i, count);
                    //CRIAR UM NOVO REGISTRO NA TABELA DE APONTAMENTOS
                    int record = preactor.CreateRecord("Apontamento");

                    //ESCREVER NA TABELA APONTAMENTOS
                    preactor.WriteField("Apontamento", "Ordem", record, iten.Ordem);
                    if (!string.IsNullOrEmpty(iten.Recurso))
                        preactor.WriteField("Apontamento", "Recurso", record, iten.Recurso);
                    if (!string.IsNullOrEmpty(iten.Status))
                        preactor.WriteField("Apontamento", "Status", record, iten.Status);
                    if (iten.DataDeInicio != DateTime.MinValue)
                        preactor.WriteField("Apontamento", "Data de Início", record, iten.DataDeInicio);
                    if (iten.DataDeFim != DateTime.MinValue)
                        preactor.WriteField("Apontamento", "Data de Fim", record, iten.DataDeFim);
                }
                preactor.DestroyStatus();
                //VAMOS SALVAR OS DADOS NA TABELA DO PREACTOR
                preactor.Commit("Apontamento");
                MessageBox.Show("Seus dados foram importados com sucesso!");
            }
            catch (Exception ex)
            {
                preactor.DestroyStatus();
                MessageBox.Show("Falha ao importar os Apontamentos:" + Environment.NewLine + ex.Message);
            }

            return 0;

        }
4º Criei um botão no arquivo de configuração prmdf, já fizemos isso no olá mundo.


5º Cadastrei a ação dentro do Preactor conforme a ação Olá Mundo, acompanhe o passo a passo:

clique em Editar
Clique em "Novo Registro" em seguida "Adicionar->", digite o nome "arquivo" E clique Ok


Vá para o Menu Script de Eventos => Script de Eventos


Clique em "Parameters.."

Clique Sobre o nome "arquivo"


No campo "File Name", adicione o caminho e o nome do arquivo que iremos importar

6º Vamos Testar nossa ação, vá no Visual Studio e aparte a tecla de atalho "F5", e vamos debugar nosso código:



Com isso encerramos nosso primeiro WorkShop, não detalhei as ações pois elas são bem simples, igual uma receita de bolo, basta seguir o passo-a-passo que não tem erro.

Se houver algum dúvida sobre esse workshop me escreva besaleel@msn.com ou faça um comentário aqui no blog que responderei o mais breve possível.

Se preferir faça o download da solução completa do WorkShop 01.

PARTE 2 -Manipulando dados do Preactor - Treinamento Preactor

Nessa segunda parte do treinamento iremos aprender a ler e escrever dados nas tabelas do Preactor utilizando a API do Preactor. Para essa parte do treinamento eu preciso que você faça download do modelo que iremos utilizar, para isso clique aqui.

Faça Download do arquivo "Preactor.prtdf" e o coloque na pasta do modelo que estamos trabalhando (C:\Users\Public\Documents\Preactor Configurations\Preferred Sequence (400 & 500 APS) v11.2).

O que há de diferente nesse arquivo é uma nova tabela que foi criada de nome Apontamento, ela possui a seguinte estrutura:
Apontamento,,0,600:
   Number,0,INTEGER,
      PRIMARY KEY
      HIDDEN:
   Ordem,"",STRING,
      FREE FORMAT (30):
   Recurso,"",STRING,
      FREE FORMAT (30):
   Status,"1",STRING,
      FREE FORMAT (30):
   Data de Início,-1,TIME,
      SHOW DATE:
   Data de Fim,-1,TIME,
      SHOW DATE:
   Import Marker,-1,INTEGER,
      DIALOG LEVEL 99
      DIALOG ONLY
      READ ONLY
      IMPORT MARKER;


O que podemos aprender ao ver o código da tabela:

Cabeçalho: "Apontamento,,0,600:"
Table: Apontamento
Total de Registros permitido pela tabela: 600
Fields: Number, Ordem, Recurso, Status, Data de Início, Data de Fim, Import Marker;

Iremos utilizar essas informações para podermos ler e gravar dados na tabela Apontamento.

Abra o Preactor para que as alterações do arquivo "preactor.prtdf" sejam incorporadas ao modelo.

Clique em sim.



Criando um novo registro, lendo e escrevendo dados no Preactor

Esse nosso primeiro contato com o API da Preactor será em torno de três funções básicas que são responsáveis por grande parte de nosso trabalho ao customizar um software, Ler dados, escrever e Criar novos registros. 

A sintaxe é bem simples, vejam os código logo abaixo:

public int Run(ref PreactorObj preactorComObject, ref object pespComObject)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);
            
            //CRIAR UM NOVO REGISTRO NA TABELA DE APONTAMENTOS
            int record = preactor.CreateRecord("Apontamento");
            
            //ESCREVER NA TABELA APONTAMENTOS
            preactor.WriteField("Apontamento", "Ordem", record, "ORD-001");
            //obs:
            //A Função WriteField possui 4 parametros básicos
            // 1º - Tabela, 
            // 2º - Campo da tabela(Field), 
            // 3º - Numero do Registro, 
            //4 - Valor que vamos escrever no banco de dados

            preactor.WriteField("Apontamento", "Recurso", record, "Packing Line 2");
            preactor.WriteField("Apontamento", "Status", record, "Iniciada");
            preactor.WriteField("Apontamento", "Data de Início", record, new DateTime(2000,10,01,11,00,00));
            preactor.WriteField("Apontamento", "Data de Fim", record, new DateTime(2000, 10, 01, 12, 30, 00));
            //OBSERVAÇÃO, OS CAMPOS Number, e Import Marker são de uso do Preactor, 
            //não precisamos preencher esses campos;

            //VAMOS SALVAR OS DADOS NA TABELA DO PREACTOR

            preactor.Commit("Apontamento");
            return 0;
        }



Para ler os dados Gravados na tabela iremos utilizar duas funções, uma para contar o número total de registros da tabela e a outra para ler os dados da tabela.
  public int Lendo(ref PreactorObj preactorComObject, ref object pespComObject)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);

            //CRIAR UM NOVO REGISTRO NA TABELA DE APONTAMENTOS
            int count = preactor.RecordCount("Apontamento");

            IList ordens = new List();
            //VAMOS LER TODAS AS ORDENS E GRAVAR SEU VALOR NA LISTA
            for (int record = 1; record <= count; record++)
            {
                //VAMOS LER OS DADOS DA TABELA (parametros: tabela, campo, número do registro)
                string ordem = preactor.ReadFieldString("Apontamento", "Ordem", record);
                ordens.Add(ordem);
                //OS DADOS SÃO SALVOS DE FORMA SEQUENCIAL, MESMO EXCLUINDO
                //UM REGISTRO DO MEIO DA FILA, A FILA É REORDENADA
                //NÃO DEIXANDO BURRACOS

            }
            MessageBox.Show("O número de registros lidos:" + ordens.Count());
            return 0;
        }



Outras funções de Manipulação de dados:


public void DeletarRegistro(IPreactor preactor, int record)
{
            //EXCLUI UM ÚNICO REGISTRO
            preactor.DeleteRecord("Apontamento", record);

            //PARA LIMPAR A TABELA EXCLUINDO TODOS OS REGISTROS
            preactor.Clear("Apontamento");
}


Mas para frente abordaremos como busca uma string dentro de um campo de uma tabela.



WorkShop 01


Faça uma função que importe um arquivo CSV (download arquivo CSV ) de apontamentos, e salve os dados na tabela "Apontamento" do Preactor. Mas antes de salvar limpe sempre a tabela.

tente fazer o workshop sem olhar a resposta (workShop 01)