Página 1 de 1

SPED PIS COFINS sem mistério.

Enviado: 01 Fev 2013 02:10
por rochinha
Amiguinhos,

Para me ajudar a desenhar e manter as funções para o tratamento dos registros do SPED PIS/COFINS, criei a tabela PISCO.DBF que tem todos os registros e torna fácil a alteração ou inclusão de campos.

download

Ao executar o programa ele irá gerar o codigo fonte necessário para o trabalho pesado.

A saber:

PISCOT.txt - Funcoes para geracao das tabelas/registro com campos
PISCOTC.txt - Funcoes para geracao de todas as tabelas em demanda
PISCOS.txt - Funcoes para geracao do salvamento de dados de cada registro
PISCOR.txt - Funcoes para geracao das linhas formatadas
PISCORG.txt - Funcoes para geracao do conteudo do arquivo digital

Uma biblioteca poderá ser gerada para manter os arquivos acima, já que deverão ser ligados ao corpo principal da geração do arquivo digital.

O corpo principal deverá iniciar mais ou menos como a seguir:

Código: Selecionar todos

FUNCTION GeraSPEDPisCofins(cPath,dDATAINI,dDATAFIM)
   public cPath := "c:\sistema"
   public SPEDPath := "c:\sistema\sped"
   public SPEDFile := "spedpc.txt"

   dbCloseAll()
   // Gera todas as tabelas de registros
   GeraPISCOTabelas()
   dbCloseAll()

   // Abre tabelas acessorias necessarias
   USE &(cPath+"\IBGE")     SHARED NEW INDEX &(cPath+"\IBGE")
   USE &(cPath+"\CLIENTES") SHARED NEW INDEX &(cPath+"\CLIENTES")
   USE &(cPath+"\FORNEC")   SHARED NEW INDEX &(cPath+"\FORNEC")
   USE &(cPath+"\PEDIDOS")  SHARED NEW INDEX &(cPath+"\PN")
   USE &(cPath+"\ITENS")    SHARED NEW INDEX &(cPath+"\ES")
   USE &(cPath+"\UNIDADES") SHARED NEW INDEX &(cPath+"\UNIDADES")
   USE &(cPath+"\NATUREZA") SHARED NEW INDEX &(cPath+"\NATUREZA")

   USE &(SPEDPath+"\R9001") SHARED NEW
   USE &(SPEDPath+"\R9900") SHARED NEW
   USE &(SPEDPath+"\R9990") SHARED NEW
   USE &(SPEDPath+"\R9999") SHARED NEW

   // Monta blocos
   GeraPISCOBloco0()
   GeraPISCOBlocoA()
   GeraPISCOBlocoC()
   GeraPISCOBlocoD()
   GeraPISCOBlocoF()
   GeraPISCOBlocoM()
   GeraPISCOBlocoP()
   GeraPISCOBloco1()
   GeraPISCOBloco9()

   SPEDhandle := fCreate( SPEDFile )

   GeraPISCORegistros(SPEDhandle)

   fClose( SPEDhandle )
   
   return .t.
Parte do coração do gerador, geracao do Bloco 0:

Código: Selecionar todos

FUNCTION GeraPISCOBloco0()
   ******************************************************************************************************
   ******************************************************************************************************
   // BLOCO 0: ABERTURA, IDENTIFICAÇÃO E REFERÊNCIAS.
   ******************************************************************************************************
   ******************************************************************************************************
   USE &(SPEDPath+"\R0000") SHARED NEW
   USE &(SPEDPath+"\R0001") SHARED NEW
   USE &(SPEDPath+"\R0100") SHARED NEW
   USE &(SPEDPath+"\R0110") SHARED NEW
   USE &(SPEDPath+"\R0111") SHARED NEW
   USE &(SPEDPath+"\R0140") SHARED NEW
   USE &(SPEDPath+"\R0150") SHARED NEW
   USE &(SPEDPath+"\R0190") SHARED NEW
   USE &(SPEDPath+"\R0200") SHARED NEW
   USE &(SPEDPath+"\R0205") SHARED NEW
   USE &(SPEDPath+"\R0206") SHARED NEW
   USE &(SPEDPath+"\R0208") SHARED NEW
   USE &(SPEDPath+"\R0400") SHARED NEW
   USE &(SPEDPath+"\R0450") SHARED NEW
   USE &(SPEDPath+"\R0500") SHARED NEW
   USE &(SPEDPath+"\R0600") SHARED NEW
   USE &(SPEDPath+"\R0990") SHARED NEW

   // ************************ INICIO DA CRITICA DE GERACAO DE BLOCO ************************ //
   // Hierarquia
   /*   1   2   3   4
	R0000						
        R0001					
			R0100				
			R0110				
				R0111			O (se no registro 0110 o Campo “COD_INC_TRIB” = 1 ou 3 e o Campo “IND_APRO_CRED” = 2) N (se no registro 0110 o Campo “COD_INC_TRIB” = 2 ou o Campo “IND_APRO_CRED” = 1)
			R0140				
				R0150			
				R0190			
				R0200			
					R0205		
					R0206		
					R0208		
				R0400			
				R0450			
			R0500				
			R0600				
		R0990					
   */
   
   ******************************************************************************************************
   * Carrega as variaveis que serão imputadas na tabela pela função PISCOSalvaR0000()
   * Formato da linha que sera gerada pela função PISCORegistroR0000
   // |0000|002|0|0||01012012|31012012|LIMPEZA E CONSERVACAO PEMA LTDA|03040285000182||4107207||00|2|
   M->REG              := '0000'   // 01 - Texto fixo contendo ?0000?.
   M->COD_VER          := '002'    // 02 - Código da versão do leiaute conforme a tabela 3.1.1.
   M->TIPO_ESCRIT      := '0'      // 03 - Tipo de escrituração:
                                   //    0 - Original;
                                   //    1 – Retificadora.
   M->IND_SIT_ESP      := '0'      // 04 - Indicador de situação especial:
                                   //    0 - Abertura
                                   //    1 - Cisão
                                   //    2 - Fusão
                                   //    3 - Incorporação
                                   //    4 – Encerramento
   M->NUM_REC_ANTERIOR := ''       // 05 - Número do Recibo da Escrituração anterior a ser retificada, utilizado quando TIPO_ESCRIT for igual a
   M->DT_INI           := CharRem( '/', DtoC( dDATAINI ) ) // 06 - Data inicial das informações contidas no arquivo.
   M->DT_FIN           := CharRem( '/', DtoC( dDATAFIM ) ) // 07 - Data final das informações contidas no arquivo.
   M->NOME             := ClNome   // 08 - Nome empresarial da pessoa jurídica
   M->CNPJ             := CharRem( './-', ClCNPJ )  // 09 - Número de inscrição do estabelecimento matriz da pessoa jurídica no CNPJ.
   M->UF               := ClUF     // 10 - Sigla da Unidade da Federação da pessoa jurídica.
   M->COD_MUN          := ClCodMun // 11 - Código do município do domicílio fiscal da pessoa jurídica, conforme a tabela IBGE
   M->SUFRAMA          := ''       // 12 - Inscrição da pessoa jurídica na Suframa
   M->IND_NAT_PJ       := '00'     // 13 - Indicador da natureza da pessoa jurídica:
                                   //    00 – Sociedade empresária em geral
                                   //    01 – Sociedade cooperativa
                                   //    02 – Entidade sujeita ao PIS/Pasep exclusivamente com base na Folha de Salários
   M->IND_ATIV         := '0'      // 14 - Indicador de tipo de atividade preponderante:
                                   //    0 – Industrial ou equiparado a industrial;
                                   //    1 – Prestador de serviços;
                                   //    2 - Atividade de comércio;
                                   //    3 – Atividade financeira;
                                   //    4 – Atividade imobiliária;
                                   //    9 – Outros
   * Salva o registro R0000 com dados das variáveis acima
   PISCOSalvaR0000() // REGISTRO 0000: ABERTURA DO ARQUIVO DIGITAL E IDENTIFICAÇÃO DA PESSOA JURÍDICA
   ******************************************************************************************************


   cEstado             := 'SP'
   cCidade             := 'SAO PAULO'

   
   ******************************************************************************************************
   * Carrega as variaveis que serão imputadas na tabela pela função PISCOSalvaR0001()
   * Formato da linha que sera gerada pela função PISCORegistroR0001
   // |0001|0|
   M->REG              := '0001'   // 01 - Texto fixo contendo ?0001?.
   M->IND_MOV          := '0'      // 02 - Indicador de movimento
                                   //    0 - Bloco com dados informados;
                                   //    1 - Bloco sem dados informados
   * Salva o registro R0001 com dados das variáveis acima
   PISCOSalvaR0001() // REGISTRO 0001: ABERTURA DO BLOCO 0
   ******************************************************************************************************

   IF M->IND_MOV = '0'
      /* *********** INICIO DOS REGISTROS DO BLOCO *********** */

      // |0100|Nome do contabilista|00000000000|Numero de Inscr|00000000000000|0|Logradouro e Endereço do Imóvel|Numero do Imovel|Dados Complementares do Endereco|Bairro em que o Imovel esta Situado|Numero do|Numero do|Endereço do Correio Eletronico|0|
      ...
      PISCOSalvaR0100() // REGISTRO 0100: DADOS DO CONTABILISTA
      ******************************************************************************************************

      // |0110|2|2|1|
      ...
      PISCOSalvaR0110() // REGISTRO 0110: REGIMES DE APURAÇÃO DA CONTRIBUIÇÃO SOCIAL E DE APROPRIAÇÃO DE CRÉDITO
      ******************************************************************************************************

      ...
      /* *********** FINAL DOS REGISTROS DO BLOCO *********** */
   ENDIF // IF M->IND_MOV = '0'
   
   // ************************ INICIO DA CRITICA DE GERACAO DE BLOCO ************************ //

   ******************************************************************************************************
   * Gera registro finalizador deste bloco
   // |0990|11|
   M->REG                  := '0990' // 01 - Texto fixo contendo "0990"
   M->REG_BLC              := '0990' // 01 - Texto fixo contendo "0990"
   M->QTD_LIN_0            := '1' // 02 - Quantidade total de linhas do Bloco 0

   * Salva o registro R0990
   PISCOSalvaR0990() // ENCERRAMENTO DO BLOCO 0
   ******************************************************************************************************

   return .t.
   ******************************************************************************************************
