look through array assign values into cells - vba

I have 2d-array like this below. There are 26 values from 1-26, but also "bigger" categories, e.g. 2nd value: "Important", "very important", "extremely important", and are all classified as "check".
Can I integrate this into this Array like adding after "important: priority (1,3)? Or (2,3) Sorry, I am starting with Arrays.... I do not fully understand this yet. The values I then want to populate into columns. Example, if column = 1 then column2 = "Important" and column3 = "check" and so on.
Dim Priority(1 To 26, 1 To 2)
Priority(1, 1) = 1: Priority(1, 2) = "Important"

For Each Zelle In Range(Cells(FirstRow + 2, 14), Cells(LastRow, 14))
Zelle.Offset(0, 1) = Application.VLookup(Zelle, Priority, 3, False)
Zelle.Value = Application.VLookup(Zelle, Priority, 2, False)
'Zelle = IIf(IsError(Zelle), "???", "Zelle")
Next Zelle
it checks CellX and then goes directly to CellX+1 and so on...I am sure this could be also done with For i Loop

Related

VLookup analogue in VBA, printing two columns based on StrComp with common first column

I'm updating a VBA script and trying to match a 4-digit code with a table and printing the two corresponding columns into my original sheet, plus handling codes missing from the reference table.
jobcodes = sample codes to match.
codematch = reference table, 1st column is reference codes, I want the corresponding values in columns 2 and 3 in K and L of "jobcodes".
At the minute I'm getting blank values in the first two rows, then #N/A errors in the rest of the sample table.
finrow3 = jobs.Cells(Rows.Count, 1).End(xlUp).Row
jobcodes = jobs.Range(("J2"), ("L" & finrow3)).Value
codematch = stat.Range("I2:K143").Value
For i = 1 To finrow3 - 1
For j = 1 To UBound(codematch, 1)
If StrComp(jobcodes(i, 1), codematch(j, 1)) = 0 Then
resulta(z, 1) = codematch(j, 2)
resulta(z, 2) = codematch(j, 3)
Else
resulta(z, 1) = ""
resulta(z, 2) = ""
End If
Next j
Next i
jobs.Range(("K2"), ("L" & finrow3)).Value = Application.Transpose(resulta)

Generating array of all possible combinations from array regardless of number of elements in VBA

I need to take an input of mins and maxes for multiple variables and generate an array containing each possible combination.
Example: Entering the array
[A min, A max
B min, B max]
should return
[A min, B min
A min, B max
A max, B min
A max, B max]
I was able to do this but only with under 3 variables but can't conveniently expand it. I can't figure out how to make it work for any amount of variables, like if there was a C that also has a max and min.
Does anyone have suggestions?
edit:
If this helps anyone, purpose of this function is to find the extremes of a variable based expression. The first array is generated from the variables included in the expression, then the variables are replaced with values from the second array. So essentially every is calculated to find the highest possible outcome and lowest possible outcome.
So an input that created the first array could have been something like: 'A+B'
Then, for each row in the second array, 'A' and 'B' would be substituted with the instructed value.
Here is a VBA function which can be used to solve one interpretation of your problem:
Function Products(A As Variant) As Variant
'A is assumed to be a 2-column 1-based array
'The function returns another 2-column 1-based array
'Where each successive 4 rows gives the Cartesian product
'of two of the rows of A, with the earlier row
'providing the first element and the latter row the second
Dim i As Long, j As Long, k As Long, n As Long
Dim P As Variant
n = UBound(A, 1)
ReDim P(1 To 2 * n * (n - 1), 1 To 2)
k = 1
For i = 1 To n - 1
For j = i + 1 To n
P(k, 1) = A(i, 1)
P(k, 2) = A(j, 1)
P(k + 1, 1) = A(i, 1)
P(k + 1, 2) = A(j, 2)
P(k + 2, 1) = A(i, 2)
P(k + 2, 2) = A(j, 1)
P(k + 3, 1) = A(i, 2)
P(k + 3, 2) = A(j, 2)
k = k + 4
Next j
Next i
Products = P
End Function
Used like: Range("C1:D12").Value = Products(Range("A1:B3").Value)

If statement results overwriting each other VBA

I am experiencing a problem with the outputs from my loop. As the sub is running I can see that the results from the final IF statement are being overwritten by the results from the second one. My code is structured as follows:
for i = 1 to 5
for j = 1 to 50
for each events.value in eventArray
if events.value = arrayElem then
if cells(i,j).value = "x" then
type = "col1"
elseif cells(i,j).value = "y" then
date = "col2"
elseif cells(i,j).value = "z" then
num = "col3"
end if
count = count + 1
activeworkbook.worksheets("output").cells(count + 1, 1) = type
activeworkbook.worksheets("output").cells(count + 1, 2) = date
activeworkbook.worksheets("output").cells(count + 1, 3) = num
end if
next arrayElem
if cells(i,j).value = "a" then
name = "row1"
elseif cells(i,j).value = "b" then
size = "row2"
elseif cells(i,j).value = "c" then
height = "row3"
end if
activeworkbook.worksheets("output").cells(count + 2, 1) = name
activeworkbook.worksheets("output").cells(count + 2, 2) = size
activeworkbook.worksheets("output").cells(count + 2, 3) = height
next j
next i
Obviously these are dumby variables and results, but the overall structure is the same as the real code. I can see "name","size", and "height" being printed, but then they get replaced by "type", "date", and "num". How do I prevent this from happening? Each time a new event is found I need it to print its associated characteristics printed into a new row in the "output" sheet.
Consider the following simplified version of your code:
For i = 1 To 100
If x = y Then
rowNum = rowNum + 1
Cells(rowNum + 1, 1) = "A"
End If
Cells(rowNum + 2, 1) = "B"
Next
Each time through the loop you are writing out either one or two things (two if x = y is true, one if it isn't) but you are only incrementing the row number by zero or one (one if x = y is true, zero if it isn't). Even if you know that x will always equal y, you are still trying to write two rows of information out but only increasing the row counter by one.
Assuming you are not trying to replace the "B"s in my example with the "A"s from the next iteration through the loop, you should change the code to something like:
For i = 1 To 100
If x = y Then
rowNum = rowNum + 1
Cells(rowNum, 1) = "A"
End If
rowNum = rowNum + 1
Cells(rowNum, 1) = "B"
Next

Placing values generated from one sheet, into a new sheet

I have a nested for loop that is looking to take values in one row, generate a value based on an equation, then do the same for many rows following the first one, all while adding the value together.
Essentially, if row one has a value of 15, and row 2 and 3 return values of 10 and 12, the variable storing the total value (named genCost) will be 37.
I want to place the summed total values of genCost in a new sheet, separated by day, but when I run the code I get a Run-time 1004 error. I realize that this has something to do with the sheet that I am working on, and the sheet that I am trying to place the values into (the 2nd to last line in the code).
I understand my code may be ugly and simple, but can somebody help me troubleshoot this?
'Nested For loop for ALL OTHER DAYS of genCost...only 1 formula
For j = 2 To dayNumber
For i = 1 To increments
'IF(AND(U7=1,U6=0),R7,0)
If Cells(rowValue, 21) = 1 And Cells(rowValue - 1, 21) = 0 Then
ifValue = Cells(rowValue, 18)
Else
ifValue = 0
End If
'calculate value variable with second half of equation
value = (((Cells(rowValue, 23) * Cells(rowValue, 16) * (1 / 6)) + (Cells(rowValue, 25) * Cells(rowValue, 17) * (1 / 6)) + (Cells(rowValue, 21) * Cells(rowValue, 19) * (1 / 6)) + ifValue))
genCost = genCost + value
'set value and ifValue back to zero and step down one row and do again
value = 0
ifValue = 0
rowValue = rowValue + 1
Next i
Cells(3, j) = genCost
Dim genCostRefNum As Integer: genCostRefNum = 6
ThisWorkbook.Sheets(1).Range(Cells(genCostRefNum, 4)) = genCost
genCost = 0
Next j
Instead of this
ThisWorkbook.Sheets(1).Range(Cells(genCostRefNum, 4)) = genCost
write this
ThisWorkbook.Sheets(1).Cells(genCostRefNum, 4) = genCost
There is a default property of Cells statement, which is Value (same for Range). So your code was exactly
ThisWorkbook.Sheets(1).Range(Cells(genCostRefNum, 4).Value).Value = genCost
and after executing Cells something like:
ThisWorkbook.Sheets(1).Range(6).Value = genCost
It's good practice to always write complete statements and don't rely on default properties.

VLookup the same person multiple dates

I have two spreadsheets:
I want to match both sheets and make sure that dates match for every person. E.g. Person 1 has three different dates and I want to match them exactly 1:1.
Person 1, 3/2/2015 (Table A) -> Person 1, 3/2/2015 (Table B)
Person 1, 3/5/2015 (Table A) -> Person 1, 3/5/2015 (Table B)
Person 1, 3/6/2015 (Table A) -> Person 1, 3/6/2015 (Table B)
For the moment I loop through "No." column in Table A and use Application.VLookup on Table B but that only works when a Person has only one date. Otherwise it compares to the first date from Table B. See code:
For sheetArowCounter= 2 To sheetAlastRow
Sheets("A").Select
sheetAperson = Cells(sheetArowCounter, 1)
sheetAdate = Cells(sheetArowCounter, 2)
Sheets("B").Select
sheetBdate = Application.VLookup(sheetAperson, _
Sheets("B").Range(Cells(1, 1), Cells(sheetBLastRow, 2)), 2, False)
If IsError(sheetBdate ) Then
personFromTableAnotFound = personFromTableAnotFound + 1
ElseIf sheetBdate <> sheetAdate Then
sheetAdateNotMatched = sheetAdateNotMatched + 1
End If
sheetAdateCompared = sheetAdateCompared + 1
Next sheetArowCounter
Any idea how can I do that?
I agreed with Jeeped above. Try using a SUMIF. You can even nest the SUMIF in an IF statement to return text: ie: "Match", "No match"
I'd go for a countifs function which can test for criteria against multiple columns. Here is an example for how you could implement this in your code:
For sheetArowCounter = 2 To sheetAlastRow
Sheets("A").Select
sheetAperson = Cells(sheetArowCounter, 1)
sheetAdate = Cells(sheetArowCounter, 2)
Sheets("B").Select
'using the countifs function eg. =COUNTIFS(B!A3:A11,A!A3,B!B3:B11,A!B3)
PersonDateMatches = Application.WorksheetFunction.CountIfs(Sheets("B").Range(Cells(1, 1), Cells(sheetBLastRow, 1)), sheetAperson, Sheets("B").Range(Cells(1, 2), Cells(sheetBLastRow, 2)), sheetAdate)
If PersonDateMatches = 0 Then
personDateFromTableAnotFound = personDateFromTableAnotFound + 1
End If
sheetAdateCompared = sheetAdateCompared + 1
Next sheetArowCounter