Importare dati da una matrice su 2 listbox

Anonimo
2016-06-21T09:57:27+00:00

Buongiorno a tutti,

avrei bisogno di un aiuto nel creare una routine per caricare dei dati in due listbox in funzione di due condizioni.

Venendo al dunque, ho su una userform 3 listbox, nella prima un elenco di nomi e gradi che sono le colonne A e B del foglio di lavoro.

Nelle intestazioni delle altre colonne ci sono 30 corsi in 30 colonne. Nell'incrocio tra le colonne e le righe ho se quel determinato corso è obbligatorio oppura raccomandato per la persona selezionata.

Quindi al momento che clicco su una persona vorrei che una routine spazzoli tutti i corsi ed ad ogni intersezione con la riga mi inserisca quelli obbligatori in una listbox e quelli raccomandati nella seconda listbox. Ovviamente se l'intersezione risulta vuota non aggiunge nessun corso. Spero di essere stato chiaro nella spiegazione e vi allego una parte della tabella con i dati mensionati.

Anticipatamente ringrazio

Saluti

Giuseppe

JOB TITLE SURMANE & NAME PERSONAL SURVIVAL TECNIQUES STCW A-VI/1-1 FIRE PREVENTION AND FIREFIGHTING STCW  A-VI/1-2 ELEMENTARY FIRST AID STCW A-VI/1-3 PERSONAL SAFETY & SOCIAL RESPONSIBILIES STCW A-VI/1-4 PROFICENCY IN SURVIVAL CRAFTS AND RESCUE BOATS (other than fast rescue boat) STCW A-VI/2<br>(7*) ADVANCED FIRE FIGHTING STCW A-VI/3 (7*) FAST RESCUE BOATS STCW  A-VI/2 MEDICAL FIRST AID STCW A-VI/4-1 MEDICAL CARE STCW A-VI/4-2 GMDSS STCW A- IV/2
Master LANGELLA GIUSEPPE M M M M M M M M
Master CASTELLANO GIUSEPPE M M M M M M M M
Chief Mate PITINO SALVATORE M M M M M M R M M
Chief Mate SEKULJA RAJKO M M M M M M R M M
2nd Mate PERSIANO RAFFAELE M M M M M M R R R M
2nd Mate LANDINI ANDREA M M M M M M R R R M
3rd Mate BAZIN ALEKSANDR M M M M M M R R R M
3rd Mate FILIPCIUK ANDREJ M M M M M M R R M
Chief Engineer ANICHINI FEDERICO M M M M M M R
Chief Engineer RIVANO VICTOR M M M M M M R
1st Engineer SOLARI FABIO M M M M M M R R
1st Engineer MORGERA GIUSEPPE M M M M M M R R
2nd Engineer FAVATELLA ANTONIO M M M M M M R R
2nd Engineer LUCIA LUIGI M M M M M M R R
2nd Engineer SENYAK YURIY M M M M R R R R
Microsoft 365 e Office | Excel | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento
Risposta accettata dall'autore della domanda
Anonimo
2016-06-23T00:28:30+00:00

