Moderatori: Anthony47, Flash30005
Sub Differenze()
Dim myStart As String, myDiff As String, I As Long, J As Long
Dim myLast As Long, myCol As Long
'
myStart = "A2" '<< La cella in cui comincia l' elenco
myDiff = "B1" '<< La cella in cui e' scritta la differenza da cercare
'
myLast = Range(myStart).End(xlDown).Row
myCol = Range(myStart).Column
Range(Range(myStart).Offset(0, 1), Cells(myLast, myCol + 1).Resize(, Columns.Count - myCol)).ClearContents
For I = Range(myStart).Row To myLast '- 1
' For J = I + 1 To myLast
For J = Range(myStart).Row To myLast
If Abs(Cells(I, myCol) - Cells(J, myCol)) = Range(myDiff).Value Then
Cells(I, Columns.Count).End(xlToLeft).Offset(0, 1) = Cells(J, myCol)
End If
Next J
Next I
End Sub
Il caso che poni e' molto piu' semplice ...
...accanto a ogni numero dell' elenco saranno riportati, in orizzontale, i numeri quella differenza.
Sub Differenza(ByVal DifF As Long)
Dim myStart As String, myDiff As String, I As Long, J As Long
Dim myLast As Long, myCol As Long
'
myStart = "B2" '<< La cella in cui comincia l' elenco
'myDiff = "B1" '<< La cella in cui e' scritta la differenza da cercare
myLast = Range(myStart).End(xlDown).Row
myCol = Range(myStart).Column
Range(Range(myStart).Offset(0, 1), Cells(myLast, myCol + 1).Resize(, Columns.Count - myCol)).ClearContents
For I = Range(myStart).Row To myLast '- 1
' For J = I + 1 To myLast
For J = Range(myStart).Row To myLast
' If Abs(Cells(I, myCol) - Cells(J, myCol)) = Range(myDiff).Value Then
If Abs(Cells(I, myCol) - Cells(J, myCol)) = DifF Then
Cells(I, Columns.Count).End(xlToLeft).Offset(0, 1) = Cells(J, myCol)
End If
Next J
Next I
End Sub
Sub multidiff()
Dim mySource As String, myDiff As String, DifF
mySource = "Foglio1" '<< Il foglio con l' elenco e le differenze
myDiff = "A2:A50" '<< L' intervallo con le differenze
'
Sheets(mySource).Select
For I = Worksheets.Count To ActiveSheet.Index + 1 Step -1
' Application.DisplayAlerts = False '<< Vedi Testo
Sheets(I).Delete
Next I
Application.DisplayAlerts = True
'
For Each DifF In Range(myDiff)
If DifF <> 0 Then
Differenza (DifF)
Sheets(mySource).Copy After:=Sheets(Worksheets.Count)
ActiveSheet.Name = "Diff-" & DifF
Sheets(mySource).Select
End If
Next DifF
End Sub
Non so quale e' l' uso di questo lavoro, quindi prendo per buona l' ipotesi di creare tanti fogli con le differenze ...
'QUESTE VANNO OBBLIGATORIAMENTE IN CIMA AL MODULO
Public myStart As String, myLast As Long, myCol As Long
Public myArres() As Variant
Public Const myDiff As String = "A2:A10" '<< L' intervallo con le differenze
Sub Differenza2(ByVal DifF As Long)
Dim I As Long, J As Long
'
Range(Range(myStart).Offset(0, 1), Cells(myLast, myCol + 1).Resize(, Columns.Count - myCol)).ClearContents
For I = Range(myStart).Row To myLast '- 1
For J = Range(myStart).Row To myLast
If Abs(Cells(I, myCol) - Cells(J, myCol)) = DifF Then
Cells(I, Columns.Count).End(xlToLeft).Offset(0, 1) = Cells(J, myCol)
End If
Next J
Next I
End Sub
Sub multidiffArr()
Dim mySource As String, DifF
'
myStart = "B2" '<< La cella in cui comincia l' elenco
mySource = "Foglio12" '<< Il foglio con l' elenco e le differenze
'
Sheets(mySource).Select
myLast = Range(myStart).End(xlDown).Row
myCol = Range(myStart).Column
'(eliminato il codice che cancellava i fogli)
'
ReDim myArres(1 To Range(myDiff).Rows.Count)
Range(myStart).Offset(-1, 1).Value = "Ricalcolo della matrice in corso...."
For Each DifF In Range(myDiff)
jJ = jJ + 1
If DifF <> 0 Then
Differenza2 (DifF)
myArres(jJ) = Application.Intersect(Range(myStart).CurrentRegion, Range(Range(myStart).Offset(0, 1), Cells(myLast, myCol + 1).Resize(, Columns.Count - myCol))).Value
End If
Next DifF
Range(myStart).Offset(-1, 1).Value = "<<< Elenco delle differenze >>>"
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Application.Intersect(Target, Range(myDiff)) Is Nothing Then Exit Sub
ReDim myArres(0)
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim AaA
'myDiff = "A2:A10" '<< L' intervallo con le differenze
If Application.Intersect(Target, Range(myDiff)) Is Nothing Or Target.Count > 1 Then Exit Sub
On Error Resume Next
AaA = UBound(myArres, 1)
On Error GoTo 0
If IsEmpty(AaA) Or AaA = 0 Then Call multidiffArr
Range(Range(myStart).Offset(0, 1), Cells(myLast, myCol + 1).Resize(, Columns.Count - myCol)).ClearContents
Range(myStart).Offset(-1, 1).Value = "<<< Elenco per Delta = " & Target.Value & " >>>"
If Target.Value <> 0 Then
Mioff = Application.Match(Target.Value, Range(myDiff), 0)
Range(myStart).Offset(0, 1).Resize(UBound(myArres(Mioff), 1), UBound(myArres(Mioff), 2)).Value = myArres(Mioff)
End If
End Sub
Non so quale e' l' uso di questo lavoro, quindi prendo per buona l' ipotesi di creare tanti fogli ...
.Essa determina quali numeri di un insieme di N numeri, calcolati a gruppi di 1, di 2, di 3, ... di N, danno una certa somma.
Il caso che poni e' molto piu' semplice perche' si tratta di calcolare una differenza tra ognuno dei numeri e ognuno dei restanti (quindi sempre a coppie) e controllare se il risultato e' quello impostato
Un risultato puo' essere ottenuto tramite infinite sottrazioni diverse ...
..ti troveresti con una macro che non si fermera' mai
Forse stai parlando di cercare le combinazioni in un elenco di valori
Avendo concluso che l' obiettivo e' ricercare i risultati tra un elenco definito di numeri dovresti gia' avere l' esempio di cosa intendevo per "delimitare il campo di variabilità"se fai un piccolo esempio mi sarà più chiaro.
Dim VArr, WkArr(), WkIndex(), I As Integer, J As Integer, maxCol As Long, FlExit As Boolean
Dim Kappa As Integer, WResult As String, TgVal As Long, LastLev As Long, II As Long, NElem As Integer
Dim myCCurr As Long, DataCol As Long, maxCombin As Long
Sub CercaDiff()
'V1 B31018
'
Dim diffVal As Long, xyI As Long
DataCol = 2 '<<< La colonna che contiene i dati da esaminare; 1=A, 2=B, etc
maxCol = 200 '<<< N° max di match
maxCombin = 20000000 '<<< N° max di combinazioni che saranno testate
VArr = Range(Cells(2, DataCol), Cells(Rows.Count, DataCol).End(xlUp))
NElem = UBound(VArr, 1)
ReDim WkArr(NElem): ReDim WkIndex(NElem)
Cells(1, DataCol + 1).Resize(NElem + 1, Columns.Count - 1 - Cells(1, DataCol).Column).Clear
diffVal = InputBox("Valore Differenza (intero positivo)?")
sTimer = Timer
For xyI = 2 To NElem
If Cells(xyI, DataCol) > diffVal Then
Call CercaCombV1(Cells(xyI, DataCol), diffVal)
End If
Next xyI
MsgBox ("Completato in " & Format(Timer - sTimer, "0.0") & " Secondi" & vbCrLf & "Rilevati " & _
Application.WorksheetFunction.CountA(Cells(1, DataCol).Resize(1, Columns.Count - DataCol - 1 - 1)) _
& " match" & vbCrLf & mexflex)
End Sub
Sub CercaCombV1(ByVal myCurr As Long, myDiff As Long)
'Rev. 1
'B31018
myCCurr = myCurr
TgVal = myCurr - myDiff
Dim Col2H As Double, Col2K As Double
'
''DataCol = 2 '<<< La colonna che contiene i dati da esaminare; 1=A, 2=B, etc
''maxCol = 23 '<<< N° max di match
''maxCombin = 20000000 '<<< N° max di combinazioni che saranno testate
'
FlExit = False
If maxCol > Columns.Count Then maxCol = Columns.Count - 3
''TgVal = (InputBox("Valore target?"))
''TgVal = Val(Replace(TgVal, ",", ".")) 'Gestisce decimale sia "punto" che "virgola"
''VArr = Range(Cells(2, DataCol), Cells(Rows.Count, DataCol).End(xlUp))
''NElem = UBound(VArr, 1)
''ReDim WkArr(NElem): ReDim WkIndex(NElem)
''Cells(1, DataCol + 1).Resize(NElem + 1, Columns.Count - 1 - Cells(1, DataCol).Column).Clear
'
LastLev = 3
For I = 1 To NElem - 1
'modificato per calcolare anche il tot delle combinazioni (uso di Col2K e II)
Col2H = Col2H + Evaluate("FACT(" & NElem & ")/FACT(" & I & ")/FACT(" & NElem - I & ")")
If Col2H <= maxCombin Then Col2K = Col2H - 1: II = I
If Col2H <= maxCombin Then Gruppidi = Gruppidi & " " & I
Next I
'Rispo = MsgBox("Il valore target e': " & TgVal _
& vbCrLf & "Impostato max combinazioni: " & Round(MaxCombin / 1000000, 1) & " Milioni" _
& vbCrLf & "N° di combinazioni massime che saranno testate: " & Col2K - _
Evaluate("FACT(" & NElem & ")/FACT(" & I & ")/FACT(" & NElem - I & ")") & vbCrLf _
& "(Combinazione di " & NElem & " elementi a gruppi di " & Gruppidi & ")" & vbCrLf _
& "Massimo " & maxCol & " risultati" & vbCrLf _
& "(Corrispondente al " & Int(Col2K / Col2H * 100) & "% delle possibili combinazioni)" & vbCrLf _
& vbCrLf & "OK per procedere, CANCEL per annullare e modificare i parametri", vbOKCancel)
If Rispo = vbCancel Then Exit Sub
UserForm1.Show vbModeless
''sTimer = Timer
'
If TgVal = 0 Then GoTo ZeroVal
'
For LastLev = 1 To II + 1
For J = 0 To NElem
WkArr(J) = "": WkIndex(J) = ""
Next J
Call Recur(1, NElem, 1)
DoEvents '???
Next LastLev
If FlExit = True Then mexflex = "(stop per limite di colonne massime da riportare)"
ZeroVal:
Unload UserForm1
''MsgBox ("Completato in " & Format(Timer - sTimer, "0.0") & " Secondi" & vbCrLf & "Rilevati " & _
Application.WorksheetFunction.CountIf(Range("1:1"), "x") _
& " match" & vbCrLf & mexflex)
End Sub
Sub Recur(ByVal Iniz As Integer, ByVal Final As Integer, ByVal myLevel As Integer)
Dim myI As Integer, myK As Integer
For myI = Iniz To (Final - LastLev + myLevel)
GoTo XYz
aaa = WkArr(1): bbb = WkIndex(1)
aaa = WkArr(2): bbb = WkIndex(2)
aaa = WkArr(3): bbb = WkIndex(3)
aaa = WkArr(4): bbb = WkIndex(4)
XYz:
WkArr(myLevel) = VArr(myI, 1)
WkIndex(myLevel) = myI
'aaa = Application.WorksheetFunction.Sum(WkArr())
If myLevel = LastLev Then 'Or (Round(Application.WorksheetFunction.Sum(WkArr()), 3)) > Round(TgVal, 3) Then
'If Application.WorksheetFunction.Sum(WkArr()) > 161270.7 Then Stop
'aaa = Application.WorksheetFunction.Sum(WkArr())
If Round(Application.WorksheetFunction.Sum(WkArr()), 3) = Round(TgVal, 3) And FlExit = False Then
Cells(1, Columns.Count).End(xlToLeft).Offset(0, 1) = myCCurr
mycol = Cells(1, Columns.Count).End(xlToLeft).Column
If mycol > maxCol Then FlExit = True
For myK = 1 To LastLev
Cells(WkIndex(myK) + 1, mycol) = 1 'WkIndex(myK)
Next myK
End If
Else
If Round(Application.WorksheetFunction.Sum(WkArr()), 3) > TgVal Then
' Stop
GoTo SkNxLev
' Exit For
End If
Call Recur(myI + 1, NElem, myLevel + 1)
End If
If FlExit = True Then Exit For
SkNxLev:
Next myI
WkArr(myLevel) = ""
End Sub
Torna a Applicazioni Office Windows
differenza fra orari MA con 1 eccezione Autore: raimea |
Forum: Applicazioni Office Windows Risposte: 7 |
formattare una colonnacon numeri senza virgolaSalve Autore: giorgioa |
Forum: Applicazioni Office Windows Risposte: 5 |
Come nascondere I Numeri non Appartenenti Al Mese Deside Autore: Maury170419 |
Forum: Applicazioni Office Windows Risposte: 3 |
Visitano il forum: Nessuno e 13 ospiti