Sum values based on cells with an indent - vba

I'm having a certain layout like this:
0
0
0 5
1 6
1
0 7
1 8
1
0
0 9
1 10
1
0 11
1 12
Above is a list with combinations from 000, 001, 010, 011 to 111. The combinations all have a certain value, from 5 to 12.
(The enters are new rows, the spaces are indentlevels of cells, the 5, 6, 7, etc. are in a new column. The 0's and 1's are all in the same column.)
Now I need to have the sum of all the values in which the first 0/1 is 1, the sum of all the values in which the second 0/1 is 1, and the same for the last value. The results in this case must be: 42, 38 and 36
I can't find out how to programm this properly. I was hoping for something like this:
While not Sheets("Sheet 1").Cells(j, 1).indentlevel(2).Value = 0
sum = sum + cells(j,2)
j = j + 1
Wend
But obviously this doesn't work. I can't program this all out without loops, because the codes can be up to 5 didgets (ex. 01101)

Have you thought of using a for loop? Also I think you are using the IndentLevel syntax incorrectly.
With ThisWorkbook.Sheets("Sheet 1")
set rng = Range(.cells(1,1), .cells(3,10)) ' Change this to match your range
End With
For each c in rng
If c.IndentLevel = 2 Then
sum = sum + c
End If
Next c

This doesn't need VBA. The real problem is an inappropriate data format. Update your convention such that each indentation level is moved to a separate column. You'll then be able to proceed with simple Excel formulas.

Related

Counting the number of each part used, from a table with combination of parts

I have a table counting the number of instances a certain part is used. However, the way the data was collected is messy - it counts each unique combination of parts used separately (so A+B is different from B+A).
Here's an example:
Part Number | Count
A 1
A+B 2
B 3
B+A 4
C 5
A,C 6
D 7
D+D+D 10
Based on this table, I would like to get a tally of the total number of each part used. So for instance, the count for D from the above table would be 37 (one count of D used 7 times + three counts of D used 10 times).
Envisioned output:
Part Number | Total Count
A 13
B 9
C 11
D 37
Is it possible to do this with a script, either in SQL or in Excel?
This VBA function will find count occurances in the first column and then multiply by the second column (if numeric).
Function find_part(part As String, searchRange As Range) As Long:
Dim r As Range
find_part = 0
For Each r In searchRange.Resize(, 1)
If Len(part) > 0 And IsNumeric(r.Offset(, 1)) Then
occurances = (Len(r.Value) - Len(Replace(r.Value, part, ""))) / Len(part)
find_part = find_part + occurances * r.Offset(, 1)
End If
Next
End Function
Here's how to call it from Excel, and what the return values look like;

Shuffle an existing column multiple times with no repeats on any row

I am using VBA
I have a column of integers in an array
I run the array thru a randomizer module and copy that to a second column
I run the array thru a randomizer module and copy that to a third column
I run the array thru a randomizer module and copy that to a fourth column
The issue I can't seem to over come is duplicates on the same row
IE:
2 13 27 14
27 27 13 5
14 5 2 13
13 2 14 27
5 14 5 2
*columns are much longer
I have searched the web but everyone is focused on creating random numbers without duplicate. I have found shuffling but once again it seems to be one dimensional.
'// get a random number from 1 to the last row of column 25
For N1 = 1 To LastRow
Again:
Randomize Timer
RNum = Int(Rnd * (LastRow - 1 + 1) + 1)
'// this is where the values in "NArray" get shuffled around
Temp = NArray(N1)
NArray(N1) = NArray(RNum)
NArray(RNum) = Temp
ws5.Cells(N1, Lp) = NArray(N1)
'// this looks for duplicate numbers in the row
Select Case Lp
Case 26: a = ws5.Cells(N1, Lp).Value + 0
b = ws5.Cells(N1, Lp - 1).Value + 0
If a = b Then
GoTo Again
End If
Case 27: a = ws5.Cells(N1, Lp).Value + 0
b = ws5.Cells(N1, Lp - 2).Value + 0
c = ws5.Cells(N1, Lp - 1).Value + 0
If a = b Then
GoTo Again
ElseIf a = c Then
GoTo Again
End If
...
'// the shuffled array is inserted into the cells of column 26
For N1 = 1 To LastRow
ws5.Cells(N1, Lp) = NArray(N1)
Next N1
Next Lp
no errors with the exception that when comparing cell values in the row going from column to column it misses duplicate values such as row 2 column 3 may contain "14" and row 2 column 4 contains "14" it doesn't loop back and get another value for column 4

FormulaArray keeps changing to relative references

