ExcelBanter

ExcelBanter (https://www.excelbanter.com/)
-   Excel Programming (https://www.excelbanter.com/excel-programming/)
-   -   find result - only for expert (https://www.excelbanter.com/excel-programming/316808-find-result-only-expert.html)

mark

find result - only for expert
 
Hi,
I looking for best min_result in table below:

Name Data Distance
A 2.5 150
B 6.5 250
A 5.6 123
A 9.5 121
B 3.5 120
B 4.8 150
A 6.8 200

min_result = sum of three min (the least) data (column 2)
for Name in column 1.

Important remark!!!
Necessary condition: Distance (sum in column 3) of those
three data must be 500.
Min_result can be higher result if nacessary condition
can't be perform.
Is there any way to resolve my problem?
Any help will be appreciate.
Regards
Mark


Tom Ogilvy

find result - only for expert
 
Can you sort your data on the "Data" column ascending? Then you take the
first 3 sequential cells that sum to greater than 500.

--
Regards,
Tom Ogilvy



"Mark" wrote in message
...
Hi,
I looking for best min_result in table below:

Name Data Distance
A 2.5 150
B 6.5 250
A 5.6 123
A 9.5 121
B 3.5 120
B 4.8 150
A 6.8 200

min_result = sum of three min (the least) data (column 2)
for Name in column 1.

Important remark!!!
Necessary condition: Distance (sum in column 3) of those
three data must be 500.
Min_result can be higher result if nacessary condition
can't be perform.
Is there any way to resolve my problem?
Any help will be appreciate.
Regards
Mark




ManualMan

find result - only for expert
 
Tom/Mark,

The problem appears to be that this min_result should be calculated
*for each* name in Column A. The problem isn't exactly clear to me on
one point however:

If the condition sum(distance)500 isn't met, there are 3 possible
outcomes:

1. take one extra row until the total 500 (so more than 3 rows)
2. drop the row with the smallest value in Distance and take the next
that has a higher value in Distance (so the amount of rows remains 3)
3. drop the row with the highest value in Data (from the 3 lowest) and
find the nearest lowest Data row

Which is it?


Ron Rosenfeld

find result - only for expert
 
On Mon, 15 Nov 2004 03:53:30 -0800, "Mark" wrote:

Hi,
I looking for best min_result in table below:

Name Data Distance
A 2.5 150
B 6.5 250
A 5.6 123
A 9.5 121
B 3.5 120
B 4.8 150
A 6.8 200

min_result = sum of three min (the least) data (column 2)
for Name in column 1.

Important remark!!!
Necessary condition: Distance (sum in column 3) of those
three data must be 500.
Min_result can be higher result if nacessary condition
can't be perform.
Is there any way to resolve my problem?
Any help will be appreciate.
Regards
Mark


Will this UDF do what you want? The arguments are the desired name (or cell
reference to that name) and the table (as a range or a named range).

=================================
Function foo(Name As String, tbl As Range) As Double
Dim NmDt()
Dim c As Range
Dim i As Integer, j As Integer
Dim col As Long, rw As Long
Const MinDistance As Double = 500

'Get Data and Distance for Name

col = tbl.Column
rw = tbl.Row

For i = rw To rw + tbl.Rows.Count - 1
If Cells(i, col).Text = Name Then
ReDim Preserve NmDt(1, j)
NmDt(0, j) = Cells(i, col + 1) 'Data
NmDt(1, j) = Cells(i, col + 2) 'Distance
j = j + 1
End If
Next i

'Sort array by distance

Call BubbleSort2(NmDt, 1)

For i = 0 To UBound(NmDt, 2) - 2
If NmDt(1, i) + NmDt(1, i + 1) + NmDt(1, i + 2) MinDistance Then
foo = NmDt(0, i) + NmDt(0, i + 1) + NmDt(0, i + 2)
End If
If foo 0 Then Exit For
Next i

End Function


Sub BubbleSort2(TempArray As Variant, Optional D As Variant) 'D is dimension to
sort on, 1-based

Dim Temp As Variant
Dim i As Integer, j As Integer
Dim NoExchanges As Integer
Dim NumDim As Long

If IsMissing(D) Then D = 1
D = D - 1

'determine number of dimensions
On Error GoTo ErrorNumDim
For j = 1 To 60
Temp = UBound(TempArray, j)
If NumDim 0 Then Exit For
Next j
On Error GoTo 0

' Loop until no more "exchanges" are made.
Do
NoExchanges = True

' Loop through each element in the array.
For i = 0 To UBound(TempArray, 2) - 1

' If the element is greater than the element
' following it, exchange the two elements.
If TempArray(D, i) TempArray(D, i + 1) Then
NoExchanges = False
Temp = TempArray(D, i)
TempArray(D, i) = TempArray(D, i + 1)
TempArray(D, i + 1) = Temp
For j = 0 To NumDim - 1
If j < D Then
Temp = TempArray(j, i)
TempArray(j, i) = TempArray(j, i + 1)
TempArray(j, i + 1) = Temp
End If
Next j
End If
Next i
Loop While Not (NoExchanges)
Exit Sub

ErrorNumDim: If Err.Number = 9 Then
NumDim = j - 1
On Error GoTo 0
End If
Resume Next

End Sub

=============================

--ron

Ron Rosenfeld

find result - only for expert
 
The comment below in the UDF:

'Sort array by distance

Should read:

'Sort array by Data

Obviously, makes no difference in how it functions.

--ron



On Mon, 15 Nov 2004 17:15:25 -0500, Ron Rosenfeld
wrote:

On Mon, 15 Nov 2004 03:53:30 -0800, "Mark" wrote:

Hi,
I looking for best min_result in table below:

Name Data Distance
A 2.5 150
B 6.5 250
A 5.6 123
A 9.5 121
B 3.5 120
B 4.8 150
A 6.8 200

min_result = sum of three min (the least) data (column 2)
for Name in column 1.

Important remark!!!
Necessary condition: Distance (sum in column 3) of those
three data must be 500.
Min_result can be higher result if nacessary condition
can't be perform.
Is there any way to resolve my problem?
Any help will be appreciate.
Regards
Mark


Will this UDF do what you want? The arguments are the desired name (or cell
reference to that name) and the table (as a range or a named range).

=================================
Function foo(Name As String, tbl As Range) As Double
Dim NmDt()
Dim c As Range
Dim i As Integer, j As Integer
Dim col As Long, rw As Long
Const MinDistance As Double = 500

'Get Data and Distance for Name

col = tbl.Column
rw = tbl.Row

For i = rw To rw + tbl.Rows.Count - 1
If Cells(i, col).Text = Name Then
ReDim Preserve NmDt(1, j)
NmDt(0, j) = Cells(i, col + 1) 'Data
NmDt(1, j) = Cells(i, col + 2) 'Distance
j = j + 1
End If
Next i

'Sort array by distance

Call BubbleSort2(NmDt, 1)

For i = 0 To UBound(NmDt, 2) - 2
If NmDt(1, i) + NmDt(1, i + 1) + NmDt(1, i + 2) MinDistance Then
foo = NmDt(0, i) + NmDt(0, i + 1) + NmDt(0, i + 2)
End If
If foo 0 Then Exit For
Next i

End Function


Sub BubbleSort2(TempArray As Variant, Optional D As Variant) 'D is dimension to
sort on, 1-based

Dim Temp As Variant
Dim i As Integer, j As Integer
Dim NoExchanges As Integer
Dim NumDim As Long

If IsMissing(D) Then D = 1
D = D - 1

'determine number of dimensions
On Error GoTo ErrorNumDim
For j = 1 To 60
Temp = UBound(TempArray, j)
If NumDim 0 Then Exit For
Next j
On Error GoTo 0

' Loop until no more "exchanges" are made.
Do
NoExchanges = True

' Loop through each element in the array.
For i = 0 To UBound(TempArray, 2) - 1

' If the element is greater than the element
' following it, exchange the two elements.
If TempArray(D, i) TempArray(D, i + 1) Then
NoExchanges = False
Temp = TempArray(D, i)
TempArray(D, i) = TempArray(D, i + 1)
TempArray(D, i + 1) = Temp
For j = 0 To NumDim - 1
If j < D Then
Temp = TempArray(j, i)
TempArray(j, i) = TempArray(j, i + 1)
TempArray(j, i + 1) = Temp
End If
Next j
End If
Next i
Loop While Not (NoExchanges)
Exit Sub

ErrorNumDim: If Err.Number = 9 Then
NumDim = j - 1
On Error GoTo 0
End If
Resume Next

End Sub

=============================

--ron


--ron

Ron Rosenfeld

find result - only for expert
 
To enter the UDF that I posted:

<alt<F11 opens the Visual Basic Editor.
Ensure your project is highlighted in the Project Explorer Window, then
Insert/Module.

Paste the code below into the window that opens.

To USE the UDF, in some cell enter a formula:

=foo(A1,tbl) where A1 contains the Name, and tbl is the range consisting of the
Table.


--ron


On Mon, 15 Nov 2004 03:53:30 -0800, "Mark" wrote:

Hi,
I looking for best min_result in table below:

Name Data Distance
A 2.5 150
B 6.5 250
A 5.6 123
A 9.5 121
B 3.5 120
B 4.8 150
A 6.8 200

min_result = sum of three min (the least) data (column 2)
for Name in column 1.

Important remark!!!
Necessary condition: Distance (sum in column 3) of those
three data must be 500.
Min_result can be higher result if nacessary condition
can't be perform.
Is there any way to resolve my problem?
Any help will be appreciate.
Regards
Mark


Will this UDF do what you want? The arguments are the desired name (or cell
reference to that name) and the table (as a range or a named range).

=================================
Function foo(Name As String, tbl As Range) As Double
Dim NmDt()
Dim c As Range
Dim i As Integer, j As Integer
Dim col As Long, rw As Long
Const MinDistance As Double = 500

'Get Data and Distance for Name

col = tbl.Column
rw = tbl.Row

For i = rw To rw + tbl.Rows.Count - 1
If Cells(i, col).Text = Name Then
ReDim Preserve NmDt(1, j)
NmDt(0, j) = Cells(i, col + 1) 'Data
NmDt(1, j) = Cells(i, col + 2) 'Distance
j = j + 1
End If
Next i

'Sort array by distance

Call BubbleSort2(NmDt, 1)

For i = 0 To UBound(NmDt, 2) - 2
If NmDt(1, i) + NmDt(1, i + 1) + NmDt(1, i + 2) MinDistance Then
foo = NmDt(0, i) + NmDt(0, i + 1) + NmDt(0, i + 2)
End If
If foo 0 Then Exit For
Next i

End Function


Sub BubbleSort2(TempArray As Variant, Optional D As Variant) 'D is dimension to
sort on, 1-based

Dim Temp As Variant
Dim i As Integer, j As Integer
Dim NoExchanges As Integer
Dim NumDim As Long

If IsMissing(D) Then D = 1
D = D - 1

'determine number of dimensions
On Error GoTo ErrorNumDim
For j = 1 To 60
Temp = UBound(TempArray, j)
If NumDim 0 Then Exit For
Next j
On Error GoTo 0

' Loop until no more "exchanges" are made.
Do
NoExchanges = True

' Loop through each element in the array.
For i = 0 To UBound(TempArray, 2) - 1

' If the element is greater than the element
' following it, exchange the two elements.
If TempArray(D, i) TempArray(D, i + 1) Then
NoExchanges = False
Temp = TempArray(D, i)
TempArray(D, i) = TempArray(D, i + 1)
TempArray(D, i + 1) = Temp
For j = 0 To NumDim - 1
If j < D Then
Temp = TempArray(j, i)
TempArray(j, i) = TempArray(j, i + 1)
TempArray(j, i + 1) = Temp
End If
Next j
End If
Next i
Loop While Not (NoExchanges)
Exit Sub

ErrorNumDim: If Err.Number = 9 Then
NumDim = j - 1
On Error GoTo 0
End If
Resume Next

End Sub

=============================

--ron


--ron

mark

find result - only for expert
 
Hi Ron!

You code is very smart i've managed and appeared correct
result.
I've one more question:
My table has thousands rows and tens columns.
How to show in another sheet data perform neccesary
condition for all Name in column)? The form data could be
e.g.:

Min_result for A = 4.8, Distance = 530
Name Data Distance Data_in_Column7 (additionally)
A 1.2 150 Xrt
A 2.2 280 Yur
A 1.4 100 Opu

'two rows below is next Name perform condition

Min_result for B = 6,2, Distance = 620
Name Data Distance Data_in_Column7 (additionally)
A 2.2 240 Pok
A 2.4 280 Utr
A 1.6 100 Opu

etc.. next Name in column 1


Thanks for your professional help!
Best Regards
Mark




-----Original Message-----
To enter the UDF that I posted:

<alt<F11 opens the Visual Basic Editor.
Ensure your project is highlighted in the Project

Explorer Window, then
Insert/Module.

Paste the code below into the window that opens.

To USE the UDF, in some cell enter a formula:

=foo(A1,tbl) where A1 contains the Name, and tbl is the

range consisting of the
Table.


--ron


On Mon, 15 Nov 2004 03:53:30 -0800, "Mark"

wrote:

Hi,
I looking for best min_result in table below:

Name Data Distance
A 2.5 150
B 6.5 250
A 5.6 123
A 9.5 121
B 3.5 120
B 4.8 150
A 6.8 200

min_result = sum of three min (the least) data (column

2)
for Name in column 1.

Important remark!!!
Necessary condition: Distance (sum in column 3) of

those
three data must be 500.
Min_result can be higher result if nacessary condition
can't be perform.
Is there any way to resolve my problem?
Any help will be appreciate.
Regards
Mark


Will this UDF do what you want? The arguments are the

desired name (or cell
reference to that name) and the table (as a range or a

named range).

=================================
Function foo(Name As String, tbl As Range) As Double
Dim NmDt()
Dim c As Range
Dim i As Integer, j As Integer
Dim col As Long, rw As Long
Const MinDistance As Double = 500

'Get Data and Distance for Name

col = tbl.Column
rw = tbl.Row

For i = rw To rw + tbl.Rows.Count - 1
If Cells(i, col).Text = Name Then
ReDim Preserve NmDt(1, j)
NmDt(0, j) = Cells(i, col + 1) 'Data
NmDt(1, j) = Cells(i, col + 2) 'Distance
j = j + 1
End If
Next i

'Sort array by distance

Call BubbleSort2(NmDt, 1)

For i = 0 To UBound(NmDt, 2) - 2
If NmDt(1, i) + NmDt(1, i + 1) + NmDt(1, i + 2)

MinDistance Then
foo = NmDt(0, i) + NmDt(0, i + 1) + NmDt(0, i +

2)
End If
If foo 0 Then Exit For
Next i

End Function


Sub BubbleSort2(TempArray As Variant, Optional D As

Variant) 'D is dimension to
sort on, 1-based

Dim Temp As Variant
Dim i As Integer, j As Integer
Dim NoExchanges As Integer
Dim NumDim As Long

If IsMissing(D) Then D = 1
D = D - 1

'determine number of dimensions
On Error GoTo ErrorNumDim
For j = 1 To 60
Temp = UBound(TempArray, j)
If NumDim 0 Then Exit For
Next j
On Error GoTo 0

' Loop until no more "exchanges" are made.
Do
NoExchanges = True

' Loop through each element in the array.
For i = 0 To UBound(TempArray, 2) - 1

' If the element is greater than the element
' following it, exchange the two elements.
If TempArray(D, i) TempArray(D, i + 1) Then
NoExchanges = False
Temp = TempArray(D, i)
TempArray(D, i) = TempArray(D, i + 1)
TempArray(D, i + 1) = Temp
For j = 0 To NumDim - 1
If j < D Then
Temp = TempArray(j, i)
TempArray(j, i) = TempArray

(j, i + 1)
TempArray(j, i + 1) = Temp
End If
Next j
End If
Next i
Loop While Not (NoExchanges)
Exit Sub

ErrorNumDim: If Err.Number = 9 Then
NumDim = j - 1
On Error GoTo 0
End If
Resume Next

End Sub

=============================

--ron


--ron
.


Ron Rosenfeld

find result - only for expert
 
On Mon, 15 Nov 2004 23:00:42 -0800, "Mark" wrote:

Hi Ron!

You code is very smart i've managed and appeared correct
result.
I've one more question:
My table has thousands rows and tens columns.
How to show in another sheet data perform neccesary
condition for all Name in column)? The form data could be
e.g.:

Min_result for A = 4.8, Distance = 530
Name Data Distance Data_in_Column7 (additionally)
A 1.2 150 Xrt
A 2.2 280 Yur
A 1.4 100 Opu

'two rows below is next Name perform condition

Min_result for B = 6,2, Distance = 620
Name Data Distance Data_in_Column7 (additionally)
A 2.2 240 Pok
A 2.4 280 Utr
A 1.6 100 Opu

etc.. next Name in column 1


Thanks for your professional help!
Best Regards
Mark


Mark,

I would use a very different approach for that sort of solution. Although I
could modify my approach to work (and I would have to do some debugging on my
sort routine), it would take a very long time to go through that amount of
data.

What I would do, and in VBA, would be to copy the data table to a new sheet;
then sort it ascending by Name, and then by Data.

Then I would go through a rolling group of three names until I had the Minimum
Distance criterion satisfied; and delete the rest of the names.

It shouldn't be too tough to do. You can use the macro recorder to get some
code to do the copy and filtering routines. I can't work on it now, but may be
able to later on the day.


--ron

mark

find result - only for expert
 
Dear expert!
I stoped on:
"Then I would go through a rolling group of three names
until I had the Minimum
Distance criterion satisfied; and delete the rest of the
names"

I need technical assistance again.

Best regards
Mark


-----Original Message-----
On Mon, 15 Nov 2004 23:00:42 -0800, "Mark"

wrote:

Hi Ron!

You code is very smart i've managed and appeared correct
result.
I've one more question:
My table has thousands rows and tens columns.
How to show in another sheet data perform neccesary
condition for all Name in column)? The form data could

