Syntax / Loop Errors - vba

I am coding a nested loop to run through every cell (row and then column) of a table I have. Each cell has a distinct "combination" that it must be equal to, and if it matches values that I am referencing on another sheet, it will take a value (specified in Analysis worksheet) from that same row and return it in this table. Here's my code. I am getting an error in the larger If statement. Any help is appreciated. Thanks!
Updated code, all works except the last "And..." within the if statement. Without it, the code runs, but not correctly (for obvious reasons). When I include it back in, excel freezes up and it never finishes running. Please help.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i, j, k, m, n As Long
Worksheets("Chart Data").Range("C6:DR10000").Value = ""
j = 3
Do Until Worksheets("Chart Data").Cells(4, j).Value = ""
For i = 4 To Worksheets("Chart Data").Cells(Rows.Count, "A").End(xlUp).Row
k = i + 3
m = i + 2
n = 1
ThisWorkbook.Sheets("Running Avg Log").Activate
' If the current row in running avg log doesnt meet this if statement criteria, it skips & increments i w/o doing anything
If Worksheets("Running Avg Log").Cells(i, 2).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 3).Value = n _
And Worksheets("Running Avg Log").Cells(i, 4).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 1).Value = Worksheets("Chart Data").Cells(k, 2).Value Then
' When if statement is entered, this sets the selected dimension # in this accepted row and puts it into corresponding spot in chart data
Worksheets("Chart Data").Cells(m, j).Value = Worksheets("Running Avg Log").Cells(i, 6 + Worksheets("Analysis").Range("C5").Value).Value
n = n + 1
End If
Next i
' j (column number) will increment across after each row in one column is done, testing the entire table
j = j + 1
Loop
End Sub
sheet where code will input the values
sheet where the values are found. If statement looks for date, and the three values following the date. If they match what i want, it returns one of the dimension numbers in that same row. The dimension number is a drop down menu cell selected in the Analysis worksheet, and can be referenced with the cell I have shown in the line within the If statement.

The following updated piece of code works without throwing errors.
However, not sure what do you want to code to do ??
Where exactly are your table's values ? Where do you want to place them ?
Try attaching a screenshot of the desired worksheet results your are trying to obtain.
Sub GraphLoop()
Dim i, j, k, m As Long
Worksheets("Chart Data").Range("C6:DR10000").Value = ""
j = 3
Do Until Worksheets("Chart Data").Cells(4, j).Value = ""
For i = 4 To Worksheets("Chart Data").Cells(Rows.count, "B").End(xlUp).row ' modify according to your Column k = i + 3
m = i + 2
ThisWorkbook.Sheets("Running Avg Log").Activate
' If the current row in running avg log doesnt meet this if statement criteria, it skips & increments i w/o doing anything
If Worksheets("Running Avg Log").Cells(i, 2).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 3).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 4).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 1).Value = Worksheets("Chart Data").Cells(k, 1).Value Then
ThisWorkbook.Worksheets("Chart Data").Activate
' When if statement is entered, this sets the selected dimension # in this accepted row and puts it into corresponding spot in chart data
Worksheets("Chart Data").Cells(m, j).Value = Worksheets("Running Avg Log").Cells(i, 6 + Worksheets("Analysis").Range("C5").Value).Value
End If
Next i
' j (column number) will increment across after each row in one column is done, testing the entire table
j = j + 1
Loop
End Sub

Related

Exit Inner For Loop