Prova a vedere questo file di esempio (#5) dove alla UserForm ho aggiunto delle ListBox dedicate alle "intestazioni multiple" e dove ho modificato i comandi nell'evento Initialize della user.

Se poi tu volessi impostare anche la larghezza delle colonne potresti dichiarare delle costanti di testo con le misure desiderate e poi assegnare quelle misure alle rispettive TextBox (sia quelle dedicate a contenere i dati veri e propri che quelle dedicate a contenere le intestazioni multiple). In questo modo avresti i dati sempre allineati.

Questo il nuovo file: File esempio #5

Questo il codice, all'interno della User, che ho modificato per tener conto delle ListBox che fanno da intestazione.

'---

Private Sub UserForm_Initialize()

  Dim sLB_Header_MaritimeCrew As Variant

  Dim sLB_Header_CertificateOnBoard As Variant

  Dim sLB_Header_CertificateExpired As Variant

  sLB_Header_MaritimeCrew = Array("Grado", "Cognome e Nome", "Badge Nr")

  sLB_Header_CertificateOnBoard = Array("Certificato", "Data Scadenza")

  sLB_Header_CertificateExpired = Array("Certificato", "Data Scadenza", "Giorni scadenza")

  Set Wb = ThisWorkbook

  With Wb

    Set Ws1 = .Worksheets(sNameWs1)

    Set Ws1Rng1 = Ws1.Range(sWs1Rng1)

    Set CR1 = Ws1Rng1.CurrentRegion

    NumRowCR1 = CR1.Rows.Count

    NumColumnCR1 = CR1.Columns.Count

    Set Ws2 = .Worksheets(sNameWs2)

    Set Ws2Rng1 = Ws2.Range(sWs2Rng1)

    Set CR2 = Ws2Rng1.CurrentRegion

    NumRowCR2 = CR2.Rows.Count

    NumColumnCR2 = CR2.Columns.Count

  End With

  DataOdierna = Date

  With Me

    With .LB_MaritimeCrew

      .List() = CR1.Offset(1, 0).Resize(NumRowCR1 - 1, 3).Value

      .ColumnCount = 3

    End With

    With .LB_Header_MaritimeCrew

      .Column() = sLB_Header_MaritimeCrew

      .ColumnCount = 3

    End With

    With .LB_Header_CertificateOnBoard

      .Column() = sLB_Header_CertificateOnBoard

      .ColumnCount = 2

    End With

    With .LB_Header_CertificateExpired

      .Column() = sLB_Header_CertificateExpired

      .ColumnCount = 3

    End With

    .LB_CertificateOnBoard.ColumnCount = 2

    .LB_CertificateExpired.ColumnCount = 3

  End With

End Sub

'---

p.s. mi sono accorto che avevo nominato la listbox dei certificati scaduti LB_CertificateExipired (con una i dopo la x) e ho provveduto a modificare il nome della TextBox e i relativi riferimenti nel codice con LB_CertificateExpired

p.p.s questo l'aspetto grafico della UserForm con le listbox delle intestazioni colorate di "giallo chiaro"

![](http://fud.community.services.support.microsoft.com/Fud/FileDownloadHandler.ashx?fid=c6cd949e-07d5-4a2d-9cfc-4e1045bce1c3)

La risposta è stata utile?

0 commenti Nessun commento
Risposta accettata dall'autore della domanda
Anonimo
2016-06-22T21:16:50+00:00

Dopo la partita dell'Italia, un po' deludente a dire il vero, ti propongo questo file esempio (il quarto :-) ) dove ho inserito una UserForm2.

File esempio #4

Tutto il codice (così Mauro non mi cazzia :-D) è presente all'interno della UserForm2.

Alle ListBox ho dato dei nomi "particolari" (LB_MaritimeCrew, LB_Mandatory, LB_Racommended, LB_CertificateOnBoard, LB_CertificateExipired).

Questo il codice presente all'interno della UserForm2 (caricabile tramite il pulsante presente nel Foglio1).

'---

Option Explicit

Const sNameWs1 As String = "Foglio1"

Const sWs1Rng1 As String = "A1"

Const sNameWs2 As String = "Foglio2"

Const sWs2Rng1 As String = "A1"

Dim Wb As Workbook

Dim Ws1 As Worksheet

Dim Ws1Rng1 As Range

Dim CR1 As Range

Dim NumRowCR1 As Integer

Dim NumColumnCR1 As Integer

Dim Ws2 As Worksheet

Dim Ws2Rng1 As Range

Dim CR2 As Range

Dim NumRowCR2 As Integer

Dim NumColumnCR2 As Integer

Dim DataOdierna As Date

Private Sub UserForm_Initialize()

  Set Wb = ThisWorkbook

  With Wb

    Set Ws1 = .Worksheets(sNameWs1)

    Set Ws1Rng1 = Ws1.Range(sWs1Rng1)

    Set CR1 = Ws1Rng1.CurrentRegion

    NumRowCR1 = CR1.Rows.Count

    NumColumnCR1 = CR1.Columns.Count

    Set Ws2 = .Worksheets(sNameWs2)

    Set Ws2Rng1 = Ws2.Range(sWs2Rng1)

    Set CR2 = Ws2Rng1.CurrentRegion

    NumRowCR2 = CR2.Rows.Count

    NumColumnCR2 = CR2.Columns.Count

  End With

  DataOdierna = Date

  With Me

    With .LB_MaritimeCrew

      .List() = CR1.Offset(1, 0).Resize(NumRowCR1 - 1, 3).Value

      .ColumnCount = 3

    End With

    .LB_CertificateOnBoard.ColumnCount = 2

    .LB_CertificateExipired.ColumnCount = 3

  End With

End Sub

Private Sub LB_MaritimeCrew_Click()

  Dim sJobTitle As String

  Dim sNomePersonale As String

  Dim rngFindCorsiJobTitle As Range

  Dim rngFindCorsiPersonale As Range

  Dim i As Integer, t As Integer

  With Me

    .LB_Mandatory.Clear

    .LB_Racommended.Clear

    .LB_CertificateOnBoard.Clear

    .LB_CertificateExipired.Clear

  With .LB_MaritimeCrew

    sJobTitle = .List(.ListIndex, 0)

    sNomePersonale = .List(.ListIndex, 1)

  End With

  Set rngFindCorsiJobTitle = CR2.Resize(NumRowCR2, 1).Find(What:=sJobTitle, After:=Ws2Rng1, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows)

  Set rngFindCorsiPersonale = CR1.Resize(NumRowCR1, 2).Find(What:=sNomePersonale, After:=Ws1Rng1.Offset(0, 1), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows)

    For i = 1 To NumColumnCR2 - 1

      If UCase(rngFindCorsiJobTitle.Offset(0, i).Value) = "M" Then

        .LB_Mandatory.AddItem Ws2Rng1.Offset(0, i).Value

      End If

      If UCase(rngFindCorsiJobTitle.Offset(0, i).Value) = "R" Then

        .LB_Racommended.AddItem Ws2Rng1.Offset(0, i).Value

      End If

        For t = 1 To NumColumnCR1 - 3

          If Ws1Rng1.Offset(0, t + 2).Value = Ws2Rng1.Offset(0, i).Value Then

            If rngFindCorsiPersonale.Offset(0, t + 1).Value <> "" Then

              If IsDate(rngFindCorsiPersonale.Offset(0, t + 1).Value) And _

                 UCase(rngFindCorsiJobTitle.Offset(0, i).Value) = "M" Then '<------------

                If rngFindCorsiPersonale.Offset(0, t + 1).Value > DataOdierna + 90 Then

                  With .LB_CertificateOnBoard

                    .AddItem

                    .List(.ListCount - 1, 0) = Ws1Rng1.Offset(0, t + 2).Value

                    .List(.ListCount - 1, 1) = rngFindCorsiPersonale.Offset(0, t + 1).Value

                  End With

                Else

                  With .LB_CertificateExipired

                    .AddItem

                    .List(.ListCount - 1, 0) = Ws1Rng1.Offset(0, t + 2).Value

                    .List(.ListCount - 1, 1) = rngFindCorsiPersonale.Offset(0, t + 1).Value

                    .List(.ListCount - 1, 2) = rngFindCorsiPersonale.Offset(0, t + 1).Value - DataOdierna

                  End With

                End If

              Else

                With .LB_CertificateOnBoard

                  .AddItem

                  .List(.ListCount - 1, 0) = Ws1Rng1.Offset(0, t + 2).Value

                  .List(.ListCount - 1, 1) = rngFindCorsiPersonale.Offset(0, t + 1).Value

                End With

              End If

            Else

              If UCase(rngFindCorsiJobTitle.Offset(0, i).Value) = "M" Then

                With .LB_CertificateExipired

                  .AddItem

                  .List(.ListCount - 1, 0) = Ws1Rng1.Offset(0, t + 2).Value

                  .List(.ListCount - 1, 1) = "To be done"

                  .List(.ListCount - 1, 2) = "!!!!!"

                End With

              End If

            End If

          End If

        Next t

    Next i

  End With

End Sub

'---

Prova a verificare se riesce a fare ciò che è nelle tue intenzioni.

La risposta è stata utile?

0 commenti Nessun commento

68 risposte aggiuntive

Ordina per: Meno recente
  1. Anonimo
    2016-06-22T16:00:09+00:00

    Se ho inteso.

    Tu vuoi che se selezioni una riga della ListBox1 (contenente JobTitle, Cognome/Nome,Badge) vengano caricati nalla ListBox Mandatory per il relativo JobTitle tutti i corsi presenti nel foglio2 per cui sia indicato M.

    Nella ListBox Racommended per il relativo JobTitle tutti i corsi presenti nel foglio2 per cui sia indicato R.

    E questo a prescindere che siano presenti o meno nel foglio1?

    Poi solo per la ListBox Mandatory vuoi che vengano popolate le altre due ListBox ma solo se l'eventuale corso selezionato sia presente tra le intestazioni presenti nel foglio1.

    Inserendo nella ListBox "3" il nome del corso e la data di scadenza per il soggetto selezionato.

    Nella ListBox "4" oltre al nome del corso e la data di scadenza anche il numero di giorni trascorsi dalla data di scadenza alla data attuale.

    E' così?

    Oppure vuoi che anche le altre due ListBox vengano popolate automaticamente quando si seleziona una riga della sola ListBox1?

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2016-06-22T20:09:04+00:00

    Ciao Casanmaner,

    mi dilungo un po' perche' le mie spiegazioni non sono state eccelse e quindi se non capite il principio di cio' che voglio fare, vi faccio solo impazzire con me.

    Come avete visto dalle tabelle, stiamo parlando di corsi obbligatori e raccomandati in base al grado che si copre per poter lavorare a bordo delle piattaforme.

    Quindi sul foglio1 ho la lista di crew member con tutti i certificati possibili nelle colonne.

    Nel foglio2 ho solo la Matrice ufficiale corporate come riferimento che mi dice in base ad ogni grado coperto a bordo quali sono i corsi obbligatori e raccomandati.

    Pertanto il foglio di lavoro effettivo e' il foglio1, il foglio2 serve solo da verifica per dividere gli obbligatori dai raccomandati, inoltre e' quello dinamico in quanto devo aggiornare le date dei corsi quando vengono fatti i refresh, eliminare o aggiungere crew member se sbarcano o se imbarcano per la priva volta ed aggiungere corsi o eliminarli se cambia la matrice corporate. Detto questo veniamo a come vorrei impostare le list box, la prima, a sinistra, carica l'elenco dal foglio1 con il nome e cognome, grado e badge number. Al momento che seleziono un qualsiasi nome dalla listbox1, in funzione del suo grado, si dovrebbe popolare la listbox2 e 3 in automatico che riferendosi al grado selezionato mi dividera' i corsi mandatory e racommended nelle due listbox come richiesto ieri. Allo stesso momento la listbox3 verifica per ogni singolo corso caricato nella listbox1 (Mandatory) se sul foglio1 esistono le date per quel corso. Se esistono le date, carica il corso e la data relativa. Inoltre se la data e' compresa tra oggi e +90 giorni oppure e proprio scaduto, invece di caricarlo nella listbox3 lo carica nella listbox4 riportandomi che il corso e' scaduto o in scadenza, la data ad esso associato e quanti giorni mancano o da quanto e' scaduto. Se infine non e' proprio presente la data, il corso riferito alla data assente viene riportato nella listbox4 con la dicitura "To be done". Questo controllo mi serve ovviamente solo sui mandatory proprio perche' sono mandatory e quindi per legge non posso avere personale a bordo senza certificati o scaduti e l'avviso dei 90 giorni prima della scadenza mi serve in modo da avere un immediato controllo e organizzare i refresh.  Per quanto riguarda i racommended, se la persona selezionata li ha mi interessa che vengano visualizzati nella listbox3 insieme ai mandatory con la stessa metodologia anche per la listbox4, se invece non dovesse averli, in parte o tutti, non mi interessa la dicitura "To be done" in quanto non implicano l'imbarco della detta persona. Spero di aver meglio reso l'idea della funzionalita' di queste listbox.

    Grazie per la vostra pazienza

    Ciao

    Giuseppe

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2016-06-22T22:55:05+00:00

    Grande !!!!

    Hai capito perfettamente dove volevo arrivare ;)

    Adesso un'ultima chicca su questo file. Sul precedente, per intestare le listbox ho usato delle label, dato che ho sempre usato la proprietà ColumnHeads della list box sfruttando le intestazioni dei fogli di lavoro, qui come ben sai non posso. Sarebbe possibile dichiarare cosa voglio che venga scritto in ogni listbox come intestazione della stessa? Ovviamente sarà: Titolo certificato - data di scadenza - giorni rimasti ecc......

    Per la partita non ne parliamo proprio. 

    Io adesso sono in Indonesia a lavoro e quindi sono a +6 dall'Italia e d'inverno a +7 !!!!

    Quindi ho messo la mia bella sveglia alle 02:45 del mattino.

    Per fortuna mi hai sorridere tu con il codice che desideravo.

    Buon riposo a tutti, io ho iniziato il mio Giovedì di lavoro.

    La risposta è stata utile?

    0 commenti Nessun commento