Caixa de listagem com dependência de Caixa de listagem

Com base neste arquivo exemplo do @Conras,

modelo adaptado do Excel para libreoffice.ods

Neste exemplo a lista de dados estão em uma tabela.

No meu caso as listas já estão separadas, como carregar os dados na cx de listagem2 com base no escolhido da cx de listagem1

Sei fazer com Validação, mas o arquivo em questão esta todo com opções de formulário, e gostaria de manter o padrão.


Por exemplo: na cx de listagem1 escolho o nome da área nomeada e na cx de listagem2 me mostra para escolha os dados da área escolhida.

1 Like

@schiavinatto Basta estruturar alguma planilha da seguinte forma:

Coluna com os dados que vai popular a cxlistagem01;

Seguindo com um exemplo de 05 itens para cxlistagem01, é necessário:

  1. Preencher 05 colunas, onde o cabeçalho será respectivamente cada item da cxlistagem01, e as demais linhas, será com os itens referente a este encadeamento;
  2. Em VB, criar sentença para popular a cxlistagem01, e guardar a informação em uma variável;
  3. Em VB, criar sentença com 02 loop. Primeira em horizontal, avaliando a variável da cxlistagem01, percorrendo os cabeçalhos das demais colunas. Segunda em vertical, para popular a cxlistagem02.

Faça esse procedimento para o número de “n” encadeamentos necessários.

Pode utilizar do until, do while ou for next como funções de loop. Todas irão funcionar.

Ps. Desculpe não colocar exemplo. Estou em viagem no momento.

Obrigado @Conras, pela dica.

Segue arquivo com possível solução:
Ask_AlimentarCaixaListaComCriterio.ods (73,0,KB)
.
Macro utilizada:

Sub CarregarCidades(oEvent, Optional evento)
Dim oPlan			As Object		' Planilha ativa
Dim oIntervalo	As Object	
Dim clEstado		As Object
Dim clCidade		As Object
Dim colecaoCidade As New Collection		'Objeto Collection - https://helponline.libreoffice.org/latest/pt-BR/text/sbasic/shared/collection.html?DbPAR=BASIC#bm_id3149205
Dim i&
Dim j%
Dim uf$, cidade$

	REM Obtem os controles pelo evento
	evento = oEvent.Source.Context
	For i = 0 To Ubound(evento.controls())
		Select Case evento.controls(i).Model.Name
			Case "clEstado" : clEstado = evento.controls(i)
			Case "clCidade" : clCidade = evento.controls(i)
		End Select
	Next i
	
	REM Planilha ativa
	oPlan = ThisComponent.CurrentController.ActiveSheet	
	
	REM Obtem o intervalo de dados em matriz (LEITURA MAIS RÁPIDA DE DADOS)
	i = 0
	j = 0
	Do Until oPlan.getCellByPosition(0, i).String = Empty
		i = i+1
		Do Until oPlan.getCellByPosition(j, 0).String = Empty
			j = j+1
		Loop
	Loop
	oIntervalo = oPlan.getCellRangeByPosition(0, 0, j, i).DataArray
	
	REM Obtem o Estado da Caixa de Lista
	uf = clEstado.SelectedItem
	
	REM Cria a coleção com elementos usando como chave o próprio item
	REM Repetir uma chave gera um erro, pois o índice deve ser único
	REM Usamos o tratamento de erro para pular o item que gerou o erro
	REM Isso faz com que os itens não se repitam no controle
	For i = 1 To UBound(oIntervalo())
		If oIntervalo(i)(1) = uf Then
			On Error Resume Next
			cidade = oIntervalo(i)(0)
			colecaoCidade.add (cidade, cidade)
		End If
	Next i
	
	REM Limpa a Caixa de Lista Cidades
	clCidade.Model.removeAllItems()
	
	REM Alimenta a Caixa de Lista Cidades
	For Each cidade In colecaoCidade
		clCidade.addItem( cidade, colecaoCidade.count )
	Next
	MsgBox "Cidades atualizadas!"
End Sub

----COMPLEMENTO-----
Arquivo com base na descrição abaixo:
Ask_ListBoxValidacao.ods (17,7,KB)
.
Código usado:

Sub AlimentarCaixaDeLista(oEvent, Optional oCtrl)
Dim oListBox1				As Object
Dim oListBox2				As Object
Dim oNamedRange		As Object
Dim sItem					As Variant
Dim sCriterio$
Dim i%, j%

	REM Obtem as Caixas de Lista por meio de evento
	oCtrl = oEvent.Source.Context.Controls
	For i = 0 To UBound( oCtrl() )
		Select Case oCtrl(i).Model.Name
			Case "Caixa de lista 1" : oListBox1 = oCtrl(i)
			Case "Caixa de lista 2" : oListBox2 = oCtrl(i)
		End Select
	Next i
	
	REM Obtem o texto/item
	sCriterio = oListBox1.SelectedItem
	
	REM Limpa a Caixa de Lista 2
	oListBox2.Model.removeAllItems()
	
	REM Obtem os intevalos nomeados
	oNamedRange = ThisComponent.NamedRanges
	
	REM Compara o intervalo nomeado com o criterio
	REM Se corresponder, obtem os dados em matriz
	REM Alimenta a Caixa de Lista
	For i = 0 To oNamedRange.Count-1
		If oNamedRange.ElementNames(i) = sCriterio Then
			sItem = oNamedRange.getByName(sCriterio).getReferredCells(i).DataArray
			For j = 0 To UBound(sItem())
				REM Dificuldade em ordenar crescente. 
				rem Solução: valor do parâmetro posição alto (A CAIXA PARA DE PREENCHER QUANDO ACABA OS ITENS)
				oListBox2.addItem(sItem(j)(0), 50)
			Next j
		End If
	Next i
End Sub
1 Like

Olá @FelipeAle, não é necessário filtragem, os dados já estaõ agrupados.

Vide imagem e arquivo modelo…

modelo.ods (16.0 KB)

OBS.: Cada TABELA esta em uma planilha.

Vide complemento.

Perfeito @FelipeAle , obrigado.