Acima foi exemplificado somente o bloco inicial, já que cada um deverá gerar o mesmo baseado na estrutura de seus arquivos de suporte.

Abaixo um exemplo das funções finalizadoras:

Código: Selecionar todos

FUNCTION GeraPISCOBloco9()
   ******************************************************************************************************
   ******************************************************************************************************
   // BLOCO 9: CONTROLE E ENCERRAMENTO DO ARQUIVO DIGITAL
   ******************************************************************************************************
   ******************************************************************************************************
   //USE &(SPEDPath+"\R9001") SHARED NEW
   //USE &(SPEDPath+"\R9900") SHARED NEW
   //USE &(SPEDPath+"\R9990") SHARED NEW
   //USE &(SPEDPath+"\R9999") SHARED NEW
   /*   1   2
		R9001	
			R9900
		R9990	
	R9999		
   */
   // 
   M->REG                  := '9001' // 01 - Texto fixo contendo ?9001?.
   M->IND_MOV              := '0' // 02 - Indicador de movimento:
                       // 0 - Bloco com dados informados;
                       // 1 - Bloco sem dados informados
   PISCOSalvaR9001() // ENCERRAMENTO DO BLOCO 1
   ******************************************************************************************************

   // 
   M->REG                  := '9900' // 01 - Texto fixo contendo ?9900?.
   M->REG_BLC              := '9900' // 02 - Registro que será totalizado no próximo campo.
   M->QTD_REG_BLC          := '' // 03 - Total de registros do tipo informado no campo anterior.
   //
   dbSelectArea('R9900')
   M->QTD_REG_BLC := str(recco() + 1 + 2) // Somei 1 porque entra os registros 9990/9999
   //
   PISCOSalvaR9900() // REGISTROS DO ARQUIVO
   ******************************************************************************************************

   // 
   dbSelectArea('R9900')
   R9900->( dbAppend() )
   R9900->CAMPO01      := '9900' // 01 - Texto fixo contendo ?9900?.
   R9900->CAMPO02      := '9990'                  // 02 - Registro que será totalizado no próximo campo.
   R9900->CAMPO03      := '1'                     // 03 - Total de registros do tipo informado no campo anterior.
   R9900->( dbCommit() )
   //
   M->REG              := '9990' // 01 - Texto fixo contendo ?9990?.
   M->QTD_LIN_9        := '' // 02 - Quantidade total de linhas do Bloco 9.
   PISCOSalvaR9990() // ENCERRAMENTO DO BLOCO 9
   ******************************************************************************************************

   // 
   dbSelectArea('R9900')
   R9900->( dbAppend() )
   R9900->CAMPO01      := '9900' // 01 - Texto fixo contendo ?9900?.
   R9900->CAMPO02      := '9999'                  // 02 - Registro que será totalizado no próximo campo.
   R9900->CAMPO03      := '1'                     // 03 - Total de registros do tipo informado no campo anterior.
   R9900->( dbCommit() )
   //
   M->REG              := '9999' // 01 - Texto fixo contendo ?9999?.
   M->QTD_LIN          := alltrim(str(MLCount(MemoRead(SPEDFile),500))) // 02 - Quantidade total de linhas do arquivo digital.
   PISCOSalvaR9999() // ENCERRAMENTO DO ARQUIVO DIGITAL
   ******************************************************************************************************
   return .t.
   ******************************************************************************************************

