Combinational algorithm for Excel VBA - excel

Let's say that I have a set of items as the one below:
Item Units
Apples 5
Pears 5
Carrots 1
Oranges 4
And I have six persons to whom I can give these items. Let's call them:
Mr. A
Mr. B
Mr. C
Mr. D
Mr. E
Mr. F
I would need an Excel VBA code that retrieves me all the potential combinations of sharing the items presented above to the different persons. Please note that (i) order is not important and (ii) one person may have more than one unit of the same item.
In order to report this information I was thinking of a structure similar to that presented below:
Mr A Mr B ...
Apples Pears Carrots Oranges Apples Pears Carrots Oranges ...
Scenario 1 1 0 1 2 2 2 0 0 ...
Scenario 2 1 0 1 1 2 2 0 0 ...
...
I know that the number of combinations will be huge, but don't mind about computing requirements.
I've been trying to figure out the algorithm, but have not been able to achieve it.
Thanks in advance,

I tried to use Mr A and Mr B for testing and there are 360 different scenarios.
Sub distr_list()
Dim apple_a, apple_b
Count = 1
Cells(Count, 4) = "apple_a"
Cells(Count, 5) = "pear_a"
Cells(Count, 6) = "carrot_a"
Cells(Count, 7) = "orange_a"
Cells(Count, 9) = "apple_b"
Cells(Count, 10) = "pear_b"
Cells(Count, 11) = "carrot_b"
Cells(Count, 12) = "orange_b"
For apple_a = 0 To 5
For apple_b = 0 To 5
For pear_a = 0 To 5
For pear_b = 0 To 5
For carrot_a = 0 To 1
For carrot_b = 0 To 1
For orange_a = 0 To 4
For orange_b = 0 To 4
If apple_a + apple_b = 5 Then
If pear_a + pear_b = 5 Then
If carrot_a + carrot_b = 1 Then
If orange_a + orange_b = 4 Then
Cells(Count + 1, 4) = apple_a
Cells(Count + 1, 5) = pear_a
Cells(Count + 1, 6) = carrot_a
Cells(Count + 1, 7) = orange_a
Cells(Count + 1, 9) = apple_b
Cells(Count + 1, 10) = pear_b
Cells(Count + 1, 11) = carrot_b
Cells(Count + 1, 12) = orange_b
Count = Count + 1
End If
End If
End If
End If
Next
Next
Next
Next
Next
Next
Next
Next
End Sub
You can apply the same logic for the rest.

Related

Printing patterns using loop in python

My program read an integer number N, that correspond to the order of a Bidimentional array of integers, and build the Array according to the below example. I want to fill the middle elements like my expected output.
My code:
n = int(input())
for row in range(1, n+1):
for colum in range(1, n+1):
print(row, end=" ")
print()
Input:
5
My output:
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
The output I want:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
I want to fill the middle elements like this. The height number at the middle then the second height number and so on..
for the "1-2-3-2-1" sequence, you can get it as the "minimum between row and n + 1 - row" - - min(row, n + 1 - row). (And the symmetrical for column) - and then
you print the min of this calculation for row and cols:
n = int(input())
for row in range(1, n+1):
for column in range(1, n+1):
mrow = min(row, n + 1 - row)
mcol = min(column, n + 1 - column)
print(min(mrow, mcol), end=" ")
print()
I hope this is not a homework question, but i will help you.
This can be done a lot more easily with lists!:
def cell_value(i, j, n_rows):
return min(
abs(i - -1),
abs(i - n_rows),
abs(j - -1),
abs(j - n_rows),
)
rows=int(input("Enter the number of rows:"))
row2 = [
[
cell_value(i, j, rows)
for j in range(rows)
]
for i in range(rows)
]
for r in row2:
print(*r)
Or it can be done even more easily like this below:
numberOfRows = int(input("Enter the number of rows:"))
listOut = [[1]*numberOfRows] * numberOfRows #grid of 1s of appropriate size
for j in range(int((numberOfRows+1)/2)): #symmetrical, so only look to the middle
if j > 0:
listOut[j] = list(listOut[j-1]) #copy previous row
for i in range(int((numberOfRows+1)/2)):
if i>=j:
listOut[j][i] = j+1
listOut[j][numberOfRows-(i+1)] = j+1
#copy current row to appropriate distance from the end
listOut[numberOfRows-(j+1)] = list(listOut[j])
for row in listOut:
print(row)
Both of the above programs give the SAME result
Enter the number of rows:5
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
Note:this is only possible for odd numbers!
Let me know if you have any doubts...
Cheers!
enter image description here
`for i in range(n):
````print((n-i)*" ",end=" ")
````print((i+1)*"* ")

How to use nested while loops

I'm trying to make a function that uses a nested while loop that prints something like this.
ranges(5,2)
5
0 1 2 3 4
4
0 1 2 3
3
0 1 2
2
0 1
my code that i have so far looks like this
def ranges(high,low):
while high >= low:
print(high)
high = high - 1
y = 0
x = high
while x > y:
print (y, end = " ")
y = y + 1
The output is like this
5
0 1 2 3 4
0 1 2 3
0 1 2
0
I'm pretty sure I missed up in calling the nested while loop because when i split up the code to just print 5,...,2 in a column it works and so does the code for printing the numbers in a row. Any help would be cool
Add print("") right after the while loop, and modify the condition of the while loop to >=:
def ranges(high,low):
while high >= low: # <-- change the condition otherwise you'll miss the last number in every line
print(high)
high = high - 1
y = 0
x = high
while x >= y:
print (y, end = " ")
y = y + 1
print("") # <-- this
ranges(5, 2)
OUTPUT
5
0 1 2 3 4
4
0 1 2 3
3
0 1 2
2
0 1

Calculating total quantities

I have a situation where a bill of materials exported in the Excel pulls in the 'Level', 'Item' and 'Qty'. In order to calculate the total qty for an item in the BoM it is necessary to multiply up the quantities by the quantity in the parent levels. I have shown this below manually but due to the size of the real data set i was wondering if there is a method available using VBA to calculate the Total Qty values?
Level Item Qty Total Qty
1 A 1 1
1 B 2 2
2 C 3 6
2 D 1 2
2 E 2 4
3 F 5 20
3 G 3 12
2 H 2 4
3 I 1 4
2 J 1 2
2 K 3 6
1 L 2 2
1 M 1 1
Here is a UDF to use.
Paste it in a module in the workbook you are using.
Function qtyfind(level As Range) As Double
Dim i&, temp&, qtyClm&, tQtyClm&
'Change the Column name to match if different
qtyClm = WorksheetFunction.Match("QTY", Range("1:1"))
tQtyClm = WorksheetFunction.Match("TOTAL QTY", Range("1:1"))
If level = 1 Then
temp = Cells(level.Row, qtyClm)
Else
For i = level.Row To 2 Step -1 'loops bottom up
If Cells(i, level.Column) = (level.value - 1) Then
temp = Cells(i, tQtyClm) * Cells(level.Row, qtyClm)
Exit For
End If
Next
End If
qtyfind = temp
End Function
Then call it like this in the first cell and copy down:

Shuffle values to a new row two cells at a time

To explain it in the easiest way possible:
| 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 |
... needs to look like:
| 1 | 2 |
| 3 | 4 |
| 5 | 6 |
| 7 | 8 |
I've tried using the TRANSPOSE() function, but it doesn't seem to work in this situation.
How can I accomplish this simple task?
In an unused cell to the right use this formula,
=OFFSET($A$1, INT((ROW(1:1)-1)/2), COLUMN(A:A)-1+MOD((ROW(1:1)-1), 2)*2)
Fill right one column and fill down as far as necessary. Your results should resemble the following.
      
You put excel-vba in your tags, so I'll post the vba code for you. I don't know how to do it with simple cell formulas. Hopefully it's configurable enough to get what you want, beyond the simple example you gave:
START_ROW = 1
START_COL = 1
STEP_COL = 2
OUTPUT_ROW = 3
OUTPUT_COL = 10
Row = START_ROW
Col = START_COL
Out_Row = OUTPUT_ROW
While Cells(Row, Col).Value <> ""
While Cells(Row, Col).Value <> ""
For step = 0 To STEP_COL - 1
Cells(Out_Row, OUTPUT_COL + step).Value = Cells(Row, Col + step).Value
Cells(Out_Row, OUTPUT_COL + step).Value = Cells(Row, Col + step).Value
Next step
Out_Row = Out_Row + 1
Col = Col + STEP_COL
Wend
Col = START_COL
Row = Row + 1
Wend

Grouped Stacked Chart in Excel

I have the following data in Excel.
Project | Month | Calls Created | Open Calls | Closed Calls
Requests | Dec 2012 | 15 | 11 | 7
Requests | Jan 2013 | 6 | 8 | 9
Requests | Feb 2013 | 6 | 5 | 2
dotcom | Dec 2012 | 1 | |
dotcom | Jan 2013 | | 1 |
dotcom | Feb 2013 | 1 | 2 | 1
The data is only a small subset. For the full dataset, there will be four projects, and the dates range from 2012 to June 2014
I am trying to create a chart, that for month and each project the data is bar stacked, while the overlying X axis is the Month
I have attached an mockup of the chart that I am looking to produce
I can create stacked bar chart if I only want to use one of Calls Created, Open Calls, Closed Calls. However I need a chart that will combine all three
I show you what I think. If are ok, it's simple to adapt...
Following the scheme:
you have something like you need, but use a simple Chart Bar. The trick is to convert the data in the correct way. To do that I have Used VBA because it's more flexible...
Using this code inside a module connected to a button (Update) ... :
Dim N0(1 To 100) As String
Dim N1(1 To 100) As String
Dim N2(1 To 100) As String
Dim N3(1 To 100) As String
Range("B14:H44").Clear
Range("B1").Select
e = 0
For i = 1 To 9999
If ActiveCell.Offset(i, 0).Value = "" Then Exit For
e = e + 1
N0(e) = ActiveCell.Offset(i, 0).Value
N1(e) = ActiveCell.Offset(i, 1).Value
N2(e) = ActiveCell.Offset(i, 2).Value
N3(e) = ActiveCell.Offset(i, 3).Value
Next
Range("B15").Select
For i = 1 To e
If (i > 1) And (N0(i) = N0(1)) Then Exit For
ActiveCell.Offset((i - 1) * 4, 0).Value = "["
ActiveCell.Offset((i - 1) * 4 + 1, 0).Value = N0(i)
ActiveCell.Offset((i - 1) * 4 + 2, 0).Value = "]"
ActiveCell.Offset((i - 1) * 4 + 3, 0).Value = ""
Next
nRep = i - 1
Debug.Print nRep
nrow = 0
For i = 1 To e
If (i > nRep) And (N0(i) = N0(1)) Then nrow = nrow + 1
For k = 1 To 99
If ActiveCell.Offset((k - 1) * 4 + 1, 0).Value = "" Then Exit For
If ActiveCell.Offset((k - 1) * 4 + 1, 0).Value = N0(i) Then
ActiveCell.Offset((k - 1) * 4, 1 + nrow).Value = N1(i)
ActiveCell.Offset((k - 1) * 4 + 1, 1 + nrow).Value = N2(i)
ActiveCell.Offset((k - 1) * 4 + 2, 1 + nrow).Value = N3(i)
End If
Next
Next
The macro generate the NEW range Data for the Chart... The blank lines are used to visual divide the bars in base of the Mounth...
After, manually or if you prefer via VBA, you can adapt the chart (Decreasing the gap Width, add Labels ...)

Resources