I am using Excel VBA for this project. The goal of the project is to have a worksheet that shows a number of columns. Each column is headed with an item code (for a scoop) and the quantity of the scoop in inventory. This part is created and functional.
I then want the workbook to search through the list of open orders, get the item id needed to create the product on the open order, and put it in the column of items previously created.
The following code is what I have so far
For j = 2 to 264
For p =2 to 300
'If the item on the order matches the item on the material required sheet, then the variables are set and it starts the inner loop
If Sheets("OOR").Cells(j, 5).Value = Sheets("BOM").Cells(p, 1).Value then
FgScoQty = Sheets("OOR").Cells(j, 10).Value
ItemScoop = Sheets("BOM").Cells(p, 4).Value
FgItem = Sheets("BOM").Cells(p, 1).Value
'If they match, it then looks on the sheet with the columns to put this information in the next blank row of the correct column
For x = 1 to 258
If ItemScoop = Sheets("Sheet5").Cells(1, x).Value Then
lastRow = Sheets("Sheets5").Cells(Rows.Count, x).End(xlUp).Offset(1, 0).Row
Sheets("Sheet5").Cells(lastRow, x).Value = fgItem
Sheets("Sheet5").Cells(lastRow, x).Offset(0, 1).Value = fgScoQty
End If
Next x
End If
Next p
Next j
This works the first time perfectly
After that I get an issue on the line
If ItemScoop = Sheets("Sheet5").Cells(1, x).Value Then
I am not sure why. I believe I need to exit the inner loop (loop x) after the condition has been met. I've done a lot of searching on the net since this seemed like a fairly common problem, but I cannot find anything that works.
When I try Exit For it seems to remove me from all my loops.
I want it to fill in the cells with the variables, and then return to the beginning and look at the next j.
You need to exit the loop once you achieve what you want
So to force the beginning of the next loop ( j ), you need to use the Exit for
Try it:
For j = 2 to 264
For p =2 to 300
'If the item on the order matches the item on the material required sheet, then the variables are set and it starts the inner loop
If Sheets("OOR").Cells(j, 5).Value = Sheets("BOM").Cells(p, 1).Value then
FgScoQty = Sheets("OOR").Cells(j, 10).Value
ItemScoop = Sheets("BOM").Cells(p, 4).Value
FgItem = Sheets("BOM").Cells(p, 1).Value
'If they match, it then looks on the sheet with the columns to put this information in the next blank row of the correct column
For x = 1 to 258
If ItemScoop = Sheets("Sheet5").Cells(1, x).Value Then
lastRow = Sheets("Sheets5").Cells(Rows.Count, x).End(xlUp).Offset(1, 0).Row
Sheets("Sheet5").Cells(lastRow, x).Value = fgItem
Sheets("Sheet5").Cells(lastRow, x).Offset(0, 1).Value = fgScoQty
End If
Next x
'HERE YOU ESCAPE THE LOOP
Exit For
Else
End If
Next p
Next j

Calculating values using loops and formulas with VBA

I am new with VBA for Excel as I work on a project that involves lots of calculations, which I want to automate with VBA. My data ranges from 15 months. To do this, I use loops and formulas but the code results into diferent results. Spefically:
1 - I would like to calculate the sum of values for next month and show the result in the last day of previous month. This is done in column H11.
2- I would like to use this formula =H11-G11-F11 in the last day of the month, after having determined the value of H11.
3- I want to calculate the values of next month following the same logic expect that, in this case my formula depends on the results from previous months. For instance: G29=L11+L112*K31; I know the value in K31.
Here is the code I am using:
Dim i As Long
Dim lrow As Long
Dim start_dif As Double
lrow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 26 To lrow
data = Cells(i, "A")
next_date = Cells(i + 1, "A")
If Month(next_date) = Month(data) + 1 Or _
Year(next_date) = Year(data) + 1 Then
'first diference
start_dif = Cells(i, "I").Value
'Calculating value in G for each end of month
Cells(i, "G").Value = start_dif + start_dif * Cells(i, "K").Value
'setting up next start_dif
start_dif = Cells(i + 1, "I").Value
End If
Next i
Please note that I could not figured out the code for calculating the sum. Let me say how grateful I am for your help.

Generate Vote Counting Sheet From Values In Another Sheet

