• Revista PROGRAMAR: Já está disponível a edição #56 da revista programar. Faz já o download aqui!

lynkyn_devil

Preencher automaticamente células no excel usando VBA

9 mensagens neste tópico

Boa tarde comunidade,

Ando a tentar trabalhar com o VBA no Excel de modo a tentar aplicar esse conhecimento na minha tese de mestrado, mas estou com algumas dúvidas.

Eu estou a tentar criar uma função em VBA que preencha células consoante um determinado valor. Na imagem seguinte tenho dois quadros, um com valores nos vértices e outro todo preenchido pelo valor 1. O quadro da esquerda, representa uma câmara de vigilância, que está na célula B1. No quadro da direita é suposto aparecer a área de cobertura dessa mesma câmara. A área da câmara ocupa 10 células.

O código que tenho é o seguinte:

Sub Limpar()
Range("G5:J8") = ""
End Sub

Sub Executar()
If Cells(5, "B").Value = 1 Then Preencher
End Sub

Sub Preencher()
Dim contador As Integer
contador = 10
Do While contador > 0
Range("G5:J8") = 1
contador = contador - 1
Loop
End Sub

E o seu resultado é este:

g6LeY.jpg

 

Como podem ver a minha função preenche tudo, e o objectivo era só preencher 10 células. O que pretendia era algo parecido ao que está na imagem seguinte:

 

HmRiX.jpg

 

Alguém sabe como fazer em VBA para no quadro da direita apresentar só o número de células preenchidas pela área da câmara? Que neste caso deveriam aparecer 10 células preenchidas. Eu sei que o meu código preenche o quadro todo, mas não era isso que eu estava a tentar, eu queria era preencher quadrícula a quadrícula até que perfizesse as 10 quadrículas correspondentes à área da câmara da célula B5.

Se eu conseguir para uma câmara, provavelmente conseguirei para outras câmaras de áreas diferentes e colocadas em vértices diferentes.

Obrigado para quem me ajudar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

No ciclo "Do While" estás a dizer para preencher sempre aquele Range enquanto for vazio.

Utiliza o ciclo "For ... Next"  nos valores 71 a 74, decrementando 1 em cada ciclo, para te definir as colunas. Carater 71=Letra G e os valores 5 a 8 para definir as linhas.

Mais ou menos isto:
 

Private Sub CommandButton1_Click()
Dim X As Integer, Y As Integer

For X = 74 To 71 Step -1
    Y = 5
        Range(Chr(X) & Y).Value = 1
Next X
For X = 73 To 71 Step -1
    Y = 6
        Range(Chr(X) & Y).Value = 1
Next X
For X = 72 To 71 Step -1
   Y = 7
        Range(Chr(X) & Y).Value = 1
Next X
For X = 71 To 71
   Y = 8
        Range(Chr(X) & Y).Value = 1
Next X

End Sub

 

Estas linhas de código permitem-te obter o resultado que pretendes.

Para outras câmaras, consegues com facilidade bastando alterar os nºs que vão compor o range que pretendes utilizar.

Editado por manuel antonio
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bom dia e obrigado pela resposta,

Eu estive a implementar o seu código e o resultado é o esperado e o que pretendia.

Pelo que percebi, somos nós que definimos quais as células que ficam preenchidas, neste caso em forma de triângulo. E se a câmara ocupar 15 células?

Alguma maneira de preencher as células automaticamente? Tenho umas 15 câmaras e quase todas tem áreas de cobertura diferentes, então eu nunca sei em que vértice as câmaras vão ficar.

A câmara 1 ocupa 10 células e a câmara 2 ocupa 15 células, o objectivo era preencher as células vazias até o 10 ou o 15 chegar a zero. E que qualquer uma das câmaras pode ficar em 1 dos 4 vértices do quadro da esquerda. Estou a tentar explicar-me o melhor possível. O solver coloca as câmaras automaticamente nos vértices, eu só queria que a área coberta pelas câmaras aparecesse no quadro da direita, consoante o tipo de câmara e a localização da mesma. Será isso possível de se obter?

Sou bastante novo em VBA.

Seria possível eu enviar-lhe o documento original do excel onde tenho a minha formulação e onde pretendo implementar o código em VBA? Pode ser que assim consiga entender melhor a situação.

Editado por lynkyn_devil
Adicionei texto que faltava
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boa tarde.

4 horas atrás, lynkyn_devil disse:

Pelo que percebi, somos nós que definimos quais as células que ficam preenchidas, neste caso em forma de triângulo. E se a câmara ocupar 15 células?

Obviamente nenhum computador tem capacidade para adivinhar onde queremos que ele mostre os resultados. Temos que ser nós a dizer-lhe. O exemplo que enviei foi em função das células que tens na imagem que enviaste. Se quiseres mudar a folha ou a localização, tens que informar o Excell e para isso conversas com ele via VBA.

4 horas atrás, lynkyn_devil disse:

Alguma maneira de preencher as células automaticamente? Tenho umas 15 câmaras e quase todas tem áreas de cobertura diferentes, então eu nunca sei em que vértice as câmaras vão ficar.

É claro que há. Apenas depende do que pretendes dizer com automaticamente...

Quando queres ter luz na sala, pressionas o interruptor e a luz acende-se automaticamente. No Excell ... faz-se clik num botão ou noutro objeto.

Mas automaticamente também pode ser em função de um temporizador, que alterna desta para aquela câmara. Se for este o caso não tenho conhecimentos para te ajudar, mas podes pesquisar como implementar um "timer".

Tudo no entanto funciona em função de condições. Essas condições és tu que as defines. O raciocínio para a área das câmaras é sempre o mesmo apenas mudas as linhas e colunas onde queres ver apresentados os resultados.

Depois de obteres o código para cada uma é só implementar condições.

Se a câmara 1 estiver ativa, utilizar a rotina A. Se estiver ativa a 2, utilizar a rotina B e assim sucessivamente.

4 horas atrás, lynkyn_devil disse:

O solver coloca as câmaras automaticamente nos vértices, eu só queria que a área coberta pelas câmaras aparecesse no quadro da direita, consoante o tipo de câmara e a localização da mesma. Será isso possível de se obter?

Mas o "solver" não coloca câmaras diferentes no mesmo vértice pois não? Não alterna de uma câmara com alcance de 10 células para uma  câmara com alcance de 15 células?

4 horas atrás, lynkyn_devil disse:

Pelo que percebi, somos nós que definimos quais as células que ficam preenchidas, neste caso em forma de triângulo. E se a câmara ocupar 15 células?

Neste caso, como se vê com facilidade, deixas de ter um Quadrado de 4 por 4 e passas a ter um de 5 por 5. Obviamente aumentas uma coluna e uma linha.

Utilizas o sentido ascendeste ou descendente dos números que representam as colunas, dependendo da orientação que queres dar ao triângulo que representa a área de cobertura.

O que falei até aqui, refere-se apenas às duas câmaras superiores.

Para as câmaras inferiores, o ciclo "FOR" é preenchido com os nºs das linhas passando a constante a ser o nº da coluna.

4 horas atrás, lynkyn_devil disse:

Seria possível eu enviar-lhe o documento original do excel onde tenho a minha formulação e onde pretendo implementar o código em VBA? Pode ser que assim consiga entender melhor a situação.

Por enquanto vais pensar um pouco na situação e tentar levar a água ao teu moinho. Além disso eu precisava que os meus dias tivessem 30 horas.

Olha para o exemplo e desenvolve os restantes.

Depois se verá.

 

 

 

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
2 horas atrás, manuel antonio disse:

Mas o "solver" não coloca câmaras diferentes no mesmo vértice pois não? Não alterna de uma câmara com alcance de 10 células para uma  câmara com alcance de 15 células?

Por acaso é mesmo isso que ele faz. O "solver" coloca as câmaras todas em todos os vértices, de modo a encontrar a melhor solução. No meu exemplo ele coloca as duas câmaras nos quatro vértices e após algumas iterações, o "solver" indica-me a melhor combinação possível, neste caso coloca uma câmara no vértice de cima. Por isso é que eu nunca sei qual a câmara que será escolhida.

É algo do género, tenho um ponto fixo, e queria que os pontos adjacentes ficassem preenchidos consoante um determinado número.

Foi como disse, liga o interruptor e a luz é ligada, mas a luz tem um foco, inicia-se na lâmpada e vai desvanecendo consoante o alcance. essa área que a lâmpada ilumina altera-se dependendo o tipo de lâmpada.

Tenho o quadrado do lado direito, tenho a câmara no vértice, as células adjacentes, deviam preencher-se consoante a área da câmara. Ou seja, o número de células mais perto da câmara preenchem-se pela área da câmara, que aqui são 10 quadrículas.

Antes de mais, quero agradecer pelo seu tempo que tem gasto a ajudar-me.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Imaginemos que são 4 câmaras, 1 em cada vértice nomeadas dessa forma. A câmara 1, a câmara 2, a 3 e a 4. O dito "solver", pode colocar no vértice superior esquerdo a câmara 1 e ao fim de algum tempo, colocar a 4? É isso? E a ser assim, como pretendes distingui-las? Colocando a ocupar a área correspondente à câmara, em vez do nº 1 colocar o nº da câmara respetiva?

1 hora atrás, lynkyn_devil disse:

É algo do género, tenho um ponto fixo, e queria que os pontos adjacentes ficassem preenchidos consoante um determinado número.

Isso fica resolvido com o código que te enviei, incluindo para as outras câmaras com as devidas alterações nos nºs. Até porque se não fossem fixas, chamavam-se drones.

1 hora atrás, lynkyn_devil disse:

Foi como disse, liga o interruptor e a luz é ligada, mas a luz tem um foco, inicia-se na lâmpada e vai desvanecendo consoante o alcance. essa área que a lâmpada ilumina altera-se dependendo o tipo de lâmpada.

Aquilo que eu quis dizer com o interruptor não tem nada a haver com o foco de luz. Quis dizer que há algo que despoleta a situação. Pelo que depreendo das tuas palavras o que faz acionar o "solver" é o click num botão? Certo?

O que há a fazer, é um bloco de código para cada vértice a contemplar as 4 câmaras e sujeitar o código às condições necessárias.

A instrução "if" serve para isso, assim tipo:

if activecell=1 then

     call camara1 (a rotina estaria gravada num módulo e dá-se-lhe o nome camara1)

elseif activecell=2 then

     call camara2 (a rotina estaria gravada num módulo e dá-se-lhe o nome camara2)

elseif activecell=3 then

     call camara3

else

     call camara4

end if

Aparentemente não é difícil.

Vai tentando SFF

Entretanto, em mensagem particular, enviei-te o meu e-mail. Tenta enviar o ficheiro e vou ver o que posso fazer.

 

Editado por manuel antonio
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bom dia,

Eu resolvia a questao da seguinte forma :

  • para cada camara uma matriz de preenchimento, isto é , para a camara A dizia quais as celulas que seriam preenchidas se a camara A ocupa 5, 8, 10 ou seja o que for.... de forma a ficar do genero  https://ibb.co/e89uXv

De seguida , dependendo do facto da camara ser 1 ou zero, e consoante as celulas que a mesma preenche, neste caso estao todas 10 nas celulas m2,m3,m4 .... o codigo preenche a matriz de destino ....

Sub Executa()

Dim Matriz1 As Variant
Dim Matriz2 As Variant
Dim Matriz3 As Variant
Dim Matriz4 As Variant

'limpa matriz de destino
ActiveSheet.Range("g5:j8").Value = ""

'carrega as matrizes de acordo com o desejado
Matriz1 = CarregaMatriz(5, 8, 15, 18, 5, 15)
Matriz2 = CarregaMatriz(5, 8, 20, 23, 5, 20)
Matriz3 = CarregaMatriz(5, 8, 25, 28, 5, 25)
Matriz4 = CarregaMatriz(5, 8, 30, 33, 5, 30)

'carrega a matriz de destino de acordo com as camaras e com os vertices
Call CarregaMatrizDestino(ActiveSheet.Range("b5").Value, ActiveSheet.Range("m2").Value, Matriz1)
Call CarregaMatrizDestino(ActiveSheet.Range("e5").Value, ActiveSheet.Range("m3").Value, Matriz2)
Call CarregaMatrizDestino(ActiveSheet.Range("b8").Value, ActiveSheet.Range("m4").Value, Matriz3)
Call CarregaMatrizDestino(ActiveSheet.Range("e8").Value, ActiveSheet.Range("m5").Value, Matriz4)

End Sub

Sub CarregaMatrizDestino(ByRef Vertice, ByRef Camara, ByRef Matriz)

If Vertice = 1 Then
    For i = 1 To 4
       For j = 1 To 4
        If Matriz(i - 1, j - 1) <= Camara Then
            Cells(i + 4, j + 6).Value = 1
        End If
        Next
    Next
End If
End Sub

Function CarregaMatriz(ByRef IInicial, ByRef IFinal, ByRef JInicial, ByRef JFinal, ByRef AcertoLinha, ByRef AcertoColuna) As Variant

Dim Matriz(4, 4) As Integer

For X = IInicial To IFinal
    For z = JInicial To JFinal
            Matriz(X - AcertoLinha, z - AcertoColuna) = Cells(X, z)
           
    Next
Next

CarregaMatriz = Matriz
End Function

 

Editado por Antonio Silva Magalhaes
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Obrigado pela resposta.

Testei a sua maneira e já está bastante parecido com o que pretendo.

A câmara A, pode estar em qualquer um dos vértices, certo?

 

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
4 horas atrás, lynkyn_devil disse:

Obrigado pela resposta.

Testei a sua maneira e já está bastante parecido com o que pretendo.

A câmara A, pode estar em qualquer um dos vértices, certo?

 

Boa tarde.

Sim, cada uma das matrizes simula a posição da camara em cada um dos vértices. Se olhares para a matriz repara que o numero 1 , em cada uma delas, representa o vértice onde ela se localiza. Mais , como está  podes ter mais que uma camara "activa" em cada um dos vertices que simula o ambiente criado pelas duas ou tres camaras em conjunto.

Se colocares "1" no vértice superior esquerdo e "1" no vértice superior direito, por exemplo,  do range("B5;E7") , o que acontece é que simulas a existencia de duas camaras , uma no canto superior direito e outra no canto superior esquerdo, assim https://ibb.co/eZMEFF

O resultado final esta na Matriz Destino como podes ver.

Abraço

 

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora