erro de array

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

erro de array

Mensagem por cjp »

Colegas,

Preciso da ajuda de vocês com um erro de array, que não consegui entender. O erro é:

Código: Selecionar todos

Error BASE/1132  Erro de limite: acesso de array.
No meu computador o problema não ocorre. Mas no computador dos demais usuários, estranhamente, sempre ocorre o erro.

Como peguei essa função de alguém, e não a entendo bem, já que não sei lidar bem com vetor, não consigo saber a origem do erro.

Minha função está assim (o erro está dando na primeira linha da função implist8, abaixo):

Código: Selecionar todos

function imprlist

do while .t.
   
   clear
   
   set devi to screen
   
   tmax=300
   
   nprn=0
   
   aPrn := Win_PrinterList( .t., .f. )
   
   aPNomes := {}
   
   escimpr()
   
   do case 
           
      case nprn=len(aprn)+1
           
           @ 15,5 say "Será salvo o arquivo LISTCOM.TXT na pasta CRIANCAS do"
           
           @ 16,5 say "teu computador; abra-o no Bloco de Notas e imprima."
           
           tone(261.7,3)
           
           inkey(1)
           
           wait ""
           
           inkey(5)
           
           set device to print
           
           set printer to listcom.txt
           
           set device to screen
           
      case nprn=len(aprn)+2
           
           confnimpr="N"
           
           clear
           
           @ 5,5 say "Tem certeza que não vai imprimir a lista?"get confnimpr pict "@!"
           
           tone(261.7,3)
           
           wait ""
           
           read
           
           if confnimpr#"S"
              
              loop
              
           else
              
              exit
              
           endif
           
           otherwise
           
           cls
           
           @ 5,5 say "Confira se a impressora está ligada e com papel rascunho; o programa"
           
           @ 7,5 say "irá imprimir diretamente; tecle ENTER quando estiver pronta."
           
           tone(261.7,3)
           
           wait ""
           
           cInicio := "substr(texto,1,72)" // "substr(produto,1,50) + space(3) + alltrim(str(prmaximo)) + space(1) + substr(unidade,1,16)"
           
           cCampos := "substr(texto,73,72)" //"substr(produto,51,50) + space(3) + substr(unidade,17,20)" // "DTOC(data) + Space(2) + hora + Space(2) + tarefa"
           
           cFinal := "substr(texto,145)"
           
           cCriterio := "Recno() >= nrc"
           
           if alias()#"LISTCOM"
              
              usebase("listcom")
              
           endif
           
           Go nrc // apenas para esse exemplo
           
           implist8() // ( cCampos, cCriterio )
           
   endcase                       
   
   clear
   
   confimpr="N"
   
   @ 15,5 say "Atenção: só é pra confirmar depois de terminar de imprimir"
   
   inkey(3)
   
   @ 5,5 say "Imprimiu a lista?"get confimpr pict "@!"
   
   inkey(5)
   
   read
   
   if confimpr="S"
      
      exit
      
   endif
   
enddo

return







function escimpr

Local i, oPrn, nMaxLen := 0



If Empty( aPrn )
   
   Hb_Alert( "Nenhuma impressora Instalada" )
   
   Return Nil
   
Endif



For i=1 To Len( aPrn )
    
    AaDd( aPNomes , aPrn[i,1] )
    
    nMaxLen := If( Len( aPrn[i,1] ) > nMaxLen, Len( aPrn[i,1] ), nMaxLen )
    
Next

if upper(procname(1))="IMPRLIST"
   
   AaDd ( aPNomes , "Imprimir manualmente" )
   
   AaDd ( aPNomes , "Não imprimir" )
   
endif



Clear Screen



nPrn := AChoice( 3, 5, 13, 65, aPNomes, .T., Nil , aPNomes )



If nPrn = 0
   
   Return Nil
   
Endi



return









FUNCTION Implist8 

oPrn:=Win_Prn():new( aPNomes[nPrn] )



If !oPrn :Create()
   
   Hb_alert("Nao foi criado o documento de Impressao")
   
   Return nil
   
ElseIf !oPrn :StartDoc("Imprimindo Documento")
   
   Hb_alert("Erro na Impressora")
   
   Return nil
   
EndIf

oPrn:SetFont('Times New',16, 0,.F.,.T.,.F.)



nlnh=1

nrpg=1

oPrn:NewLine()

While &cCriterio. .And. !Eof()

nlnh++

oPrn:NewLine()

oPrn:NewLine()

oPrn:TextOut(&cInicio. )

oPrn:SetFont('Times New',16, 0,.F.,.F.,.F.)

if !empty(&cCampos)
   
   nlnh++
   
   oPrn:NewLine()
   
   oPrn:NewLine()
   
   if at(" ",&cCampos)=1
      
      oPrn:TextOut(" "+&cCampos. ) 
      
   else   
      
      oPrn:TextOut("  "+&cCampos. ) 
      
   endif   
   
