next up previous contents
Next: Ordenação Up: Técnicas de Programação Utilizando Previous: Trabalhando com Várias Planilhas

Vetores

Até agora todos os tipos de dados vistos (Integer, Double, String, Boolean, ) foram tipos de dados atômicos. O tipo de Dados Vetor é um tipo de dados composto por outros tipos de dados.

Basicamente, um vetor é uma seqûência de dados do mesmo tipo. Desta forma, podemos ter um vetor de inteiros, um vetor de strings, etc. O que caracteriza um vetor é o fato de possuir um tamanho, que é o conjunto de posições contidas no vetor, e o fato de estas posições de dados poderem ser acessadas através de um índice.

Uma declaração de um vetor de 20 posições de inteiros é feita da seguinte maneira:

Dim vet(20) as Integer

Em geral, costuma-se deixar o valor de um vetor representado na forma de uma constante:

Const TAM_VET = 20
Dim vet(TAM_VET) as Integer

A primeira posição do vetor é a posição 1. A última é a posição TAM_VET. As posições do vetor podem ser acessadas através de um índice inteiro. Eis aqui alguns exemplos de manipulação do vetor vet:

vet(1) = 22
i=2
vet(i) = 20
vet(i+1) = vet(i) - vet(i-1)

Acessos ao vetor com valores de índice fora do intervalo padrão 1..TAM_VET são considerados ilegais e causam erros de execução no programa. Podemos alterar os valores deste intervalo padrão na declaração, por exemplo:

Dim lucroAnual(1985 To 2010) as Double

faz com que os valores legais de índice para o vetor estejam no intervalo 1985..2010. Note que o tamanho do vetor lucroAnual é 26 = 2010 - 1985 + 1 (a mesma fórmula é usada no cálculo dos vetores no caso padrão: o tamanho de vet é 20 = 20 - 1 + 1; em geral tamanho = PosiçaoFinal - PosiçãoInicial + 1.)

Podemos ter vetores multidimensionais. Um vetor bidimensional é, em geral, chamado de matriz. A declaração dos vetores multidimensionais segue o mesmo padrão da declaração dos vetores unidimensionais:

Dim matriz(50, 10) as String 'Matriz de 50 linhas por 10 colunas
Dim multiDimensional(5, 10, 2) as Double

O acesso a uma matriz se dá através de dois índices; similarmente, um vetor de n dimensões é acessado através de níndices. Em geral, quando mencionamos vetores, temos em mente o caso unidimensional, e é a ele que vamos nos restringir nesta seção.

Com relação ao uso de vetores como parâmetros de funções e procedimentos:

Como conseqüência deste último fato, a alteração de vetores dentro de uma função ou procedimento se dá por efeito colateral. Com isso queremos dizer que, se um vetor é passado para uma função e, no interior desta função este vetor é alterado, esta alteração será percebida na função ou procedimento que chamou a função.

Isto é o que ocorre na função ColVet() abaixo, que lê uma coluna e copia seus valores um um vetor. Esta função recebe um vetor como parâmetro e, ao retornar, além de retornar o número de posições lidas, o valor do vetor está alterado, contendo uma cópia dos valores contidos na coluna.

Vamos considerar um exemplo. Considere uma planilha que contém, em uma coluna, valores positivos e negativos. Queremos eliminar os valores negativos (pois supostamente representam valores ilegais) eliminar as células ocupadas por estes valores. Por exemplo, queremos transformar:

12,50   12,50
-4,00   5,20
5,20 em 7,00
-9,50    
7,00    

Para resolver este problema, vamos dividi-lo em uma série de funções e macros auxiliares, de acordo com a seguinte descrição geral da solução:

Antes de iniciar o detalhamento, vamos mostrar as constantes usadas no módulo.

Const TamVet = 20
Const LinhaInicial = 2
Const ColunaFoco = 1

Começamos mostrando a macro principal, que invoca todas as outras funções e procedimentos , além de realizar a compactação do vetor no item 3.

