Vba range pairwise division - vba

I have a set of variable ranges and I want to do pairwise division of each of the members of each range and bold the member or two highest members if there is a difference of 3/1
Example 1
Column A. Ferrets. Rabbits. Foxes.
Column B. 3000 1000 4000
Because Ferrets and Foxes are in greater than 3/1 proportion to rabbits bold them
Example 2
Column A. Ferrets. Rabbits. Foxes.
Column B 1000 1000 4000
Because foxes are in greater than 3/1 proportion to ferrets and rabbits bold them
Example 3
Column A. Ferrets. Rabbits. Foxes.
Column B. 3000 3500 4000
Bold nothing
I can get the logic to bold but im not quite sure where to begin to get excel to loop through all the possible divisions. Note the range will vary with the number of rows. Sometimes up to 5 and 6 or maybe more which is why im having the problem.

I only have a do loop to count the number of cells in the range. This gives the number of columns that is contained in the range. What I do not know how to do is then take and store a double of whatever division may come from all the pairwise divisions. So if it were 2 rows there would be two answers, 3 rows and there would be 6, 4 and there would be 12...i think the function will be n(n-1) now that i think about it.
Option Explicit
Sub Bold()
Dim i, j As Integer
i = 2 'Row
j = 3 'Column
Do
If Cells(i,j).Value <>"" Then
i = i + 1
End If
Loop Until Cells(i, j).Value = ""
i = i - 1
I figure it would be some sort of nested loop but I'm not quite sure where to start with the function on the number of rows.

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;

VBA: Offset with cells position

I have been searching, and the Offset only can be fixed (http://www.homeandlearn.org/the_offset_property.html)?
I would like to know how to do a variable offset. For example, I choose a fixed value from worksheet (1), based on the condition that you can see below it will do the offset, and use the offset value in a formula from code of worksheet (2).
Worksheet 1: I have the columns A to H and row 1
A B C D E F G H
1 5 10 15 20
Worksheet 2: I have column B and rows 14 to 18. In this worksheet, the values 2,3,4,5,6 are random and are used to determine the number of columns to offset in the worksheet 1. As follows, I expressed what I am trying to do, may be its easier to understand.
Row B
14 2 Sheets(1).Offset(A1,0,($B2-$B$2)*2,1,1)= Offset(5,0,(2-2)*2,1,1) =5 (A1)
15 3 Sheets(1).Offset(A1,0,($B3-$B$2)*2,1,1)= Offset(5,0,(3-2)*2,1,1) =10 (C1)
16 4 Sheets(1).Offset(A1,0,($B4-$B$2)*2,1,1)= Offset(5,0,(4-2)*2,1,1) =15 (E1)
17 5 Sheets(1).Offset(A1,0,($B5-$B$2)*2,1,1)= Offset(5,0,(5-2)*2,1,1) =20 (G1)
18 6 Sheets(1).Offset(A1,0,($B6-$B$2)*2,1,1)= Offset(5,0,(6-2)*2,1,1) =0 (I1)
During my search, I only found possible to do an offset by placing numbers of rows and columns desired to offset. However, it does not work for me.
Since the following code, returns time error '1004, I would like to know why? Is not supposed to return a value? If everything is defined, why does the offset not working? What's wrong?
Sheets(1).Cells(1,1).Offset(0,(Cells(i+countRows,3) - Cells(i,3))*2))
How can I solve this error?
I hope I made myself clear.
Thanks in advance!

Excel VBA selecting data from a sorted Table

I am running into a problem in VBA in excel.
I am trying to create a participant registration program in excel for a sports tournament. One can add data like the weight, age and name of a participant. And then based on that, The participants are divided into poules named with letters A, B... until Z. I have a table which can sort these poules by letters and then for example only display the participants which are in poule A such as below
Example
Now i want to count the numbers with VBA macros of participants in the poule which is displayed by the sorted table. For example when i sort on poule A it has to return 3 and when i sort on B, it has to return 2.
Determined by the number of participants in a poule the program will print a different poule scheme, depending on the number of participants. (i have this part in VBA)
The problem is when i have a sorted table like below
Example 2
It counts all the participants, and not just the ones in B or any other sorted letter.
I have this:
Sub Count()
Dim nRows As Integer
nRows = Range(Range("A18"), Range("A18").End(xlDown)).Rows.Count
MsgBox (nRows)
End Sub
This works well if you sort A, but when you sort any other letter, it counts All the table until that letter. Eg. when you sort B, it displays 5 (Number of A + B).
I have looked on the internet for a really long time to find a solution but without succes.
I hope my question is clear and that somebody can help me.
I am assuming that you are using worksheet functions. Use Subtotal when working with filtered data.
These parameters evaluate all cells visible or hidden
1 AVERAGE
2 COUNT
3 COUNTA
4 MAX
5 MIN
6 PRODUCT
7 STDEV
8 STDEVP
9 SUM
10 VAR
11 VARP
These parameters evaluate only visible cells
101 AVERAGE
102 COUNT
103 COUNTA
104 MAX
105 MIN
106 PRODUCT
107 STDEV
108 STDEVP
109 SUM
110 VAR
111 VARP
The code does work now, except that it only counts the first letters it encounters.
So when the first column for the poules is for example A A A E A A B B E.
And i sort to A and use the count function, it only returns a value of 3 and not of 5 (because there are 5 A's)
When I sort the table to A, it looks like this (column number, poule value):
14 A
15 A
16 A
18 A
19 A
And it returns just a count of 3, have you maybe got any fixes for that problem as well?
Pictures:
sorted tabel to E
Table
Range.SpecialCells will return a range of only visible cells.
Dim rSource As Range
Dim rVisibleCells
Set rSource = Range(Range("A2"), Range("A2").End(xlDown))
Set rVisibleCells = rSource.SpecialCells(xlCellTypeVisible)
MsgBox rVisibleCells.Rows.Count

How to Find the Length of a Column in VBA with a Variable Last Row

I'm a beginner to vba and hope to use it in order to automate a process. I have a computer program that provides me an excel spreadsheet, where the amount of data in the columns can change. For example, I could have a column of length 9 one time:
1
3
2
4
24
23
432
55
2
Or a column of length 5 (note: actual column sizes are usually in the thousands):
1
2
3
4
8
I want to write code that will grab this column, not knowing how long the column will be. Something like:
Dim list1 As Array
'I don't know how to find the upper bound
list1 = Range("A1:A" & Upper Bound).Value
Any help is appreciated. Thanks!
If you are working with constant values in these columns and are working with larger amounts of cells in these columns, it could be useful to use the count function:
dim x As Long
x = Worksheets(*sheet name*).Range(*column range*).Cells.SpecialCells(xlCellTypeConstants).Count
x is being passed the number of non-empty cells in your column. So you may want to be careful in your column range not to include any headers, if applicable.
I believe this will get you the last row. You might need to be careful if you're looking to count all values (e.g. the first couple rows are blank).
Dim lastRow As Long
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
To get the data from column A into a 2d variant array, use the following:
Dim vA As Variant
vA = [a1:index(a:a,counta(a:a))]
This assumes that there are no blank cells within the data, and that the data starts in row 1.

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