endif    

if !empty(&cFinal)
   
   nlnh++
   
   oPrn:NewLine()
   
   oPrn:NewLine()
   
   if at(" ",&cFinal)=1
      
      oPrn:TextOut(" "+&cFinal. ) 
      
   else
      
      oPrn:TextOut("  "+&cFinal. ) 
      
   endif 
   
endif    



If nlnh>28
   
   nlnh=0
   
   oPrn:NewLine()
   
   oPrn:NewLine()
   
   oPrn:NewLine()
   
   oPrn:TextOut("                                                  Página "+alltrim(str(nrpg)))
   
   oPrn:NewLine()
   
   nrpg++
   
   oPrn:NewPage()
   
Endi



Skip



Endd





if nrpg>0
   
   do while nlnh<27
      
      oPrn:NewLine()
      
      nlnh++
      
   enddo   
   
   oPrn:NewLine()
   
   oPrn:NewLine()
   
   oPrn:TextOut("                                                    Página "+alltrim(str(nrpg)))
   
endif

oPrn:EndDoc()

oPrn:Destroy()

Return Nil
Alguém me ajuda, por favor?
Nota de Moderação:
por Rochinha: Trecho de codigo foi re-identado para melhor leitura do codigo. Os espaços entre linhas continam os mesmos.
Inacio de Carvalho Neto
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

erro de array

Mensagem por Jairo Maia »

Olá Inácio,

Veja que se estiver vindo da função IMPRLIST você acrescenta na matriz aPNome duas opções além das impressoras detectadas. Se o usuário coloca o S para imprimir então você chama a função IMPLIST8, porém, nPrn é o tamanho da matriz de impressoras mais 2, e quando chega na IMPLIST8 você tenta selecionar uma impressora que está fora da lista.

Primeiro, tente alterar sua função ESCIMP assim:

Código: Selecionar todos

function escimpr( lComOpcoes )  // acrescentado o parametro lComOpcoes

Local i, oPrn, nMaxLen := 0

lComOpcoes := If( lComOpcoes = Nil, .t., lComOpcoes )  // trata o parametro se Nil

If Empty( aPrn )
   
   Hb_Alert( "Nenhuma impressora Instalada" )
   
   Return Nil
   
Endif

For i=1 To Len( aPrn )
    
    AaDd( aPNomes , aPrn[i,1] )
    
    nMaxLen := If( Len( aPrn[i,1] ) > nMaxLen, Len( aPrn[i,1] ), nMaxLen )
    
Next

if upper(procname(1))="IMPRLIST" .And. lComOpcoes  // se .F., mostra somente impressoras
   
   AaDd ( aPNomes , "Imprimir manualmente" )
   
   AaDd ( aPNomes , "Não imprimir" )
   
endif

Clear Screen

nPrn := AChoice( 3, 5, 13, 65, aPNomes, .T., Nil , aPNomes )

If nPrn = 0
   
   Return Nil
   
Endi

return
E na função IMPRLIST no trecho que você chama a IMPLIST8 que está assim:

Código: Selecionar todos

 Go nrc // apenas para esse exemplo
           
 implist8() // ( cCampos, cCriterio )
Altere desta forma:

Código: Selecionar todos

 Go nrc // apenas para esse exemplo
           
 nPrn := 0
 escimpr( .F. )  // parametro .F. para mostrar somente impressoras
 If nPrn > 0 
  implist8() // ( cCampos, cCriterio )
 Endi
Veja se vai funcionar.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

erro de array

Mensagem por JoséQuintas »

Quando ocorre erro, é apresentada a linha e função aonde ocorreu o erro.
Esse é o ponto de partida pra alguma solução.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

erro de array

Mensagem por cjp »

Jairo, vou testar como vc disse, mas inicialmente já estranhei duas coisas que vc mencionou:

1) vc disse
você tenta selecionar uma impressora que está fora da lista
. Mas, salvo erro de minha parte, não é isso que está ocorrendo. Onde eu estaria selecionando uma impressora fora da lista?

2) da forma como vc fez, o programa vai chamar duas vezes a função escimp(), o que não faz sentido. Tem que ser assim mesmo?

José, não sei se te entendi, mas eu mencionei acima a linha onde está ocorrendo o erro. Queria justamente entender o erro.
Inacio de Carvalho Neto
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

erro de array

Mensagem por Jairo Maia »

Olá Inácio,
cjp escreveu:Mas, salvo erro de minha parte, não é isso que está ocorrendo. Onde eu estaria selecionando uma impressora fora da lista?
Na primeira linha da funcao IMPLIST8, veja:

Código: Selecionar todos