be
e.g.:

Min_result for A = 4.8, Distance = 530
Name Data Distance Data_in_Column7 (additionally)
A 1.2 150 Xrt
A 2.2 280 Yur
A 1.4 100 Opu

'two rows below is next Name perform condition

Min_result for B = 6,2, Distance = 620
Name Data Distance Data_in_Column7 (additionally)
A 2.2 240 Pok
A 2.4 280 Utr
A 1.6 100 Opu

etc.. next Name in column 1


Thanks for your professional help!
Best Regards
Mark


Mark,

I would use a very different approach for that sort of

solution. Although I
could modify my approach to work (and I would have to do

some debugging on my
sort routine), it would take a very long time to go

through that amount of
data.

What I would do, and in VBA, would be to copy the data

table to a new sheet;
then sort it ascending by Name, and then by Data.

Then I would go through a rolling group of three names

until I had the Minimum
Distance criterion satisfied; and delete the rest of the

names.

It shouldn't be too tough to do. You can use the macro

recorder to get some
code to do the copy and filtering routines. I can't work

on it now, but may be
able to later on the day.


--ron
.


Ron Rosenfeld

find result - only for expert
 
On Tue, 16 Nov 2004 23:16:54 -0800, "Mark" wrote:

Dear expert!
I stoped on:
"Then I would go through a rolling group of three names
until I had the Minimum
Distance criterion satisfied; and delete the rest of the
names"

