Página 1 de 1

Arvore de menu

Enviado: 17 Set 2009 14:45
por fxavierds
Galera precisando de uma "senhora" ajuda

Trabalho com advpl (Microsiga) que cria menus de acesso de forma dinâmica através de um arquivo xnu que nada mais é que um xml. Fui encarregado de fazer um programa para gerar esses xnu's. Tenho a seguinte tabela:

Funcao -> nome do prg
Descricao -> Nome do Menu
Caminho -> Posição da função no menu

Seria algo assim:

Funcao -> clientes.prg
Descricao -> Clientes
Caminho -> cadastro/vendas

Dai gero o menu Cadastro subitem vendas e subitem clientes, o problema é o controle para não repetir menus, alguém poderia me ajudar? Sei que é meio complicado mas se alguem pudesse me dar uma luz, se tiver algum algoritmo de arvore parecido com isso...

Desde já agradeço.

Re: Arvore de menu

Enviado: 17 Set 2009 16:26
por fxavierds
Vixe tá dificil mesmo, vou simplificar, tudo que quero é o seguinte:

Tenho uma string := "1234" quero transforma-la em:
1
|->2
|->3
|->4

dai acho a string := "1324", então fica
1
|->2
| |->3
| |->4
|->3
|->2
|->4

dp tenho string = "212", fica
1
|->2
| |->3
| |->4
|->3
| |->2
| |->4
|->2
|->1
|->2

Alguém sabe que tipo de algoritmo resolveria isso???

Re: Arvore de menu

Enviado: 17 Set 2009 16:47
por alxsts
Saudações a todos!

O que voce precisa fazer?
Ler um XML e gerar um menu ou criar um XML?

Poste um exemplo desse XML. Talvez ajude a tornar mais claro o problema.

Re: Arvore de menu

Enviado: 17 Set 2009 17:55
por fxavierds
<ApMenu>
<DocumentProperties>
<Module>SIGATRM</Module>
<Version>10</Version>
</DocumentProperties>
<Menu Status="Enable">
<Title lang="pt">Atualizações</Title>
<Title lang="es">Atualizações</Title>
<Title lang="en">Atualizações</Title>
<MenuItem Status="Enable">
<Title lang="pt">Produtos Vendidos </Title>
<Title lang="es">Produtos Vendidos </Title>
<Title lang="en">Produtos Vendidos </Title>
<Function>MATR311 </Function>
<Type>1</Type>
<Access>xxxxxxxxxx</Access>
<Module>26</Module>
<Owner>53</Owner>
</MenuItem>
<Menu Status="Enable">
<Title lang="pt">Atualizacoes</Title>
<Title lang="es">Atualizacoes</Title>
<Title lang="en">Atualizacoes</Title>
<Menu Status="Enable">
<Title lang="pt">Cadastro </Title>
<Title lang="es">Cadastro </Title>
<Title lang="en">Cadastro </Title>
<MenuItem Status="Enable">
<Title lang="pt">Funcao do Menu </Title>
<Title lang="es">Funcao do Menu </Title>
<Title lang="en">Funcao do Menu </Title>
<Function>EITC0001 </Function>
<Type>3</Type>
<Access>xxxxxxxxxx</Access>
<Module>26</Module>
<Owner>53</Owner>
</MenuItem>
</Menu>
</Menu>
<Menu Status="Enable">
<Title lang="pt">Atualizacoes</Title>
<Title lang="es">Atualizacoes</Title>
<Title lang="en">Atualizacoes</Title>
<Menu Status="Enable">
<Title lang="pt">Cadastro </Title>
<Title lang="es">Cadastro </Title>
<Title lang="en">Cadastro </Title>
<MenuItem Status="Enable">
<Title lang="pt">GRUPOS </Title>
<Title lang="es">GRUPOS </Title>
<Title lang="en">GRUPOS </Title>
<Function>EITC0002 </Function>
<Type>3</Type>
<Access>xxxxxxxxxx</Access>
<Module>26</Module>
<Owner>53</Owner>
</MenuItem>
</Menu>
</Menu>
</Menu>
<Menu Status="Enable">
<Title lang="pt">Relatórios</Title>
<Title lang="es">Relatórios</Title>
<Title lang="en">Relatórios</Title>
<Menu Status="Enable">
<Title lang="pt">Relatorios </Title>
<Title lang="es">Relatorios </Title>
<Title lang="en">Relatorios </Title>
<MenuItem Status="Enable">
<Title lang="pt">FUNCOES </Title>
<Title lang="es">FUNCOES </Title>
<Title lang="en">FUNCOES </Title>
<Function>EITR0001 </Function>
<Type>3</Type>
<Access>xxxxxxxxxx</Access>
<Module>26</Module>
<Owner>53</Owner>
</MenuItem>
</Menu>
</Menu>
</ApMenu>
ta ai o exemplo.. repare q tem itens repetidos...quero a partir de um dbf gerar um xml...

