01. VISÃO GERAL
Caso exista a necessidade de aumentar o tamanho dos campos que estão contidos no grupo (SXG) 134 - Sequencia de baixa, é necessário que seja executado o RDMAKE abaixo para que o conteúdo destes campos seja ajustado para o novo tamanho, evitando assim a duplicidade de sequencias para o mesmo registro, o que pode ocasionar não conformidades no produto.
Este RDMAKE tem como objetivo ajustar o conteúdo destes campos adicionando '0' a esquerda.
Exemplo:
- Antes da alteração o conteúdo do campo E5_SEQ estava com '02'
- Houve a necessidade de aumentar o tamanho deste campo para 4
- Após rodar o RDMAKE o conteúdo que será gravado é esse '0002'
02. EXEMPLO DE UTILIZAÇÃO
O Rdmake foi desenvolvido através do que foi especificado na "Visão geral", sendo disponibilizada a correção somente para este cenário. Caso seja encontrado outros cenários a função de usuário está disponível nesta documentação para personalização. IMPORTANTE!
Como utilizar:
Sugerimos que a execução seja feita primeiramente em um ambiente de homologação e, somente após ser validado, executar em um ambiente de produção.
- Realize um backup da base de dados
- Copiar o exemplo do RDMAKE abaixo e compilar no ambiente a ser processado
- No programa inicial no SmartClient, preencha "U_FIXSEQBX" e clique em "OK"
- Seguir o passo a passo do Wizard que será apresentado
- Aguardar o processamento das atualizações
RDMAKE #include "protheus.ch" #include "totvs.ch" User Function FIXSEQBX() MsApp():New( "SIGAFIN" ) oApp:cInternet := Nil __cInterNet := NIL oApp:bMainInit := { || ( oApp:lFlat := .F. , WizardSeq() , FnQuit(oApp) ) } oApp:CreateEnv() OpenSM0() PtSetTheme( "TEMAP10" ) SetFunName( "FIXSEQBX" ) oApp:lMessageBar := .T. oApp:Activate() Return Nil Static Function WizardSeq() Local oWizard As Object Local aBrowse As Array Static __TmpTbl As Object __TmpTbl := NIL aBrowse := {} oWizard := FwWizardControl():New() oWizard:ActiveUISteps() //---------------------------- // Pagina 1 - Apresentação //---------------------------- o1stPage := oWizard:AddStep("1STSTEP",{|Panel| cria_pn1(Panel)}) o1stPage:SetStepDescription("Apresentação") o1stPage:SetNextTitle("Avançar") o1stPage:SetNextAction({||.T.}) o1stPage:SetCancelAction({||.T.}) //--------------------------------------- // Pagina 2 - Escolha do grupo de empresas //--------------------------------------- o2ndPage := oWizard:AddStep("2RDSTEP", {|Panel|cria_pn2(Panel,@aBrowse)}) o2ndPage:SetStepDescription("Grupo de empresa") o2ndPage:SetNextTitle("Avançar") o2ndPage:SetPrevTitle("Retornar") o2ndPage:SetNextAction({|| .T.}) o2ndPage:SetPrevWhen({|| .F. }) o2ndPage:SetCancelAction({|| .T.}) //---------------------------- // Pagina 3 - Aviso do backup //---------------------------- o3rdPage := oWizard:AddStep("3NDSTEP", {|Panel|cria_pn3(Panel,aBrowse)}) o3rdPage:SetStepDescription("Avisos") o3rdPage:SetNextTitle("Concluir") o3rdPage:SetPrevTitle("Retornar") o3rdPage:SetNextAction({|| ExecFix(aBrowse) }) o3rdPage:SetPrevAction({|| .T.}) o3rdPage:SetCancelAction({|| .T.}) oWizard:Activate() oWizard:Destroy() Return Static Function cria_pn1(oPanel As Object) Local oSay0 AS Object Local oSay1 AS Object Local oSay2 AS Object Local oFont AS Object Local oFont2 AS Object oFont := TFont():New( ,, -25, .T., .T.,,,,, ) oFont2 := TFont():New("Arial",,-15,,.F.,,,,,,.F.,.F.) oSay0 := TSay():New(010,015, {|| "Ajuste sequencia de baixa" }, oPanel,,oFont ,,,,.T.,CLR_BLUE, ) oSay1 := TSay():New(045,015, {|| "Esse FIX tem como objetivo ajustar a sequencia de baixa dos campos que estiverem"}, oPanel,,oFont2,,,,.T.,CLR_BLACK,) oSay1 := TSay():New(060,015, {|| "contidos no grupo de campos 134 - Sequencia de baixa"}, oPanel,,oFont2,,,,.T.,CLR_BLACK,) oSay2 := TSay():New(075,015, {|| "Clique no botão avançar para continuar" }, oPanel,,oFont2,,,,.T.,CLR_BLACK,) Return Static Function cria_pn2(oPanel,aBrowse) Local oMrkBrowse Local nX := 0 Local oOk := LoadBitMap(GetResources(), "LBOK") Local oNo := LoadBitMap(GetResources(), "LBNO") aGrupo := FWAllGrpCompany() For nX := 1 to len(aGrupo) Aadd(aBrowse,{.F.,aGrupo[nX],FWGrpName(aGrupo[nX])}) Next nX oMrkBrowse := TWBrowse():New( 010 , 010 , (oPanel:nClientWidth/2 - 020) , oPanel:nClientHeight/2 - 020 ,,,,oPanel,,,,,{|| IIF(!Empty(aBrowse[oMrkBrowse:nAt][2]), aBrowse[oMrkBrowse:nAt][1] := !aBrowse[oMrkBrowse:nAt][1] , '') , oMrkBrowse:Refresh() },,,,,,,.F.,,.T.,,.F.,,, ) oMrkBrowse:SetArray(aBrowse) oMrkBrowse:AddColumn(TCColumn():New("" , {|| Iif(aBrowse[oMrkBrowse:nAt][1],oOK,oNO)} ,,,,'CENTER' ,20,.T.,.F.,,,,.F.,)) oMrkBrowse:AddColumn(TCColumn():New("EMPRESA", {|| aBrowse[oMrkBrowse:nAt][2] } ,,,,'LEFT' ,40,.F.,.F.,,,,.F.,)) oMrkBrowse:AddColumn(TCColumn():New("DESCRIÇÃO", {|| aBrowse[oMrkBrowse:nAt][3] } ,,,,'LEFT' ,70,.F.,.F.,,,,.F.,)) Return Static Function cria_pn3(oPanel As Object, aBrowse As Array) Local oSay0 AS Object Local oSay1 AS Object Local oFont AS Object Local oFont2 AS Object oFont := TFont():New( ,, -25, .T., .T.,,,,, ) oFont2 := TFont():New("Arial",,-15,,.F.,,,,,,.F.,.F.) oSay0 := TSay():New(010,015, {|| "Verificação do ambiente" }, oPanel,,oFont ,,,,.T.,CLR_BLUE, ) oSay1 := TSay():New(045,015, {|| "Execute o processo em modo exclusivo"}, oPanel,,oFont2,,,,.T.,CLR_BLACK,) oSay1 := TSay():New(060,015, {|| "Execute o FIX em uma base de homologação para validar os ajustes"}, oPanel,,oFont2,,,,.T.,CLR_BLACK,) oSay1 := TSay():New(075,015, {|| "Faça o backup do banco de dados antes de iniciar a execução"}, oPanel,,oFont2,,,,.T.,CLR_BLACK,) Return Static Function ExecFix(aBrowse As Array) Local nX As Numeric Local aTables := {"SE2","SE5","FK2","FK1","FK5","SE1"} For nX := 1 to Len(aBrowse) If aBrowse[nX][1] FWMsgRun(, {|| StartRPC(aBrowse[nX][2],aTables) }, "Processando", "Atualizando dados empresa "+aBrowse[nX][2]) Endif Next nX Return .T. Static Function StartRPC(cGrpEmp,aTables) RpcSetType(3) RpcSetEnv( cGrpEmp,,,,,,aTables,,,.T. ) FnSeqBx() RpcClearEnv() Return Static Function FnSeqBx() Local aTables := {} Local nX := 0 Local cAlias := "" Local nY := 0 Local nTamNew := 0 Local cLogMsg := "" aFields := FWSX3Util():GetAllGroupFields( "134" ) //Pego o tamanho de qualquer campos, pois todos terão o mesmo tamanho nTamNew := FWSX3Util():GetFieldStruct( aFields[1] )[3] For nY := 1 to Len(aFields) cAlias := SUBSTR(aFields[nY], 1, AT("_", aFields[nY]) - 1) If Len(cAlias) == 2 cAlias := "S"+cAlias Endif Aadd(aTables,{cAlias,aFields[nY]}) Next nY For nX := 1 to Len(aTables) UPDATETBL(aTables[nX][1],aTables[nX][2],nTamNew,@cLogMsg) Next nX If TCSPExist("UPDTMP_"+cEmpAnt) If TcSqlExec("DROP PROCEDURE UPDTMP_"+cEmpAnt) <> 0 Conou("Erro ao deletar Stored procedure "+ TcSqlError()) Endif EndIf FnLog(cLogMsg) Return Static Function UPDATETBL(cTable,cField,nTamNew,cLogMsg) Local cQuery := "" Local cErro := "" Local cOut := "" Local cRet := "" Local nError := 0 Local lRet := .T. Local cAliasQry := "" Local cCampo := cTable + "->" + cField If TCSPExist("UPDTMP_"+cEmpAnt) If TcSqlExec("DROP PROCEDURE UPDTMP_"+cEmpAnt) <> 0 lRet := .F. Endif EndIf If lRet If Alltrim(TcGetDB()) == "ORACLE" cQuery := "SELECT R_E_C_N_O_ RECNO" cQuery += "FROM "+RetSqlName(cTable) + " " cQuery += "WHERE "+cField+" <> '' AND D_E_L_E_T_ = '' " cQuery := ChangeQuery(cQuery) cAliasQry := MpSysOpenQuery(cQuery) (cAliasQry)->(DbGotop()) DbSelectArea(cTable) If (cAliasQry)->(!EOF()) WHILE (cAliasQry)->(!EOF()) &(cTable)->(DbGoto((cAliasQry)->RECNO)) If Len(ALLTRIM(&cCampo)) < nTamNew cZero := Replicate("0", nTamNew - Len(ALLTRIM(&cCampo))) Reclock(cTable,.F.) Do Case CASE cTable == "FIP" FIP->FIP_SEQBX := cZero + ALLTRIM(FIP->FIP_SEQBX) CASE cTable == "FIS" FIS->FIS_SEQBX := cZero + ALLTRIM(FIS->FIS_SEQBX) CASE cTable == "FK1" FK1->FK1_SEQ := cZero + ALLTRIM(FK1->FK1_SEQ) CASE cTable == "FK2" FK2->FK2_SEQ := cZero + ALLTRIM(FK2->FK2_SEQ) CASE cTable == "FK5" FK5->FK5_SEQ := cZero + ALLTRIM(FK5->FK5_SEQ) CASE cTable == "FR2" FR2->FR2_SEQBX := cZero + ALLTRIM(FR2->FR2_SEQBX) CASE cTable == "GZK" GZK->GZK_SEQ := cZero + ALLTRIM(GZK->GZK_SEQ) CASE cTable == "MDM" MDM->MDM_SEQ := cZero + ALLTRIM(MDM->MDM_SEQ) CASE cTable == "N9G" N9G->N9G_SEQBXA := cZero + ALLTRIM(N9G->N9G_SEQBXA) CASE cTable == "SE1" SE1->E1_SEQBX := cZero + ALLTRIM(SE1->E1_SEQBX) CASE cTable == "SE2" SE2->E2_SEQBX := cZero + ALLTRIM(SE2->E2_SEQBX) CASE cTable == "SE5" SE5->E5_SEQ := cZero + ALLTRIM(SE5->E5_SEQ) CASE cTable == "SEI" SEI->EI_SEQ := cZero + ALLTRIM(SEI->EI_SEQ) CASE cTable == "SEV" SEV->EV_SEQ := cZero + ALLTRIM(SEV->EV_SEQ) CASE cTable == "SEZ" SEZ->EZ_SEQ := cZero + ALLTRIM(SEZ->EZ_SEQ) CASE cTable == "SFQ" SFQ->FQ_SEQORI := cZero + ALLTRIM(SFQ->FQ_SEQORI) CASE cTable == "SFQ" SFQ->FQ_SEQDES := cZero + ALLTRIM(SFQ->FQ_SEQDES) END CASE MsUnLock() Endif (cAliasQry)->(DbSkip()) ENDDO cLogMsg += 'Atualização executada com sucesso, Tabela '+cTable+ ' Atualizada ' + chr(10) Endif Else cQuery := "CREATE PROCEDURE UPDTMP_" + cEmpAnt + " AS " + CRLF cQuery += "DECLARE CUR_SEQUEN CURSOR FOR SELECT "+cField+", R_E_C_N_O_ " + CRLF cQuery += "FROM "+RetSqlName(cTable) + CRLF + " " cQuery += "WHERE "+cField+" <> '' AND LEN("+cField+") < "+cValTochar(nTamNew+1)+" AND D_E_L_E_T_ = '' " + CRLF cQuery += "DECLARE @NEWSEQ CHAR(4) " + CRLF cQuery += "DECLARE @FIELD CHAR(10) " + CRLF cQuery += "DECLARE @RECNO INT " + CRLF cQuery += "OPEN CUR_SEQUEN " + CRLF cQuery += "FETCH NEXT FROM CUR_SEQUEN " + CRLF cQuery += "INTO @FIELD, @RECNO " + CRLF cQuery += "WHILE @@FETCH_STATUS = 0 " + CRLF cQuery += "BEGIN " + CRLF cQuery += "SELECT @NEWSEQ = REPLICATE( '0' ,"+cValTochar(nTamNew)+" - LEN(@FIELD)) || @FIELD " + CRLF cQuery += "UPDATE "+RetSqlName(cTable)+" SET "+cField+" = @NEWSEQ WHERE R_E_C_N_O_ = @RECNO " + CRLF cQuery += "FETCH NEXT FROM CUR_SEQUEN " + CRLF cQuery += "INTO @FIELD, @RECNO " + CRLF cQuery += "END " + CRLF cQuery += "CLOSE CUR_SEQUEN " + CRLF cQuery += "DEALLOCATE CUR_SEQUEN " + CRLF cRet := msparsefull(cQuery,Alltrim(TcGetDB()), @cErro, @cOut) If cRet == '1' cLogMsg += "Resultado: Parse da query executado com sucesso!" + chr(10) nError := TcSqlExec(cOut) If nError < 0 cLogMsg += 'Erro na criação da Stored Procedure : ' + TcSqlError() + chr(10) Else TCSPEXEC( xProcedures("UPDTMP") ) If !Empty(TcSqlError()) cLogMsg += 'Erro na execução da Stored Procedure : ' + TcSqlError() + chr(10) Else cLogMsg += 'Procedure executada com sucesso, Tabela '+cTable+ ' Atualizada ' + chr(10) Endif Endif Else cLogMsg += "Resultado: Falha!" + chr(10) + "Error: " + cErro + chr(10) + "Parcial: " + cOut Endif Endif Endif Return Static Function FnLog(cLogText) Local cLogFile As Character Local cLogHead As Character Local lContinua As Logical Local nHandle As Numeric lContinua := .T. cLogFile := "\SYSTEM\FIXSEQBX.log" If !File(cLogFile) nHandle := FCreate( cLogFile ) If nHandle == -1 lContinua := .F. Else cLogHead:= DToC(date()) + CRLF FSeek ( nHandle, 0, 2 ) // Posiciona no final do arquivo. FWrite( nHandle, cLogHead, Len(cLogHead) ) FClose(nHandle) EndIf EndIf If lContinua // Grava o texto no Arquivo de LOG cLogText := "Execução da THREAD" + "[" + AllTrim(Str(ThreadID())) + "]" + CRLF + cLogText; nHandle := FOpen(cLogFile, 2 ) FSeek ( nHandle, 0, 2 ) // Posiciona no final do arquivo. FWrite( nHandle, cLogText, Len(cLogText) ) FClose( nHandle ) EndIf Return Static Function FnQuit(oApp) MsgInfo("Foi gerado um arquivo de log na system com o nome FIXSEQBX.log com as informações da execução","LOG de processamento") __Quit() Return |
---|
03. TABELAS UTILIZADAS
Este RDMAKE realiza a correção nas tabelas onde os campos pertencem ao grupo 134 (SXG - Grupo de campos)