I need technical assistance again.

Best regards
Mark


Mark,

I am going to be out of town for a few days and will be unable to work on this
any time real soon. But I'll get back to it when I'm back on line if no one
else has given you a solution.


--ron

Ron Rosenfeld

find result - only for expert
 
On Tue, 16 Nov 2004 23:16:54 -0800, "Mark" wrote:

Dear expert!
I stoped on:
"Then I would go through a rolling group of three names
until I had the Minimum
Distance criterion satisfied; and delete the rest of the
names"

I need technical assistance again.

Best regards
Mark


Mark,

Try out the following SUB and see if it comes close to what you want.

The SUB assumes that your data is contiguous (no blank rows). It also assumes
that for every name, there is a series of three that will meet the Minimum
Distance Criteria. In other words, it does not handle the situation in which
the sum of the Distances for a Name is less than 500.

It also leaves intermediate worksheets in place, and does not give them any
particular name.

But it is a first stab.

=================================
Option Explicit

Sub Res()
Dim tbl As Range, c As Range
Dim Count As Integer
Const ResCount As Integer = 3
Const MinSumDistance As Integer = 500

Dim i As Long, j As Long
Dim SumDistance As Integer
Dim SumData As Double
Dim CurName As String

Dim Header() As String
Dim ColCt As Integer

Dim Grp(ResCount - 1, 2)


'copy data table to new sheet and sort

ActiveCell.CurrentRegion.Copy
Sheets.Add
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks
_
:=False, Transpose:=False
Application.CutCopyMode = False
ActiveCell.CurrentRegion.Sort Key1:=Range("A2"), Order1:=xlAscending,
Key2:= _
Range("B2"), Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, _
MatchCase:=False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, _
DataOption2:=xlSortNormal



Set tbl = ActiveCell.CurrentRegion
ColCt = tbl.Columns.Count

i = 2

Application.ScreenUpdating = False

Do
CurName = tbl.Cells(i, 1)

Do
SumDistance = 0
For j = 0 To 2
Grp(j, 0) = tbl.Cells(i, 1) 'Name
Grp(j, 1) = tbl.Cells(i, 2) 'Data
Grp(j, 2) = tbl.Cells(i, 3) 'Distance
i = i + 1
Next j

For j = 0 To 2
SumDistance = SumDistance + Grp(j, 2)
Next j

If SumDistance < MinSumDistance Then
tbl.Cells(i - 3, 1).EntireRow.Hidden = True
i = i - 2
End If

Loop Until SumDistance = MinSumDistance

Do While tbl.Cells(i, 1) = CurName
tbl.Cells(i, 1).EntireRow.Hidden = True
i = i + 1
Loop