Re: Arvore de menu

Enviado: 17 Set 2009 18:24
por alxsts
Saudações a todos!
...quero a partir de um dbf gerar um xml...
Por que tem ítens repetidos? É um erro na geração do XML?

Poste um DBF pequeno zipado, com alguns dados para vermos a estrutura do mesmo e a natureza dos dados.

Re: Arvore de menu

Enviado: 18 Set 2009 10:04
por fxavierds
Tem itens repetidos justamente pq não tou conseguindo fazer a árvore...
Imagina o seguinte: vc tem o campo (string) caminho no menu, dai tem 3 registros

1. Cadastro/Vendas/Clientes
2. Cadastro/Vendas/Produtos
3. Relatório/Vendas/Clientes

Qual algoritmo uso para gerar o menu automatico?

Re: Arvore de menu

Enviado: 18 Set 2009 16:20
por fxavierds
Galera o que quero é o seguinte, pegar esse xnu e gerar um array com a seguinte estrutura

aMenu //-> Sub itens
aMenu[1][1] //Nome -> Atualizacoes, etc
aMenu[3] //-> Sub/Sub Itens
aMenu[3][k][1] //Nome -> Cadastros
aMenu[3][k][3][j] //Item do Menu
aMenu[3][k][3][j][2] //Nome
aMenu[3][k][3][j][2] //Status E=Enable
aMenu[3][k][3][j][3] //Rotina
aMenu[3][k][3][j][4] //Aliases (Array)
aMenu[3][k][3][j][5] //Acessos xxxxxxxxxx
aMenu[i][3][k][3][j][6] //Modulo
aMenu[i][3][k][3][j][7] //Tipo

o problema é que não sei trabalhar com array multidimensional. alguém tem algum totorial sobre isso?

Re: Arvore de menu

Enviado: 19 Set 2009 02:51
por alxsts
Saudações a todos!

Xavier:

Preparei um exemplo simples de como carregar um arquivo .DBF em um array Clipper. Compile com opção debug e veja como fica o array resultante na memória.

Código: Selecionar todos

// Posições (colunas) em aFile
#define A_NOME      1
#define A_ENDERECO  2
#define A_BAIRRO    3
#define A_CIDADE    4
#define A_UF        5
#define A_CEP       6
#define A_FONE      7
//------------------------------------------------------------------------------
PROCEDURE Teste()

   // Compilar   : Clipper Teste /n/w/b
   // Link       : <teu link-editor> FI Teste, C:\Clipper5\Lib\CLD.LIB

   LOCAL aFile, nPos

   AltD()

   IF ! File( "Teste.Dbf" )
      FileLoad()
   ENDIF

   aFile := ArrayLoad()

   // acessando o array
   // suponha que precise imprimir dados do "None 12"

   // pesquisa o elemento no array
   nPos := Ascan( aFile, { |e| RTrim( e[ A_NOME ] ) == "Nome 12" } )

   // Se encontrou, exibe
   IF nPos > 0
      Alert( "Elemento encontrado:;;" + PadR( "Nome  : " + aFile[ nPos, A_NOME ], 20 ) + ";" + ;
                                        PadR( "Cidade: " + aFile[ nPos, A_CIDADE ], 20 ) + ";" + ;
                                        PadR( "UF    : " + aFile[ nPos, A_UF ], 20 ),, "N/W" )
   ENDIF

   RETURN
//------------------------------------------------------------------------------
STATIC PROCEDURE FileLoad()

   LOCAL nInd

   DBCreate( "Teste.DBF", { { "Nome", "C", 20, 0 }, ;
                            { "Endereco", "C", 30, 0 }, ;
                            { "Bairro", "C", 20, 0 }, ;
                            { "Cidade", "C", 20, 0 }, ;
                            { "UF", "C", 2, 0 }, ;
                            { "CEP", "C", 8, 0 }, ;
                            { "Fone", "C", 8, 0 } ;
                          } ;
           )

   USE Teste SHARED New

   FOR nInd := 1 TO 20

      Teste->( DBAppend() )

      Teste->Nome     := "Nome " + LTrim( Str( nInd ) )
      Teste->Endereco := "Endereco " + LTrim( Str( nInd ) )
      Teste->Bairro   := "Bairro " + LTrim( Str( nInd ) )
      Teste->Cidade   := "Cidade " + LTrim( Str( nInd ) )
      Teste->UF       := "SP"
      Teste->CEP      := Replicate( "9", 8 )
      Teste->Fone     := Replicate( "9", 8 )

   NEXT

   Teste->( DBCloseArea() )

   RETURN