oPrn:=Win_Prn():new( aPNomes[nPrn] )
aPnomes é a matriz (Array) com os nomes da impressora, e você tenta iniciar a impressora na posição nPrn.
cjp escreveu:da forma como vc fez, o programa vai chamar duas vezes a função escimp(), o que não faz sentido. Tem que ser assim mesmo?
Pelo seu código sim. Veja que se chegou naquele ponto, é porque o usuário não selecionou impressora, mas sim escolheu a opção NÃO IMPRIMIR e depois decidiu imprimir. Então precisa selecionar a impressora, ou você decidir sempre imprimir na impressora padrão, assim, com algumas mudanças no código não necessita solicitar ao usuário selecionar a impressora.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

erro de array

Mensagem por cjp »

Jairo, desculpe, mas ainda não te entendi no tocante à primeira linha da função IMPLIST8 (que já não está como vc citou, pois eu coloquei como vc mandou).

Note que, na função imprlist, primeiro é chamada a função escimpr, onde o usuário escolhe em qual impressora vai imprimir, ou se vai imprimir manualmente, ou se não vai imprimir. Em seguida, a função imprlist tem um do case: a primeira hipótese é para impressão manual; a segunda, para não imprimir; e depois, com o otherwise, para imprimir na impressora escolhida. Não vejo razão para ter outra chamada à função escimpr neste ponto.

Coloquei do jeito que vc disse, mas continua dando o mesmo erro.
Inacio de Carvalho Neto
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

erro de array

Mensagem por Eolo »

Inácio, Erro Base 1132 aparece quando vc tenta acessar um elemento que não existe no array.

Exemplo:

Código: Selecionar todos

array:-{10, 20, 30, 40}
?len(array) -> 4
x:=1
?array[x] -> 10
x:=4
?array[x] -> 40
x:=5
?array[x] -> ERRO BASE 1132 // vc chamou o elemento 5, mas o array só tem 4...
Então, dê um WAIT antes de cada uso que vc fizer do array e verifique o LEN() dele e qual elemento vc está tentando recuperar.
É aí que a coisa tá pegando.

EM TEMPO: na pasta onde o programa está rodando, procure por um arquivo ERRO.LOG (ou algo parecido). Esse arquivo vai conter as informações sobre o erro.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

erro de array

Mensagem por Jairo Maia »

Olá Eolo,
Sim, eu já até havia dito isso mais acima, o problema estava em entender o porque.

Olá Inácio,

Agora sim vi o OTHERWISE. Apesar do colega Rochinha ter melhorado a endentação, na forma que ele ficou acabei não vendo mesmo, e acho que entendi o problema.

O erro está ocorrendo quando é chamada a função ESCIMPR e o usuário pressiona ESC. Se quando aparecer a lista para selecionar impressora o usuário pressiona ESC, nPrn tem o valor 0 (zero), e entra no OTHERWISE e vai pra função IMPLIST8.

Veja que se nPrn for zero porque o usuário pressionou esc na ESCIMPR, o case atendido é o OTHERWISE. Sugiro então que desconsidere as sugestões anteriores, e acrescente um Case para tratar o nPrn quando ele for 0:

Código: Selecionar todos

Case nPrn = 0
 Exit
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

erro de array

Mensagem por cjp »

É que, quando a gente cola aqui o trecho do programa, nem sempre a identação fica correta, e eu não sei como alterar isso, por isso às vezes não fica claro.

Bom, realmente não havia tratamento para o zero. É possível que seja este o problema. Isso até explica o fato de que no meu computador nunca dava o problema, só nos dos usuários.

Apesar que eu não creio que os usuários estivessem teclando ESC, mas, de toda forma, vamos testar. Eu corrigi o programa para dar tratamento a essa situação, vamos ver se resolve.

Desde já, muito obrigado a todos.
Inacio de Carvalho Neto
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

erro de array

Mensagem por Pablo César »

cjp escreveu:É que, quando a gente cola aqui o trecho do programa, nem sempre a identação fica correta, e eu não sei como alterar isso, por isso às vezes não fica claro
Isso provavelmente ocorre quando você utiliza TAB em lugar de espaços em brancos.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

erro de array

Mensagem por cjp »

Acho que o Notepad++ usa automaticamente o tab, certo?
Inacio de Carvalho Neto
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

erro de array - desvio de assunto

Mensagem por Pablo César »

Posicione o cursor no inicio da linha onde estiver identado (deixe o insert desligado) e pressione espaços, você verá que ele irá se ajeitar e sobre-escrever os TAB por espaço.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

erro de array

Mensagem por cjp »

Verdade. Obrigado.
Inacio de Carvalho Neto
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

erro de array

Mensagem por alxsts »

Olá!

Você pode configurar o editor para inserir espaços quando se tecla TAB.
[]´s
Alexandre Santos (AlxSts)
Responder