Loop Until tbl.Cells(i, 1) = ""



'Move processed cells to another worksheet
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets.Add
ActiveSheet.Paste
Application.CutCopyMode = False

'Set up report
'Get header line

ReDim Header(1 To ColCt)
For j = 1 To ColCt
Header(j) = Cells(1, j)
Next j

i = 1

Range(Cells(i, 1), Cells(i, ColCt)).Delete (xlShiftUp)

Do
Range(Cells(i, 1), Cells(i + 2, ColCt)).Insert (xlShiftDown)
CurName = Cells(i + 4, 1)
SumData = 0
SumDistance = 0


'insert header row
For j = 1 To ColCt
Cells(i + 2, j) = Header(j)
Next j

For j = 3 To 5
SumData = SumData + Cells(i + j, 2)
SumDistance = SumDistance + Cells(i + j, 3)
Next j

Cells(i + 1, 1) = "Min_result for " _
& CurName & " = " & Format(SumData, "#.00") & _
", Distance = " & SumDistance

i = i + 6

Loop Until Cells(i, 1) = ""


Application.ScreenUpdating = True
[A1].Select
End Sub
===========================

--ron

mark

find result - only for expert
 
Hi Ron!
I've wrote "find result - only for expert" as the most
difficult level in VBA whenewer i've wrote - you're master
of VBA.