I'm trying to enter a formula in a sheet using VBA (for later use in Excel Solver). It worked fine until this morning.
For u = 1 To Row2
Sheets("Testa").Cells(u + 1, 14).FormulaArray = "=SUM(IF(B2:B2000=" & CStr(u) & ",F2:H2000,0))"
Next
For v = 1 To Row
Sheets("Testa").Cells(v + 1, 18).FormulaArray = "=SUM(IF(A2:A2000=" & CStr(v) & ",F2:H2000,0))"
Next
The first loop gives this as a result in the cell: "=SUM(IF(RC[-12]:R[1998]C[-12]=1,RC[-8]:R[1998]C[-6],0))", changing the absolute references to relative references and not translating the functions to the french equivalent. The second loop works just fine. Column A and B contain a list of numbers (from 1 to Row or Row2) that look like this :
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
I don't know what I'm missing. Any help is welcome !
The range where I was writing the formula was set up as a text range, explaining why it didn't compute the formula. Changing it manually to a standard range solved the problem.

How to subtract from each number in a comma delimited string?

I have a table with a string field where than can be one number or mulitple numbers (delimited by a comma). I need to find the difference between the values (when converted to an integer) and an unspecified value. For simplicity sake for this question, I'll just say the value to be compared is a static value of 10.
Example Table:
iId vchStringNumbers vchSubtractedStringNumbers
1 20, 30, 40
2 50
3 20
Desired Results:
iId vchStringNumbers vchSubtractedStringNumbers
1 20, 30, 40 10, 20, 30
2 50 40
3 20 10
Is there a way to accomplish this in SQL? If it would be eaiser in excel or something like that, feel free to answer as well.
If one has access to Excel 2019 or Excel O365, one could also use (in B2):
=TEXTJOIN(", ",,FILTERXML("<t><s>"&SUBSTITUTE(B2,",","</s><s>")&"</s></t>","//s")-10)
Place you CS data in an Excel column, Select the cells and run this tiny VBA macro:
Sub SubtractCSV()
Dim r As Range
For Each r In Selection
ary = Split(r.Value, ",")
For i = LBound(ary) To UBound(ary)
ary(i) = CLng(Trim(ary(i))) - 10
Next i
r.Offset(0, 1).Value = Join(ary, ",")
Next r
End Sub

A program that will return the cell address of the minimum value in a row?

So I have a chart that looks something like this. Assume that the top left value, 1, is in cell A1:
x= 1 2 3 4 5 6 7 8
4 3 2 1 2 3 4 5
9 8 7 6 7 8 9 10
8 7 6 5 4 3 2 1
Sum= 21 18 15 12 13 14 15 16
There are x values from 1 to 8, and a three columns of values resulting from using it an equation or something below it. The sum is the sum of the three values below their corresponding x-value.
I'm stuck trying to figure something out that will go through the row of sums, find the smallest value, and then assign it's corresponding x-value to a variable. I also need to assign the values to the left and right of that x-value to other variables.
For this particular chart, 12 is the smallest of the sums, so I would assign variable1 = 4, since that is that column's corresponding x-value. Then my second variable, which is called lowerbound, would equal 3, since it is to the left of x = 4, and my third variable, which is called upperbound, would equal 5, since it is to the right of x = 4.
If I could get the cell address returned of the x-value that corresponds to the smallest sum, then I could assign it to a variable, and then simply offset from that cell to assign the other variables. Even if I could make a program that will return me the cell of the minimum sum value, I could offset to the x-row, and go from there.
How would I do something like that?
TL:DR: To ask more clearly, since that's a lot of words: What would a program look like that detects the smallest value in the sum row, and returns the cell address of that value?
The length of the rows are an unknown, and vary a lot, but the length of the columns are given. They do change depending on the problem, but they will always be known. So I will always know how many rows are in a column, but I will not know how many columns are in a row.
This is the most confusingly-worded thing I've ever written in my entire life, but I hope I've explained it well enough to make some sense.
You guys really are amazing, by the way. I've gotten so far on this program, and it's all because of how helpful you are. I honestly think I would still be stuck at the beginning with you guys! You're willing to tolerate a newbie's incessant questions.
I am assuming that the sum is in A4:H4. Please change as applicable
You can use a formula like
=CELL("address",INDEX(A4:H4,MATCH(MIN(A4:H4),A4:H4,0)))
If you want to use VBA then you can use this
Sub Sample()
MsgBox Application.Evaluate("=CELL(""address"",INDEX(A4:H4,MATCH(MIN(A4:H4),A4:H4,0)))")
End Sub
Using your example, the following formula returns the cell address in row 1 whose value in row 5 is the lowest:
=ADDRESS(1,MATCH(MIN(A5:H5),A5:H5,0))
And if you want that cell's value, use INDIRECT. It takes the address as a string.
=INDIRECT(ADDRESS(1,MATCH(MIN(A5:H5),A5:H5,0)))
If you sum the columns by taking the sum of the array. Here is the VBA version:
For j = 1 To 8
For i = 1 To 3
sum(j) = sum(j) + Cells(i + 1, j + 1)
Next i
Cells(5, j + 1) = sum(j)
Next j