STATIC FUNCTION PISCOSalvaR9001()
   // *** Estrutura do Registro R9001 ***
   R9001->( dbAppend() )
   R9001->CAMPO01      := '9001' // 01 - Texto fixo contendo ?9001?.
   R9001->CAMPO02      := M->IND_MOV              // 02 - Indicador de movimento:
   R9001->( dbCommit() )
   //
   M->AREA9001 := Select()
   M->REG_BLC := '9001'
   M->QTD_LIN_9 := ''
   M->QTD_REG_BLC := '1'
   dbSelectArea('R9900')
   PISCOSalvaR9900()
   dbSelectArea('R9990')
   PISCOSalvaR9990()
   dbSelectArea(M->AREA9001)
   RETURN nil

FUNCTION PISCOSalvaR9900()
   // *** Estrutura do Registro R9900 ***
   locate for (R9900->CAMPO02 = M->REG_BLC)
   if .not. found()
      M->QTD_REG_BLC := '1'
      R9900->( dbAppend() )
   else   
      if M->REG_BLC = "0990" .or. M->REG_BLC = "A990" .or. M->REG_BLC = "C990" .or. M->REG_BLC = "D990" .or. ;
         M->REG_BLC = "F990" .or. M->REG_BLC = "M990" .or. M->REG_BLC = "1990"
         M->QTD_REG_BLC := '1'
      else      
         M->QTD_REG_BLC := alltrim(str(val(R9900->CAMPO03) + 1,6))
      endif   
      R9900->( dbRLock() )
   endif   
   R9900->CAMPO01      := '9900' // 01 - Texto fixo contendo ?9900?.
   R9900->CAMPO02      := M->REG_BLC              // 02 - Registro que será totalizado no próximo campo.
   R9900->CAMPO03      := alltrim(M->QTD_REG_BLC) // 03 - Total de registros do tipo informado no campo anterior.
   R9900->( dbCommit() )
   //
   nR9900 := recco()
   locate for (R9900->CAMPO02 = '9900')
   if .not. found()
      R9900->( dbAppend() )
   else   
      R9900->( dbRLock() )
   endif
   R9900->CAMPO01      := '9900' // 01 - Texto fixo contendo ?9900?.
   R9900->CAMPO02      := '9900' // 02 - Registro que será totalizado no próximo campo.
   R9900->CAMPO03      := alltrim(str(nR9900+2,6)) // 03 - Total de registros do tipo informado no campo anterior.
   R9900->( dbCommit() )
   //
   M->AREA9900 := Select()
   //M->REG_BLC := '9900'
   M->QTD_LIN_9 := ''
   M->QTD_REG_BLC := '1'
   dbSelectArea('R9990')
   PISCOSalvaR9990()
   dbSelectArea(M->AREA9900)
   RETURN nil

STATIC FUNCTION PISCOSalvaR9990()
   // *** Estrutura do Registro R9990 ***
   dbSelectArea('R9900')
   nR9990 := recco()
   M->QTD_LIN_9 := alltrim(str(nR9990+1+2,6)) // Somei 2 porque entra os registros 9990
   dbSelectArea('R9990')
   if recco() = 0
      R9990->( dbAppend() )
   else
      R9990->( dbRLock() )
   endif   
   R9990->CAMPO01      := '9990'              // 01 - Texto fixo contendo ?9990?.
   R9990->CAMPO02      := M->QTD_LIN_9        // 02 - Quantidade total de linhas do Bloco 9.
   R9990->( dbCommit() )
   RETURN nil

STATIC FUNCTION PISCOSalvaR9999()
   // *** Estrutura do Registro R9999 ***
   R9999->( dbAppend() )
   R9999->CAMPO01      := '9999'              // 01 - Texto fixo contendo ?9999?.
   R9999->CAMPO02      := M->QTD_LIN          // 02 - Quantidade total de linhas do arquivo digital.
   R9999->( dbCommit() )
   //
   M->AREA9999 := Select()
   M->REG_BLC := '9999'
   M->QTD_LIN_9 := ''
   M->QTD_REG_BLC := ''
   dbSelectArea('R9990')
   PISCOSalvaR9990()
   dbSelectArea(M->AREA9999)
   RETURN nil
Como poderão ver, eu achei esta ser a forma mais simples de se trabalhar com os tantos registros deste ambiente.