Glad to read you last post!!
You invent quite nice script.
I add code when data is empty (delete row).
I struggling still with following problem:

If the same Name in table is <3 item (make impossible
min_result of three min) then omit or delate row with Name.
I wonder also, how find min_result in VBA (the smallest
result of data of the same Name and necessary distance
500) when data in my table will be:


Name Data Distance
A 1.1 11
A 2.3 20
A 3.5 12
A 5.9 470

Proper effect:
min_result = 1.1 + 2.3 + 5.9 = 9.3 (distance 501)
Script should be combination three of the smallest data of
the same name. Of course distanse 500 :)

Mr Expert, thank you for any help.
Sorry for my english..

Best Regards
Mark


-----Original Message-----
On Tue, 16 Nov 2004 23:16:54 -0800, "Mark"

wrote:

Dear expert!
I stoped on:
"Then I would go through a rolling group of three names
until I had the Minimum
Distance criterion satisfied; and delete the rest of the
names"

I need technical assistance again.

Best regards
Mark


Mark,

Try out the following SUB and see if it comes close to

what you want.

The SUB assumes that your data is contiguous (no blank

rows). It also assumes
that for every name, there is a series of three that will

meet the Minimum
Distance Criteria. In other words, it does not handle

the situation in which
the sum of the Distances for a Name is less than 500.

It also leaves intermediate worksheets in place, and does

not give them any
particular name.

But it is a first stab.

=================================
Option Explicit

Sub Res()
Dim tbl As Range, c As Range
Dim Count As Integer
Const ResCount As Integer = 3
Const MinSumDistance As Integer = 500

Dim i As Long, j As Long
Dim SumDistance As Integer
Dim SumData As Double
Dim CurName As String

Dim Header() As String
Dim ColCt As Integer

Dim Grp(ResCount - 1, 2)


'copy data table to new sheet and sort

ActiveCell.CurrentRegion.Copy
Sheets.Add
Selection.PasteSpecial Paste:=xlPasteValues,

Operation:=xlNone, SkipBlanks
_
:=False, Transpose:=False
Application.CutCopyMode = False
ActiveCell.CurrentRegion.Sort Key1:=Range("A2"),

