Importar um arquivo texto para o Orçamento (MATA415)


Já tentou importar um arquivo texto para a rotina de orçamento? É uma tristeza só, a rotina de orçamento utiliza uma tabela temporária chamada TMP1 e por conta disso temos algumas pequenas dificuldades em suas validações. Mas com um certo jeitinho, conseguimos driblar e resolver os problemas do dia a dia com esta rotina. Hoje, irei mostrar umas das formas de importar um arquivo texto para o orçamento, não irei postar todo o código, mas a parte que mais interessa, que é a do preenchimento do grid. Mas antes veja o artigo Importando arquivo texto, agora que já está familiarizado, vamos no que interessa. Considerando um arquivo texto com duas colunas, sedo a primeira com o código do produto e a segunda com a quantidade.

Static Function Importar(cArquivo)
	/*declare suas variaveis*/
	Local nItem      := 0
        Local aStrutTMP1 := {}

	/*coloque aqui seu código para importar o arquivo texto e depois armazena-lo num array*/

	aAreaTMP1 := GetArea()
	TMP1->(Dbgotop())

        //A ideia é saber quantas linhas temos no grid, em caso de uma alteração
	While TMP1->(!EOF())
		nItem++
		TMP1->(dbskip())
	End

	aStrutTMP1 := dbStruct()
	
	//Preenche a grid com os dados
	If nItem==1
		cItem := "00"
	else
		cItem := TMP1->CK_ITEM
	endif

        //Supondo que você preencheu o array aLinhas com o conteudo do arquivo
        //sendo CODIGO;QUANTIDADE //aLinha[n,1];aLinha[n,2]
        //Percorremos todo o array
	For nI := 1 TO LEN(aLinhas)	
		If nI == 1 
			If nItem==1 //se tiver algum registro adiciono mais um
				TMP1->(DBGOTO(nITEM+1)) 
			Else
				TMP1->(DBGOTO(nITEM))  
				lAux:=.T.
			Endif                    
			cItem := TMP1->CK_ITEM
                        //Quando estamos no modo de inclusão, a rotina de orçamento não deixa os 
                        //campos do grid em memoria, para isso é preciso pular uma linha e começar a partir da segunda
			oGetDad:AddLine()
		EndIf
		
		nItem++
		cItem := soma1(cItem)
		
		dbSelectArea("TMP1")
              	RecLock("TMP1",.F.)
				
		TMP1->CK_ITEM    := cItem
		TMP1->CK_PRODUTO := aLinhas[nI][1]
		TMP1->CK_QTDVEN  := aLinhas[nI][2]
		TMP1->CK_VALOR   := TMP1->CK_QTDVEN * TMP1->CK_PRCVEN


		aAreaTMP1 := GetArea()
		A093Prod(.T.,TMP1->CK_PRODUTO,TMP1->CK_PRODUTO,.T.)
		
		//Valida o código do produto
		If !A415Prod(TMP1->CK_PRODUTO)
			aadd(aItensErro,{TMP1->CK_ITEM,TMP1->CK_PRODUTO})
		EndIf		

		If ExistTrigger("CK_PRODUTO")
			RunTrigger(2,nItem,Nil,,"CK_PRODUTO")
		Endif                                               
		
		M->CK_PRCVEN	:= TMP1->CK_PRCVEN	
		M->CK_QTDVEN 	:= aLinhas[nI][2]
		TMP1->CK_QTDVEN := M->CK_QTDVEN  		
		M->CK_VALOR  	:= M->CK_QTDVEN * M->CK_PRCVEN
		TMP1->CK_VALOR  := TMP1->CK_QTDVEN * TMP1->CK_PRCVEN				                    
		M->CK_ENTREG  	:= dEntrega
		//Inicializa as Variaveis
		For nA := 1 to Len(aStrutTMP1)
			cVariavel := 'M->'+astrutTMP1[nA][1]
			xConteudo := FieldGet(nA)
			Private &cVariavel:= xConteudo
		Next
		
		DbSelectArea('TMP1')
                //reforço as informações nas variaveis de memoria
		For nA := 1 to Len(aStrutTMP1)
			cVariavel := 'M->'+astrutTMP1[nA][1]
			xConteudo := &cVariavel
			FieldPut(nA,xConteudo)
		Next                            
		
		M->CK_VALOR  	:= M->CK_QTDVEN * M->CK_PRCVEN
		TMP1->CK_VALOR  := TMP1->CK_QTDVEN * TMP1->CK_PRCVEN
	    
      	        TMP1->(MsUnLock())
        
	        if nI<LEN(aLinhas) 
			oGetDad:AddLine()  //adiciono uma linha, com esta linha eu coloco o grid na memoria 
		endif
		oGetDad:Refresh()  //atualizo o grid
	Next nI

	IF lAux    
		oGetDad:AddLine()   
		oGetDad:Refresh() 
	ENDIF
	
	nBrLin := nItem + 1
	oGetDad:nCount := nItem + 1
	oGetDad:ForceRefresh()
	
	IF lAux==.F.
	       TMP1->(DBGOTOP())
	ENDIF	
Return
Talvez o código possa ficar menor, não sei, mas deste jeito funcionou muito bem comigo. Caso conheça outra forma, compartilhe...