//------------------------------------------------------------------------------
STATIC FUNCTION ArrayLoad()

   LOCAL aMain, aSub, nFCount, nFieldPos

   Use Teste SHARED New

   Teste->( DBGoTop() )

   // Salva a quantidade de campos do registro
   nFCount := Teste->( FCount() )

   // inicializa o array que conterá os dados do arquivo
   aMain   := {}

   // executa loop percorrendo o arquivo
   WHILE Teste->( ! Eof() )

      // inicializa vetor que armazena os campos da linha atual do arquivo
      aSub := {}

      // executa leitura do registro atual, campo a campo
      FOR nFieldPos := 1 TO nFCount
         // carrega o campo no final do array temporário
         AAdd( aSub, Teste->( FieldGet( nFieldPos ) ) )
      NEXT

      // adicona o array temporário no final do array definitivo
      AAdd( aMain, aSub )

      // obtem o próximo registro, caso exista
      Teste->( DBSkip() )
   ENDDO

   Teste->( DBCloseArea() )

   RETURN aMain
//------------------------------------------------------------------------------
Espero que ajude a elucidar suas dúvidas no trato com arrays uni e multi-dimensionais. Estude no NG as funções referentes ao assunto: AADD(), AINS(), ADEL(), ATAIL(), ASCAN(), ASORT()

Mais dúvidas? Continue postando!

Re: Arvore de menu

Enviado: 19 Set 2009 17:01
por fxavierds
Cara valeu mesmo pela ajuda, o problema é que tenho que gerar o menu com base em apenas 3 campos e um deles é uma string do tipo "Cadastro/Vendas/Vendedor" e dai gerar o menu e não consigo um algoritmo que controle isso, que faça sem repetir itens...

Re: Arvore de menu

Enviado: 19 Set 2009 17:21
por alxsts
Saudações a todos!

Pelo que percebi, o menu é multi-lingual, com prompts em português, espanhol e inglês. Todos os prompts, independentemente da linguagem, estão escritos em português. Acho que voce vai ter que filtrar pela linguagem. Por exemplo: para exibir o menu em portugues, no XML tem a tag <Title lang="pt">Produtos Vendidos </Title>. Provavelmente voce deve ter esta informação no teu DBF. Por isso, entre outras coisas, te pedi para postar o DBF e índices. Ficaria mais fácil...

Re: Arvore de menu

Enviado: 19 Set 2009 17:46
por fxavierds
não leva em conta a linguagem..isso estou desprezando e sempre mostro em portugues..vou te passar a estrutura do dbf

aStru := {}
AADD(aStru,{"Menu","C",25,0}) -----> Pode ser Atualizacao, Consulta, Relatorio ou Miscelanea
AADD(aStru,{"Funcao","C",10,0}) -----> Nome da funcão mas precisamente do prg
AADD(aStru,{"Descricao","C",25,0}) -----> Descricao no menu tipo Cadastro de Clientes
AADD(aStru,{"Caminho","C",200,0}) ---> Caminho, onde defino a posicao: Cadastro/Vendas
AADD(aStru,{"Posicao","C",1,0}) -----> 1 a 4 se 1 Atualizacao 2 Consulta, 3 Relatorio ou 4 Miscelanea
cArq := CriaTrab(aStru,.t.)
Use &cArq Alias dbfM new
Index on Posicao + NM + Menu to &cArq

a partir dessa informacao que são informacoes resumidas de 3 tabelas, tenho que gerar o xml no formato que vc viu, até ai tudo bem, consigo gerar, o que não consigo é evitar repeticao de itens...imagina o campo caminho como algo assim:
Atualizacao/Cadastro/Clientes
Atualizacao/Cadastro/Produtos
Consulta/Cadastro/Cliente

Deveria gerar apenas 2 menus
Atualizacao
|->Cadastro
|->Clientes
|->Produtos
Consulta
|->Cadastro
|->Cliente

E não consigo uma lógica pra isso

Re: Arvore de menu

Enviado: 19 Set 2009 18:11
por alxsts
Saudações a todos!
Xavier escreveu:
Index on Posicao + NM + Menu to &cArq
O que é o NM citado? Não consta na estrutura que voce enviou.

Re: Arvore de menu

Enviado: 19 Set 2009 18:25
por fxavierds
eu tirei pra simplificar...seria numero no menu (uma forma q tentei usar para solucionar), conte o numero de bracos do menu atualizacao/cadastro/clientes então o nm de cada um seria 1/2/3 mas não necessariamente preciso usar esse campo..como disse tava usando ele pra tentar resolver...