Order1:=xlAscending,
Key2:= _
Range("B2"), Order2:=xlAscending,

Header:=xlGuess, OrderCustom:=1, _
MatchCase:=False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, _
DataOption2:=xlSortNormal



Set tbl = ActiveCell.CurrentRegion
ColCt = tbl.Columns.Count

i = 2

Application.ScreenUpdating = False

Do
CurName = tbl.Cells(i, 1)

Do
SumDistance = 0
For j = 0 To 2
Grp(j, 0) = tbl.Cells(i, 1) 'Name
Grp(j, 1) = tbl.Cells(i, 2) 'Data
Grp(j, 2) = tbl.Cells(i, 3) 'Distance
i = i + 1
Next j

For j = 0 To 2
SumDistance = SumDistance + Grp(j, 2)
Next j

If SumDistance < MinSumDistance Then
tbl.Cells(i - 3, 1).EntireRow.Hidden = True
i = i - 2
End If

Loop Until SumDistance = MinSumDistance

Do While tbl.Cells(i, 1) = CurName
tbl.Cells(i, 1).EntireRow.Hidden = True
i = i + 1
Loop

Loop Until tbl.Cells(i, 1) = ""



'Move processed cells to another worksheet
Selection.SpecialCells(xlCellTypeVisible).Selec t
Selection.Copy
Sheets.Add
ActiveSheet.Paste
Application.CutCopyMode = False

'Set up report
'Get header line

ReDim Header(1 To ColCt)
For j = 1 To ColCt
Header(j) = Cells(1, j)
Next j

i = 1

Range(Cells(i, 1), Cells(i, ColCt)).Delete (xlShiftUp)

Do
Range(Cells(i, 1), Cells(i + 2, ColCt)).Insert

(xlShiftDown)
CurName = Cells(i + 4, 1)
SumData = 0
SumDistance = 0


'insert header row
For j = 1 To ColCt
Cells(i + 2, j) = Header(j)
Next j

For j = 3 To 5
SumData = SumData + Cells(i + j, 2)
SumDistance = SumDistance + Cells(i + j, 3)
Next j

Cells(i + 1, 1) = "Min_result for " _
& CurName & " = " & Format(SumData, "#.00") & _
", Distance = " & SumDistance

i = i + 6

Loop Until Cells(i, 1) = ""


Application.ScreenUpdating = True
[A1].Select
End Sub
===========================

--ron
.


Ron Rosenfeld

find result - only for expert
 
On Mon, 22 Nov 2004 04:34:14 -0800, "Mark" wrote:

Hi Ron!
I've wrote "find result - only for expert" as the most
difficult level in VBA whenewer i've wrote - you're master
of VBA.

Glad to read you last post!!
You invent quite nice script.
I add code when data is empty (delete row).
I struggling still with following problem:

If the same Name in table is <3 item (make impossible
min_result of three min) then omit or delate row with Name.
I wonder also, how find min_result in VBA (the smallest
result of data of the same Name and necessary distance
500) when data in my table will be:


Name Data Distance
A 1.1 11
A 2.3 20
A 3.5 12
A 5.9 470

Proper effect:
min_result = 1.1 + 2.3 + 5.9 = 9.3 (distance 501)
Script should be combination three of the smallest data of
the same name. Of course distanse 500 :)

Mr Expert, thank you for any help.
Sorry for my english..

Best Regards
Mark


The problem of eliminating, from the report, names that do not meet the
criteria, either because there are less than three entries, or because the sum
of the entries does not add up to distance 500, is relatively trivial.

However, I've been considering the issue that the results may be
non-sequential, as in your example above. One solution would be to generate
all possible 3-row combinations; eliminate those where sum distance <=500, and
take the one with the minimum sum data.

Whether this is a reasonable approach depends on the size of your data set.
What is the maximum number of entries for a given name?

If it is 20, that results in 1,140 possible combinations.

If it is 100, then there would be 161,700 combinations.

If it is 1000, then there would be 166,167,000 combinations and computation by
this method would be lengthy.





-----Original Message-----
On Tue, 16 Nov 2004 23:16:54 -0800, "Mark"

wrote:

Dear expert!
I stoped on:
"Then I would go through a rolling group of three names
until I had the Minimum
Distance criterion satisfied; and delete the rest of the
names"

I need technical assistance again.

