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 ReturnTalvez o código possa ficar menor, não sei, mas deste jeito funcionou muito bem comigo. Caso conheça outra forma, compartilhe...