Página 1 de 1

erro de array

Enviado: 27 Fev 2013 00:21
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.

erro de array

Enviado: 27 Fev 2013 09:31
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.

erro de array

Enviado: 27 Fev 2013 13:03
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.

erro de array

Enviado: 01 Mar 2013 01:00
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.

erro de array

Enviado: 01 Mar 2013 10:44
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.

erro de array

Enviado: 03 Mar 2013 23:37
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.

erro de array

Enviado: 04 Mar 2013 10:00
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.

erro de array

Enviado: 04 Mar 2013 11:03
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

erro de array

Enviado: 06 Mar 2013 18:32
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.

erro de array

Enviado: 06 Mar 2013 21:30
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.

erro de array

Enviado: 07 Mar 2013 00:21
por cjp
Acho que o Notepad++ usa automaticamente o tab, certo?

erro de array - desvio de assunto

Enviado: 07 Mar 2013 08:11
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.

erro de array

Enviado: 07 Mar 2013 16:27
por cjp
Verdade. Obrigado.

erro de array

Enviado: 07 Mar 2013 17:49
por alxsts
Olá!

Você pode configurar o editor para inserir espaços quando se tecla TAB.