I currently have a worksheet that allows the end user to select from a set of districts and have subdistricts populate along with their vote strength. For instance
District = 5
Candidates = 3
Subdistricts
Subdistrict Vote Strength
U 456
E 442
R 876
T 312
B 256
S 643
I'd like to create a button that let's an end user create an additional sheet that will populate based off of the values in their district selection. The newly created sheet would create a "ballot" of sorts. On the first sheet, they'd indicated the number of candidates and the new sheet would populate similar to this
U E R T B S
Candidate 1
Candidate 2
Candidate 3
The end user would input raw vote (a number between 0 and 4), which would be multiplied by the vote strength in sheet 1, producing a weighted vote calculator that scales up or down depending on the number of subdistricts a certain district has.
The logic would essentially be:
Create a new sheet
Horizontally add column headers for each subdistrict in sheet 1 and add rows for total number of candidates in sheet 1
As raw votes are entered, a mirrored table from the table created in sheet 2 is produced with raw vote calculated
Updated the loop to show the formula instead:
For m = 2 To i + 2
Cells(CandidateCount + 1, m).Formula = _
"=SUM(" & ActiveSheet.Range(ActiveSheet.Cells(2, m), ActiveSheet.Cells(CandidateStart, m)).Address(False, False) & ")"
Next m
So thanks to #VBA Pete for putting me on the right track, I managed to create the basic functionality. I'm now stuck on this step
As raw votes are entered, a mirrored table from the table created in sheet 2 is produced with raw vote calculated
I need to accomplish two things one more step:
1. Create a data validation requirement in a For Loop for a column range that disallows more raw votes being counted than people who are actually present. I have this stored in a variable in the code below as MembersPresent.
2. Populate the weighted vote after end user input is recorded. This can be accomplished by inserting a dynamic formula into cells inside a For loop using variables. I've seperated the working code from the non-working code below
Private Sub CommandButton1_Click()
ActiveWorkbook.Sheets.Add Before:=Worksheets(Worksheets.Count)
i = Sheet1.Cells(8, 6).Value
CandidateCount = Sheet1.Cells(11, 8).Value
CandidateState = CandidateCount + 1
SheetName = Sheet1.Cells(13, 8).Value
OrSheetName = Sheet1.Cells(13, 8).Value
v = 0
For Each Sheet In Worksheets
If SheetName = Sheet.Name Then
SheetName = OrSheetName & "_Ballot" & v
v = v + 1
End If
Next Sheet
ActiveSheet.Name = SheetName
For x = 1 To i
b = 15 + x
Subdistrict = Cells(b, 2).Value
MembersPresent = Cells(b, 6).Value
ActiveSheet.Cells(1, (x + 1)).Value = Subdistrict
For a = 2 To 6
ActiveSheet.Cells(a, x + 1).Value = 0
With ActiveSheet.Range(ActiveSheet.Cells(a, x + 1), ActiveSheet.Cells(a, x + 1)).Validation
.Add Type:=xlValidateWholeNumber, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="0", Formula2:=MembersPresent
.InputTitle = "Integers"
.ErrorTitle = "Integers"
.InputMessage = "Enter an integer from 0 to " & MembersPresent
.ErrorMessage = "You must enter a number no less than 0 and no greater than the number of members in attendance: " & MembersPresent
End With
Next a
Next x
For b = 1 To CandidateCount
Named = "Candidate Name" & " " & b
ActiveSheet.Cells((b + 1), 1).Value = Named
Next b
ActiveSheet.Cells(CandidateCount + 1, 1).Value = "Raw Vote Totals"
Broken Code that looks like what I think I want
For m = 2 To i + 2
SumRange = ActiveSheet.Range(ActiveSheet.Cells(2, m), ActiveSheet.Cells(CandidateStart, m)).Select
ActiveSheet.Cells(CandidateCount + 1, m).Formula = "=SUM(" & SumRange & ")"
Next m

Upon change in row value, Do a sumif one row back in another column

