Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 19
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14

    [VBA EXCEL 2003/2007] Domandine stupide su matrici

    Ciao ragazzi, devo risolvere un problemino idiota, ma sono pochissimi giorni che studio vba da autodidatta e non capisco come fare.

    Ho generato una matrice con numeri random 0,1 e devo calcolare le somme così:
    - sulla diagonale principale
    - sulla diagonale secondaria
    - sui bordi

    Inoltre dovrei anche costruire un vettore che restituisca ordinati tutti i valori della matrice partendo dal vertice in alto a sx andando verso destra sul bordo, continuando a scendere sul bordo e così via completando la matrice a spirale (il secondo giro quindi inizierà in posizione cells(2,1) passando a cells 2,2 fino ad arrivare a cells(2, n-1) per poi scendere, spero di essermi spiegato).

    Mi sono bloccato subito al primo problema.
    Vi posto il codice che ho provato a scrivere:

    **********************************
    Private Sub prova_matrix()
    Dim h As Integer, l As Double, n As Integer, matrix() As Integer, somma() As Integer

    Cells(1, 8) = "altezza matrix >"
    Cells(2, 8) = "lunghezza matrix quanto lunga >"
    l = Cells(1, 9)
    h = Cells(2, 9)

    ReDim matrix(1 To h, 1 To l)


    For i = 1 To h
    For j = 1 To l
    matrix(i, j) = (Rnd * 1)
    Cells(i, j) = matrix(i, j)
    Next j
    Next i



    ReDim somma(i, j)

    For i = 1 To n
    For i = 1 To n
    For j = 1 To n
    If i = j Then somma(i, j) = somma(i, j) + Cells(i, j)
    Next j
    Next i
    Cells(10, 1) = somma(i, j)
    End Sub
    **********************************



    nota bene: ho messo le dimensioni in 1,8 e 2,8 solo per semplificare il calcolo, ovviamente in questa maniera posso per ora solo scrivere matrici piccole...ma era per capire il meccanismo, dopo posizionerò la matrice in modo che possa essere nxm senza che le caselle di definizione di n ed m diano fastidio

    GRAZIE A CHIUNQUE RISPONDA!!!

  2. #2
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14
    primo quesito risolto.
    Ho capito che non serve mettere somma (i,j) e definirla come una variabile

    Basta creare un "contatore" che parta da 0 prima del ciclo for
    (ad esempio scrivere semplicemente somma=0) e poi farlo incrementare ovviamente con i valori assunti da Cells(i,j) grazie al ciclo for nel caso in cui i=j-------> ossia nel caso in cui ci troviamo nella diagonale principale della Matrice.

    Nota: sto scrivendo solo perché forse qualche altro neofita come me ne potrebbe trovare giovamento. So benissimo che per voi è quasi offensivo leggere queste cose.

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14
    Sempre per completezza scrivo la "soluzione" del secondo quesito:

    'calcolo diagonale secondaria**************************
    sommabis = 0
    For i = 1 To h
    For j = 1 To l
    If i = (l + 1 - j) Then sommabis = sommabis + Cells(i, j)
    Next j
    Next i

    Il ciclo If serve in questo caso a individuare i casi in cui si abbia che l'indice i di riga sia associato all'indice j di colonna in questo senso: per i=1 j=l, per i=2, j=l-1, per i=3, j=l-2......per i=h (ossia dimensione massima, chiamatela n), j=1.

  4. #4
    Ciao,
    interessanti i tuoi quesiti.

    Per la prima parte ti posto il codice che utilizzerei io e poi te lo illustro rapidamente visto che è poco che usi VBA.


    codice:
    Private Sub CommandButton1_Click()
    
            Worksheets("Foglio2").Activate
    
            Dim d As Integer, i, j, Casella, SommaAx, SommaBx, SommaSx, SommaDx, SommaD1, SommaD2
            
            With Worksheets("Foglio2")
                .Range(.Cells(1, 1), .Cells(20, 20)).Value = ""
            End With
            
            SommaAx = 0
            SommaBx = 0
            SommaSx = 0
            SommaDx = 0
            SommaD1 = 0
            SommaD2 = 0
            
            Randomize
                    
            d = InputBox("Lato matrice")
            
            For i = 1 To d
                For j = 1 To d
                    Cells(i, j) = Int((Rnd * 2))
                Next j
            Next i
            
    
            For Each Casella In Range(Cells(1, 1), Cells(d, d))
               If Casella.Row = 1 Then
                   SommaAx = SommaAx + Casella.Value
               End If
               If Casella.Row = d Then
                   SommaBx = SommaBx + Casella.Value
               End If
               If Casella.Column = 1 Then
                   SommaSx = SommaSx + Casella.Value
               End If
               If Casella.Column = d Then
                   SommaDx = SommaDx + Casella.Value
               End If
               If Casella.Row = Casella.Column Then
                   SommaD1 = SommaD1 + Casella.Value
               End If
               If Casella.Row + Casella.Column = d + 1 Then
                   SommaD2 = SommaD2 + Casella.Value
               End If
            Next
            
            [h1].Value = SommaAx
            [h2].Value = SommaBx
            [h3].Value = SommaSx
            [h4].Value = SommaDx
            [h5].Value = SommaD1
            [h6].Value = SommaD2
    
    
    End Sub

    come vedi l'ho associato ad un pulsante (CommandButton1) ma questo è solo per mia comodità di prove.

    La activate non è proprio necessaria, serve a definire una volta per tutte in quale foglio si sta lavorando per evitare di doverlo ripetere ogni volta che serve nel resto del codice.

    Appena comincio pulisco un'area di 20 x 20 e inizializzo le sei variabili che conterranno le sei somme (Alto, Basso, Sinistra, Destra, Diagonale1, Diagonale2).

    Segue l'istruzione randomize che genera una nuova sequenza casuale. Questo equivale a "mescolare le carte" mentre la RND si limita a "distribuirle".

    Poi chiedo all'utente con una inputbox di indicare il lato che dovrà avere la matrice di numeri.
    Per poter parlare di diagonale la matrice dev'essere quadrata quindi chiedo un solo valore, credo che averne 2 (h ed l) come avevi fatto tu sia scorretto.

    Ho modificato anche la RND per non ottenere dei valori decimali (che poi falsano le somme).

    Il cuore di tutto è la For Each che esplora, casella per casella, un range. In questo caso il range va da (1,1) a (d,d).
    All'interno di questo ciclo individuo se la casella appartiene a un lato o a una digonale e incremento il corrispondente contatore che poi visualizzo nelle caselle h1, h6.

    Per la spirale invece devo pensarci un po' perché non è tanto facile. Il fatto è che, per mia soddisfazione personale, voglio trovare una formula generale da inserire nella for each che permetta di assegnare ad ogni cella, partendo dalle sue coordinate la posizione finale che avrà nell'array dei risultati.

    Nei prossimi giorni ti farò sapere qualcosa.

    Spero di esserti stato utile.

    Ciao
    La democrazia rappresentativa ha fatto il suo tempo, è ora di passare alla democrazia diretta.
    www.beppegrillo.it

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14
    Again, calcolo sui bordi

    'calcolo bordi con ciclo if

    sommater = 0
    For i = 1 To h
    For j = 1 To l
    If j = 1 Or j = l Or i = 1 Or i = h Then sommater = sommater + Cells(i, j)
    Next j
    Next i

    **************************************

    e poi vabè mettere sommater in output.
    Basta fare un ciclo if con tutti i casi estremi (1 o l, 1 o h)

    ADESSO QUALCOSA DI PIù DIFFICILE, PER CUI RICHIEDO AIUTO DAVVERO.
    VOGLIO ORDINARE TUTTI GLI ELEMENTI SUI BORDI E METTERLI IN OUTPUT IN COLONNA
    E POI FARE LA STESSA COSA, COME HO SPIEGATO PRIMA, PARTENDO DA UN ANGOLO E PROCEDENDO A SPIRALE (questa è bella)

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14
    Grazie mille, stavo scrivendo mentre scrivevi.
    Molto interessante, ora me lo studio e poi nel caso commenterò....
    Ciao

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14
    NOn riesco proprio ad ordinare tutti gli elementi della matrice in una sola colonna.
    Qualche indizio?

  8. #8
    Penso di riuscire a darti la soluzione domani in serata, spero che tu possa aspettare.
    Ora devo andare
    Ciao
    La democrazia rappresentativa ha fatto il suo tempo, è ora di passare alla democrazia diretta.
    www.beppegrillo.it

  9. #9
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14
    Si, certo, come no, gentilissimo, anche troppo

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    14
    Sono riuscito ad incolonnare i numeri che stanno sui bordi.
    Ma è una soluzione molto insoddisfacente.
    Prima di tutto ho utilizzato ben 4 cicli for, poi l'ordine dell'incolonnamento è il seguente:
    - colonna di sinistra
    - ultima colonna
    - numeri sulla prima riga compresi fra la prima e l'ultima colonna, escluse la prima e l'ultima
    - numeri sull'ultima riga compresi fra la prima e l'ultima colonna, escluse la prima e l'ultima

    codice:
    'numeri sui bordi incolonnati
    'definizione del vettore incolonnamento
    ReDim vettore(1 To (h * l))
    
    'il primo ciclo for per la prima colonna e per l'ultima colonna
    For i = 1 To h
        For j = 1 To l
            If j = 1 Then
            vettore(i) = Cells(i + 4, j)
            Cells(i, l + 4) = vettore(i)
            End If
            If j = l Then
            vettore(i) = Cells(i + 4, j)
            Cells(i + h, l + 4) = vettore(i)
            End If
        Next j
    Next i
    
    
    ' il secondo ciclo for per la prima e l'ultima riga
    For i = 1 To h
        For j = 1 To l
            If j <> 1 And j <> l And i = 1 Then
            vettore(i) = Cells(i + 4, j)
            Cells((j - 1) + (2 * h), l + 4) = vettore(i)
            End If
            If j <> 1 And j <> l And i = h Then
            vettore(i) = Cells(i + 4, j)
            Cells((j - 1) + (3 * h) - 2, l + 4) = vettore(i)
            End If
        Next j
    Next i
    L'obiettivo è invece avere questo ordinamento:
    - tutta la prima riga
    - tutta l'ultima colonna, senza il primo elemento (già mandato in output ovviamente)
    - tutta l'ultima riga PARTENDO DA DESTRA, OSSIA DALLA FINE per tornare alla prima colonna
    - tutta la prima colonna, dalla penultima riga (l'ultima è già mandata in output) alla seconda riga (la casella 1x1 è già in output da prima)

    In colori traduco:
    voglio che il vettore venga, nell'ordine: green-orange-red-blue
    xxxxxxxxx
    x---------x
    x---------x
    x---------x
    x---------x
    x---------x
    x---------x
    xxxxxxxxx

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.