No artigo de hoje vou mostrar uma função desenvolvida para otimizar a busca de dados da SX3 para enviar os fontes no Code Analysis.
Se você já precisou atender algum cliente e mexer com o Code Analysis, sabe que em muitos fontes antigos, analistas geralmente percorriam a sx3 para montar dados de um aHeader.
Pois bem, até podemos usar a função OpenSXs para abrir a SX3, mas a performance dela deixa a desejar, então como podemos solucionar isso?
Podemos chamar a GetSX3Cache dos campos necessários, e pensando nisso, criei uma função chamada zX3ToArr, então a título de curiosidade, olha como estava antes a montagem de um aHeader em um fonte bem antigo:
cAlias := "SZA" //Cria vetor aHeader dbSelectArea("SX3") dbSetOrder(1) dbSeek(cAlias) aHeader := {} While !SX3->(EOF()) .And. SX3->X3_Arquivo == cAlias AAdd(aHeader, {SX3->X3_Titulo,; SX3->X3_Campo ,; SX3->X3_Picture ,; SX3->X3_Tamanho ,; SX3->X3_Decimal ,; SX3->X3_Valid ,; SX3->X3_Usado ,; SX3->X3_Tipo ,; SX3->X3_Arquivo ,; SX3->X3_Context}) SX3->(dbSkip()) EndDo
Agora com a função nova, veja como fica:
aStruct := SZA->(DbStruct()) aHeader := {} //Percorre todos os campos da estrutura da tabela For nAtual := 1 To Len(aStruct) //Chama a função que adiciona ao array via @, conforme o campo atual, e o tipo é 4 que será usado em um MsNewGetDados u_zX3ToArr(@aHeader, aStruct[nAtual][1], 4) Next
Abaixo o fonte completo da função zX3ToArr:
//Bibliotecas #Include "TOTVS.ch" /*/{Protheus.doc} User Function zX3ToArr Função que exporta a SX3 adicionando uma linha no array @type Function @author Atilio @since 10/06/2021 @version version @param aArray, Array, Variável do Array que terá o conteúdo adicionado (deve ser passado com @) @param cCampo, Caractere, Nome do campo a ser verificado na SX3 @param nTipo, Numeric, Tipo do array @param cTituloDef, Caractere, Título default da coluna a ser considerado no lugar do X3_TITULO @param cCampoDef, Caractere, Nome do campo que será usado no array (para MsNewGetDados) @param cBlocoDef, Caractere, Texto do bloco de código que será adicionado no array (para FWBrwColumn) @param cAliasDef, Caractere, Alias Default usado em FWMarkBrowse no método SetFields @obs Tipos do nTipo: 1 = Campos para FWTemporaryTable 2 = Campos para um aHeader de um FWMarkBrowse 3 = Campos para aSeek FWMarkBrowse 4 = Campos para um aHeader de um MsNewGetDados 5 = Campos para um aHeader composto de FWBrwColumn, porém para usar em um FWFormBrowse 6 = Campos para filtro de SetFieldFilter em um FWFormBrowse 7 = Campos para definição de um FWMarkBrowse (método SetFields) /*/ User Function zX3ToArr(aArray, cCampo, nTipo, cTituloDef, cCampoDef, cBlocoDef, cAliasDef) Local aArea := GetArea() Local cFieldX3 := "" Local cTipoX3 := "" Local cTitX3 := "" Local cPictX3 := "" Local cCBoxX3 := "" Local cF3X3 := "" Local cValidX3 := "" Local cUsadoX3 := "" Local cRelacaoX3 := "" Local aTamX3 := {} Local nTamArr := 0 Local cAliasTab := "" Default aArray := {} Default cCampo := "" Default nTipo := 0 Default cTituloDef := "" Default cCampoDef := "" Default cBlocoDef := "" Default cAliasDef := "" //Se tiver campo preenchido If ! Empty(cCampo) cFieldX3 := GetSX3Cache(cCampo, "X3_CAMPO") //Se o campo for encontrado na SX3 If ! Empty(cFieldX3) nTamArr := Len(aArray) + 1 cAliasTab := AliasCPO(cFieldX3) cTipoX3 := GetSX3Cache(cFieldX3, "X3_TIPO") aTamX3 := TamSX3(cFieldX3) cTitX3 := Iif(Empty(cTituloDef), GetSX3Cache(cFieldX3, "X3_TITULO"), cTituloDef) cPictX3 := PesqPict(cAliasTab, cFieldX3) cCBoxX3 := GetSX3Cache(cFieldX3, "X3_CBOX") cF3X3 := GetSX3Cache(cFieldX3, "X3_F3") cValidX3 := GetSX3Cache(cFieldX3, "X3_VALID") cUsadoX3 := GetSX3Cache(cFieldX3, "X3_USADO") cRelacaoX3 := GetSX3Cache(cFieldX3, "X3_RELACAO") //Para montar a Struct de uma FWTemporaryTable If nTipo == 1 aAdd(aArray, {; Iif(Empty(cCampoDef), cCampo, cCampoDef),; cTipoX3,; aTamX3[1],; aTamX3[2]; }) //Para montar o aHeader de telas com Browse (FWMarkBrowse) ElseIf nTipo == 2 aAdd(aArray, {; Iif(Empty(cCampoDef), cCampo, cCampoDef),; cTitX3,; nTamArr,; cPictX3,; 1,; aTamX3[1],; aTamX3[2],; cCBoxX3; }) //Para montar o aSeek em telas com Pesquisa no Browse ElseIf nTipo == 3 aAdd(aArray, { cTitX3, ; { { "",; cTipoX3,; aTamX3[1],; aTamX3[2],; cTitX3,; cPictX3; } }; }) //Para montar o aHeader de telas com Browse (MsNewGetDados) ElseIf nTipo == 4 aAdd(aArray, {; cTitX3,; Iif(Empty(cCampoDef), cCampo, cCampoDef),; cPictX3,; aTamX3[1],; aTamX3[2],; cValidX3,; cUsadoX3,; cTipoX3,; cF3X3,; cRelacaoX3,; cCBoxX3; }) //Para montar o aHeader de telas com FWBrwColumn (FWFormBrowse) ElseIf nTipo == 5 aAdd(aArray, FWBrwColumn():New()) nTamArr := Len(aArray) aArray[nTamArr]:SetType(cTipoX3) aArray[nTamArr]:SetTitle(cTitX3) aArray[nTamArr]:SetSize(aTamX3[1]) aArray[nTamArr]:SetPicture(cPictX3) aArray[nTamArr]:SetDecimal(aTamX3[2]) aArray[nTamArr]:SetData(&(cBlocoDef)) //Para utilizar o método SetFieldFilter (FWFormBrowse) ElseIf nTipo == 6 aAdd(aArray, {; cCampo,; cTitX3,; cTipoX3,; aTamX3[1],; aTamX3[2],; cPictX3; }) //Para utilizar o método SetFields (FWMarkBrowse) ElseIf nTipo == 7 aAdd(aArray, {; cTitX3,; &("{|| " + Iif(! Empty(cAliasDef), "(" + cAliasDef + ")->", "") + cCampo + "}"),; cTipoX3,; cPictX3,; 1,; aTamX3[1],; aTamX3[2],; .F.,; ,; ,; ,; ,; ,; ,; ,; 1; }) EndIf EndIf EndIf RestArea(aArea) Return
Obs.: O ideal é migrar as funções antigas, por exemplo, de MsNewGetDados para grids mais novas como FWBrowse e MVC, porém se tiver pouco tempo no projeto, ou até nas grids mais novas usar a SX3 para montar as informações, ai você pode adaptar a função acima
Bom pessoal, por hoje é só.
Abraços e até a próxima.