Sub EliminaNeg()
Dim i As Integer
Dim tam1 As Integer 'Tamanho inicial do vetor
Dim tam2 As Integer 'Tamanho do vetor compactado
Dim iniVet(TAM_VET) As Double 'Vetor inicial
Dim CompactVet(TAM_VET) As Double 'Vetor compactado
'Lê coluna sob Foco, no máximo TAM_VET posições
tam1 = ColVet(ColunaFoco, iniVet(), LinhaInicial, TamVet)
tam2 = 0
'Zera posições negativas
Call ApagaNeg(iniVet(), tam1)
i = 1
'Principal
Do While i
<= tam1
If iniVet(i)
> 0 Then
'Copia de iniVet para CompactVet
tam2 = tam2 + 1
CompactVet(tam2) = iniVet(i)
End If
i = i + 1
Loop
'Copia CompactVet para a coluna
Call VetCol(ColunaFoco, compactVet(), LinhaInicial, tam2)
'Esvazia demais posições
Call Esvazia(ColunaFoco, tam2 + LinhaInicial, tam1 + LinhaInicial - 1)
End Sub

Em seguida mostramos o item 2, que é uma subrotina que altera um vetor, mudando todos os valores negativos para 0. Como parâmetro, recebe o vetor e o seu tamanho:

Sub ApagaNeg(vet() As Double, tam As Integer)
Dim i As Integer
i = 1 'Inicialização
Do While i
<= tam
If vet(i)
< 0 Then
vet(i) = 0
End If
i = i + 1 'Proxima linha
Loop
End Sub

Em seguida, o item 1 é feito pela função ColVet(), que recebe como parâmetros a coluna a ser copiada, o vetor a ser alterado, o valor da primeira linha a ser copiada e o número máximo de posições que o vetor suporta. A função retorna o número de posições realmente lidas, que pode ser menor que o tamanho máximo.

Function ColVet(col As Integer, vet() As Double, iniLin As Integer, tamMax As Integer)
Dim i As Integer
Dim lin As Integer
i = 1
lin = LinhaInicial
Do While i
<= tamMax And Not IsEmpty(Cells(lin, col))
'Lê célula atual
vet(i) = Cells(lin, col)
'Próxima linha
i = i + 1
lin = lin + 1
Loop
'Retorno
ColVet = i - 1
End Function

O item 4 é feito pelo procedimento VetCol(), o oposto de ColVet(), que copia um vetor para uma coluna da planilha. Os parâmetros são os mesmos e não há necessidade de retornar nenhum valor, uma vez que o tamanho do vetor já é conhecido.

Sub VetCol(col As Integer, vet() As Double, iniLin As Integer, tam As Integer)
Dim i As Integer
i = 1
Do While i
<= tam
Cells(i + iniLin - 1, col) = vet(i)
i = i + 1
Loop
End Sub

Por fim, o procedimento que apaga as linhas restantes.

Sub Esvazia(col As Integer, iniLin As Integer, fimLin As Integer)
Dim lin As Integer
lin = iniLin
Do While lin
<= fimLin
Cells(lin, col) = Empty
lin = lin + 1
Loop
End Sub


Exercícios

Nota: Algumas versões do Excel podem vir com o padrão de indexação diferente daquele apresentado nesse cap'itulo. Para garantir que todos os vetores possuem a primeira posição indexada por 1 (e não por 0), basta adicionar no início do seu módulo (antes das declarações de Const) a seguinte instrução:

Option Base 1

1.
Fazer um programa que inverte uma coluna. Por exemplo, uma coluna que contem ``1, 2, 3, 4'' deverá ser transformada em ``4, 3, 2, 1''. O programa deve:
(a)
solicitar ao usuário qual a coluna a ser invertida (ColVet);
(b)
copiar a coluna para um vetor; o tamanho da coluna já é sabido pois foi retornado por ColVet;
(c)
inverter o vetor (ver enunciado do Exercício 1 da Lista 10). Você deve usar um segundo vetor para isso;
(d)
copiar o vetor invertido por sobre a coluna inicial (VetCol).
Não é necessário usar funções ou procedimentos auxiliares além de ColVet e VetCol.

2.
Fazer uma macro que lê uma coluna em um vetor e mostra, numa janela, a linha e o valor da menor célula na coluna. A coluna em questão deve ser solicitada ao usuário, bem como a posição da primeira linha a ser considerada.

Você deve usar uma função auxiliar que recebe um vetor e retorna o índice da posição que contém o menor valor. Não se esqueça que este valor do índice não é o mesmo que o valor da linha que contém o menor valor, pois a linha inicial na coluna considerada não é necessariamente a primeira.


next up previous contents
Next: Ordenação Up: Técnicas de Programação Utilizando Previous: Trabalhando com Várias Planilhas
Flavio Soares Correa da Silva
2000-04-10