Ciao Lavedure,
Non ho nessun modo per provare il seguente codice nel ambiente Mac ma
funziona senza la necessità di riferimenti esterni e ti chiederei di
provarlo.
• Alt+F11 per aprire l'editor di VBA
• Alt+IM per inserire un nuovo modulo di codice
• Nel nuovo modulo vuoto, incolla il seguente codice:
'===========>>
Option Explicit
'------------------------------
'\\ Code by Greg Wilson:
'\\ http://
http://goo.gl/CTna2X
''-----------------------------
Dim Abort As Boolean
'----------->>
Public Sub FindCombins()
Dim a As Long, b As Long, c As Long
Dim d As Long, e As Long, f As Long
Dim g As Long, h As Long, i As Long
Dim j As Long, x As Long, y As Long
Dim s1 As Long, s2 As Long, s3 As Long
Dim s4 As Long, s5 As Long, s6 As Long
Dim s7 As Long, s8 As Long, s9 As Long
Dim s10 As Long, col As Long
Dim Resp As Integer, Style As Integer
Dim v As Single, v0 As Single, Ar() As Double
Dim cell As Range
Dim txt As String, Title As String
Dim t1 As Date, t2 As Date
Title = "Find Combinations"
s1 = 0: s2 = 0: s3 = 0: s4 = 0: s5 = 0
s6 = 0: s7 = 0: s8 = 0: s9 = 0: s10 = 0
On Error GoTo SkipToHere
If Selection.Count < 9 Then
txt = "Errore: un minimo di nove valori devono essere " _
& " selezionat!!! "
MsgBox txt, vbCritical, Title
Exit Sub
End If
txt = "Questa macro troverà le combinazioni della corrente" _
& "- selezione di celle che che hanno un totale uguale " _
& "al valore specificato." _
& vbCr & vbCr _
& "- È supportato un massimo di 10 elementi in combinazione" _
& vbCr _
& "- Un minimo di 9 valori devono essere selezionato" _
& vbCr _
& "- La scelta può essere non contigua" _
& vbCr _
& "- Solo valori numerici devono essere selezionati" _
& vbCr _
& "- Valori duplicati dovrebbero essere rimossi dalla " _
& "selezione" _
& "per evitare risultato duplicati"
Style = vbInformation + vbOKCancel
Resp = MsgBox(txt, Style, Title)
If Resp = vbCancel Then Exit Sub
col = ActiveCell.Column
ReDim Ar(0 To Selection.Count)
Ar(0) = 0
i = 1
For Each cell In Selection.Cells
Ar(i) = cell.Value
i = i + 1
Next
Ar = SortArray(Ar)
Call FindDupes(Ar)
If Abort Then Exit Sub
txt = vbCr & vbCr & "Specify target value:"
With Application
v0 = .InputBox(txt, Title)
If v0 = 0 Then Exit Sub
.ScreenUpdating = False
End With
t1 = Now
ActiveCell.EntireColumn.Insert
x = 0
y = UBound(Ar)
'xxxxxxxxxxxx Start Loop xxxxxxxxxx
For a = s1 To y - 9: For b = a + s2 To y - 8
For c = b + s3 To y - 7: For d = c + s4 To y - 6
For e = d + s5 To y - 5: For f = e + s6 To y - 4
For g = f + s7 To y - 3
For h = g + s8 To y - 2
For i = h + s9 To y - 1
For j = i + s10 To y
v = Ar(a) + Ar(b) + Ar(c) _
+ Ar(d) + Ar(e) _
+ Ar(f) + Ar(g) _
+ Ar(h) + Ar(i) + Ar(j)
If v = v0 Then
x = x + 1
txt = GetText( _
Ar(a), Ar(b), Ar(c), _
Ar(d), Ar(e), _
Ar(f), Ar(g), _
Ar(h), Ar(i), _
Ar(j))
Cells(x, col) = txt
txt = ""
ElseIf v > v0 Then
Exit For
End If
s10 = 1
Next:
s9 = 1
Next:
s8 = 1
Next
s7 = 1
Next
s6 = 1
Next
s5 = 1
Next:
s4 = 1
Next
s3 = 1
Next
s2 = 1
Next
s1 = 1
Next
'xxxxxxxxxxxx End Loop xxxxxxxxxxxxxx
SkipToHere:
Columns(col).EntireColumn.AutoFit
t2 = Now
If x > 2 ^ 20 Then
txt = "Too many combinations found. Max capacity 2^20. "
Style = vbExclamation
ElseIf x = 0 Then
Columns(col).Delete
If Err.Number = 0 Then
txt = "Non sono state trovate combinazioni pari a " _
& v0 & " "
Else
txt = "Un errore ha causato la macro di fallire. " _
& vbCr & vbCr _
& "- Assicurarsi che la selezione non include " _
& "dei valori " _
& "non numerici" _
& vbCr _
& "- Assicurarsi che un minimo di sette valori " _
& "sono " _
& "stati selezionati" _
& vbCr & _
"- Assicurarsi che i valori numerici non sono " _
& "preceduti da apostrofi"
End If
Style = vbExclamation
Else
txt = "Combinazioni trovate eguagliando " _
& v0 & " = " & x & " " _
& vbCr & vbCr & _
"Hours = " & Hour(t2 - t1) & vbCr & _
"Minutes = " & Minute(t2 - t1) & vbCr & _
"Seconds = " & Second(t2 - t1)
Style = vbOKOnly
End If
ActiveCell.Select
Application.ScreenUpdating = True
MsgBox txt, Style, Title
End Sub
'----------->>
Private Function GetText(a As Double, b As Double, c As Double, _
d As Double, e As Double, f As Double, _
g As Double, h As Double, _
i As Double, j As Double) As String
Dim Ar As Variant
Dim x As Integer
Dim t As String
Ar = Array(a, b, c, d, e, f, g, h, i, j)
For x = 9 To 0 Step -1
If Ar(x) = 0 Then Exit For
t = " + " & Ar(x) & t
Next
GetText = Right(t, Len(t) - 3)
End Function
'----------->>
Private Function SortArray(Ar As Variant) As Variant
Dim i As Integer, j As Integer
Dim Temp As Double
For i = LBound(Ar) To UBound(Ar) - 1
For j = (i + 1) To UBound(Ar)
If Ar(i) > Ar(j) And Ar(i) <> 0 Then
Temp = Ar(j)
Ar(j) = Ar(i)
Ar(i) = Temp
End If
Next j
Next i
SortArray = Ar
End Function
'----------->>
Private Sub FindDupes(Ar As Variant)
Dim i As Integer, ii As Integer, cnt As Integer
Dim val As Double
Dim ar2() As Variant
Dim ar3() As Variant
Dim txt As String, txt2 As String
Dim Style As Integer
Dim Resp As Integer
Dim Dupes As Boolean
Dupes = False
Abort = False
ii = 0
For i = LBound(Ar) + 1 To UBound(Ar)
If Ar(i) = Ar(i - 1) Then
Dupes = True
cnt = 0
val = Ar(i)
ReDim Preserve ar2(ii)
ReDim Preserve ar3(ii)
ar2(ii) = Ar(i)
Do Until Ar(i) <> Ar(i - 1)
i = i + 1
cnt = cnt + 1
If i = UBound(Ar) Then Exit Do
Loop
ar3(ii) = cnt + 1
ii = ii + 1
End If
Next
If Not Dupes Then Exit Sub
For i = LBound(ar2) To UBound(ar2)
txt2 = txt2 & "Value: " & ar2(i) _
& " Repetitions: " & ar3(i) & vbCr
Next
txt = "Duplicate values found in selection:" _
& vbCr & txt2 & vbCr & vbCr _
& "La presenza di duplicati rallenterà le prestazioni " _
& "e non serve a nulla." & _
vbCr & vbCr & "Continue ?"
Resp = MsgBox(txt, vbOKCancel + vbExclamation, _
"Find Combinations")
If Resp = vbCancel Then Abort = True
End Sub
'<<===========
• Alt+Q per chiudere l'editor di VBA e tornare a Excel
• Salva il file con l’estensione xlsm
• Alt+F8 per aprire la finestra di gestione delle macro
• Seleziona FindCombins | Esegui
Ti ho inviato il tuo file aggiornato con questo codice,
Per eseguire il codice, seleziona nove valori e premi il pulsante. Se i
valori da sommare fossero meno di nove, potresti inserisci altri valori,
ognuno superiore al totale di interesse, altrove e quindi completare la
selezione sfruttando questi altri valori. Eventualmente, forse potrei
modificare il codice per evitare che sia necessario selezionare nove
valori. Comunque. precediamo un passo alla volta - si deve prima
verificare il codice nel tuo ambiente Mac!
===
Regards,
Norman