Espero que sirva de idéia.

SPED PIS COFINS sem mistério.

Enviado: 02 Fev 2013 11:55
por paiva_dbdc
BOM dia. Desculpe NAo entendi.

ESta gerando ou e´ Uma idéia ?

descuple aproveitar o espaço.
EU gero o sped fiscal e o Pis/cofisn em UM so prg. os 2 usam a mesma base de trabalho,

Estou precisando Fazer agora uma forma de gerar a partir dos xml de entrada e saida para ATENDER 2 clientes (contadores)

SE alguem que ler e se interessar estaria disposto ate a remunerar.

tenho no sistema um prg de NFE onde digitam a CAPA e os Itens de entrada. + tenho uma Opcao (tecla) que abre uma caixa e seleciona um XML ai ele JA gera o reg do fornecedor a capa e os Itens de entrada e se quizer OS produtos NAo encontrados. (acredito se ao inves de UM pegar TODOS (tenho um prg que uso para ALTERAR prgs el ele todos os prg a partir de uma MASCAR tipo *.prg) e PAra facilitar no inicio dar ZAP nas bases ) ai ficaria simples e JA atenderia as entradas.

Bastaria aproveitar o prg para fazer o mesmo com os xml de entrada

BOM Vejamos ? porque EU mesmo Não faço ?

1 - ja to com 60 Anos e a MEMORIA nao anda la muito bem . e PRINCIPALMENTE sou MUITO fraco em FUçar, PERCO muito tempo para fazer/testar uma coisa nova.
2- Trabalho sozinho e atendo a Comercio, Inustria, mat contr, eletrico, loja de roupa , Oficina Mecanica c/ loja tintas etc etc ALEM de Contabiliade, Folha, Livros e Patrimonio.
3 - Sped fiscal, Pis/cofins, Manad, Dirf, Rais , fgts etc etc
4 NAO aguento + se trabalha 80% do tempo para GOVERNO Incompetente

5 - Trabalho desde 1972 como programador e de 80para ca como analista e SEMPRE programando , Principalemte depois d 81 que sempre tive empresa paralela como softHouse.
se notaram troco as letras do teclado os DEDOS ja nao acompanham + o reciocionio e tenho qu eescrever e voltar depois para ler o que ficou errado (rs)

NAO tenho ciume dos sistemas SEDO par aqq um que ajude, DESDE que nao seja meu concorrente direto (rs)

Trabalhei un 7 anos com FWH logo qu elançaram ele depois LARGUEI. (apos uns ano resolvi investi em gestao agricola e apos uns BONS anos NAo consegui cleinte (NAo querem pagar Manutencao)) ai larguei o FWH , peguei um sistema antigo e converti para WVW com opcao TEXTO e Grafico. e´o que uso ATUALMENTE em todos meus cleintes.

Por algum Motivo ficou alguns comandos em Fwh (por iso uso a LIB fwh) ate hoje para LINKAR
uso um prg em Hwgi (comprei) e´um preview e depois Melhorei algumas coisas algumas ele ja tinha ou talvez a maioria atualmente ele exibe o relatorio , aumenta, diminui, imprime na padrao ou seleciona impressoras, gera html, pdf, word e um outro tipo word (free), abre com editor, Filtra paginas, Permite altear e salvar o relatoro etc etc


se essa sua ideia ja estiver em producao e PUDER fazer o que precisao (a partir do sxml) , gostaria de saber +

desde ja agreço

PAiva

SPED PIS COFINS sem mistério.

Enviado: 15 Fev 2013 22:18
por rochinha
Amiguinho,
ESta gerando ou e´ Uma idéia ?

descuple aproveitar o espaço.
EU gero o sped fiscal e o Pis/cofisn em UM so prg. os 2 usam a mesma base de trabalho,

Estou precisando Fazer agora uma forma de gerar a partir dos xml de entrada e saida para ATENDER 2 clientes (contadores)

SE alguem que ler e se interessar estaria disposto ate a remunerar.
Gero o arquivo com os registros que meu cliente necessita, apesar de que o arquivo de layout possui todos os registros inclusive os novos 120 e Bloco I.

Agora falando sobre gerar diretamente do XML, sua ideia me soa muito legal, porque os mesmos arquivos de movimento usados nos meus geradores SPED são usados pela rotina de leitura dos XML.

pergunta: Como está sua andança.

SPED PIS COFINS sem mistério.

Enviado: 04 Jun 2013 13:06
por rochinha
Amiguinhos,

O link de download foi revitalizado,