I hope you can help me my VBA question. I would like to use a loop going down column A. Once a change is detected, I would like to insert a SUMIF formula in column C to total of column B if grouped the column A (Total offset to the right). A is already sorted. Kind of like Subtotal but without using the Subtotaling row.
A B C
1 2
1 6
1 3 11 =SUMIF(A:A,A3,B:B)
2 7
2 8 15 =SUMIF(A:A,A5,B:B)
3 8
3 6 14 =SUMIF(A:A,A7,B:B)
(without the added blank rows between 1 & 2 and 2 & 3 changes) I believe I am part of the way there with the following pieces of code pieces, but am having trouble getting to work together.
Sub SUMIF_Upon_Change()
Dim r As Long, mcol As String, i As Long
' find last used cell in Column A
r = Cells(Rows.Count, "A").End(xlUp).Row
' get value of last used cell in column A
mcol = Cells(r, 1).Value
' insert rows by looping from bottom
For i = r To 2 Step -1
If Cells(i, 1).Value <> mcol Then
Cells(n, 3).Formula = _
"=SUMIF(A:A,RC[-1],B:B)"
'AND / OR This added at the change row minus one row.
'Places formula in each adjacent cell (in column "D").
Range("C2:C" & Range("A" & Rows.Count).End(xlUp).Row).Formula = "=SUMIF(A:A,A3,BB)"
End If
Next i
End Sub
Any help will be much appreciated.
XLMatters, You pretty much have it. Your only major issue is that you seem to be mixing formula reference styles ("RC[-1]" and "A3"). You have to pick one or the other. Here is a working example of your code with a few minor modifications:
Sub SUMIF_Upon_Change()
Dim r As Long, mcol As String, i As Long
' find last used cell in Column A
r = Cells(Rows.Count, "A").End(xlUp).Row
' get value of last used cell in column A
mcol = Cells(r, 1).Value
For i = r To 2 Step -1
If Cells(i, 1).Value <> Cells(i + 1, 1).Value Then
Cells(i, 3).Formula = "=SUMIF(A:A,A" & i & ",B:B)"
End If
Next i
End Sub
If your heart is set on FormulaR1C1 style, here you go:
Sub SUMIF_Upon_ChangeRC()
Dim r As Long, mcol As String, i As Long
' find last used cell in Column A
r = Cells(Rows.Count, "A").End(xlUp).Row
' get value of last used cell in column A
mcol = Cells(r, 1).Value
For i = r To 2 Step -1
If Cells(i, 1).Value <> Cells(i + 1, 1).Value Then
Cells(i, 3).FormulaR1C1 = "=SUMIF(C1,RC1,C2)"
End If
Next i
End Sub
Should you have any other questions, just ask.

Copy certain values from one to another column and deleting the original value

I want to copy values from one column to another column (into the same row) if the cell contains the word IN and delete the original value. If not, the code should proceed to the next row and perform a new test. Thus the cell in the target column will remain empty.
When I run the code in Excel nothing happens, so I don't know what is wrong.
Ideally the code should jump to the next column (8) and do the same search and paste the value into the same column (5) when it is done with the first column, but this I haven't started with yet. So I do appreciate tips for that as well :)
Sub Size()
Dim i As Integer, a As String
i = 2
a = "IN"
Do While Cells(i, 7).Value <> ""
If InStr(Cells(i, 7), a) Then
'copying the value to another column but within the same row
Cells(i, 7).Copy Cells(i, 5)
Cells(i, 7).Clear
i = i + 1
Else
i = i + 1
End If
Loop
End Sub
I found out that my first cell in column 7 was empty and thus the Do While Cells(i, 7).Value <> "" wasn't working. Hence I'm refering to a different column that always contain data. Note that the solution code also jumps to the 2 next columns in order to search for the same word.
Sub Size()
Dim i As Integer, a As String
j = 0
i = 1
a = "IN"
Range("A1").Offset(i, 0).Select
For j = 0 To 2
Do Until Selection.Value = ""
If InStr(Range("G1").Offset(i, j).Value, a) Then
Range("E1").Offset(i, 0).Value = Range("G1").Offset(i, j).Value
Range("G1").Offset(i, j).Clear
i = i + 1
Range("A1").Offset(i, 0).Select
Else
i = i + 1
Range("A1").Offset(i, 0).Select
End If
Loop
i = 1
Range("A1").Offset(i, 0).Select
Next j
End Sub