Best regards
Mark


Mark,

Try out the following SUB and see if it comes close to

what you want.

The SUB assumes that your data is contiguous (no blank

rows). It also assumes
that for every name, there is a series of three that will

meet the Minimum
Distance Criteria. In other words, it does not handle

the situation in which
the sum of the Distances for a Name is less than 500.

It also leaves intermediate worksheets in place, and does

not give them any
particular name.

But it is a first stab.

=================================
Option Explicit

Sub Res()
Dim tbl As Range, c As Range
Dim Count As Integer
Const ResCount As Integer = 3
Const MinSumDistance As Integer = 500

Dim i As Long, j As Long
Dim SumDistance As Integer
Dim SumData As Double
Dim CurName As String

Dim Header() As String
Dim ColCt As Integer

Dim Grp(ResCount - 1, 2)


'copy data table to new sheet and sort

ActiveCell.CurrentRegion.Copy
Sheets.Add
Selection.PasteSpecial Paste:=xlPasteValues,

Operation:=xlNone, SkipBlanks
_
:=False, Transpose:=False
Application.CutCopyMode = False
ActiveCell.CurrentRegion.Sort Key1:=Range("A2"),

Order1:=xlAscending,
Key2:= _
Range("B2"), Order2:=xlAscending,

Header:=xlGuess, OrderCustom:=1, _
MatchCase:=False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, _
DataOption2:=xlSortNormal



Set tbl = ActiveCell.CurrentRegion
ColCt = tbl.Columns.Count

i = 2

Application.ScreenUpdating = False

Do
CurName = tbl.Cells(i, 1)

Do
SumDistance = 0
For j = 0 To 2
Grp(j, 0) = tbl.Cells(i, 1) 'Name
Grp(j, 1) = tbl.Cells(i, 2) 'Data
Grp(j, 2) = tbl.Cells(i, 3) 'Distance
i = i + 1
Next j

For j = 0 To 2
SumDistance = SumDistance + Grp(j, 2)
Next j

If SumDistance < MinSumDistance Then
tbl.Cells(i - 3, 1).EntireRow.Hidden = True
i = i - 2
End If

Loop Until SumDistance = MinSumDistance

Do While tbl.Cells(i, 1) = CurName
tbl.Cells(i, 1).EntireRow.Hidden = True
i = i + 1
Loop

Loop Until tbl.Cells(i, 1) = ""



'Move processed cells to another worksheet
Selection.SpecialCells(xlCellTypeVisible).Sele ct
Selection.Copy
Sheets.Add
ActiveSheet.Paste
Application.CutCopyMode = False

'Set up report
'Get header line

ReDim Header(1 To ColCt)
For j = 1 To ColCt
Header(j) = Cells(1, j)
Next j

i = 1

Range(Cells(i, 1), Cells(i, ColCt)).Delete (xlShiftUp)

Do
Range(Cells(i, 1), Cells(i + 2, ColCt)).Insert

(xlShiftDown)
CurName = Cells(i + 4, 1)
SumData = 0
SumDistance = 0


'insert header row
For j = 1 To ColCt
Cells(i + 2, j) = Header(j)
Next j

For j = 3 To 5
SumData = SumData + Cells(i + j, 2)
SumDistance = SumDistance + Cells(i + j, 3)
Next j

Cells(i + 1, 1) = "Min_result for " _
& CurName & " = " & Format(SumData, "#.00") & _
", Distance = " & SumDistance

i = i + 6

Loop Until Cells(i, 1) = ""


Application.ScreenUpdating = True
[A1].Select
End Sub
===========================

--ron
.


--ron

Ron Rosenfeld

find result - only for expert
 
On Mon, 15 Nov 2004 07:12:46 -0500, "Tom Ogilvy" wrote:

Can you sort your data on the "Data" column ascending? Then you take the
first 3 sequential cells that sum to greater than 500.

--
Regards,
Tom Ogilvy


Tom,

Apparently the result may not be from sequential entries. The OP gives an
example:

======================
Name Data Distance
A 1.1 11
A 2.3 20
A 3.5 12
A 5.9 470

Proper effect:
min_result = 1.1 + 2.3 + 5.9 = 9.3 (distance 501)
======================

Any thoughts? (Other than generating all possible three row entries for each
name)






--ron


All times are GMT +1. The time now is 09:33 AM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
ExcelBanter.com